Contact List Program

Another blast from the past:  My simple contact list program!

The assignment itself is from Treehouse, but I made a few of my own changes.

My first time doing this assignment was over a year ago.  At the time, I was scratching my head at certain parts (like creating methods and how return works, exactly).

But not today!  I delve into every nook and cranny!  Nothing goes unexplained here.

Let’s start by looking at a sample run.

Sample Run

This program:

  • Continuously prompts the user for contact names
  • For each contact, continuously prompts the user for phone numbers
  • Prints a list of each contact and their number(s)

More info below….

Continue reading “Contact List Program”

Grocery List Program

Guess I’m feeling pretty nostalgic ― because today, I re-wrote one of my first Ruby programs:

A grocery list maker!  (This is actually a Treehouse assignment…with my own enhancements sprinkled on top for extra credit.)

Here’s the main data structure:

  • A hash (storing the list’s name and items)
    • An array of hashes (storing each item’s unique information)

A year ago, it felt like a Russian nesting doll of data (and kinda gave me a headache, to be honest).

But it’s a lot easier to mentally process now ― thanks to JumpStart, JumpStart Live and other resources.

So, what does it look like?  Take a look!

Sample Run

This program:

  • Continuously collects user input
  • Prints the input in an organized list (once the user is finished entering data)

You’re probably thinking, “Okay, Jansen, but how did you actually code this?”

(If you’re one of my friends, you’re probably not thinking that.  Bless you for playing along anyway.)

Anyway, read on for more deets!

Continue reading “Grocery List Program”

JumpStart Live Day 6: Exercise

Here’s the final exercise for JSL Day 6.

We need to write a program that does the following:

  • Asks the user to enter the following info about their closest friends:
    • name (not necessarily unique)
    • age
    • favorite color
  • Outputs total number of friends under 18, followed by their names
  • Outputs total number of unique colors, then lists them
  • Should use at least:
    • 1 array
    • 1 hash

My solution includes:

  • a .times loop based on user input
  • an array of hashes
  • two other arrays for printing purposes


Initializing

First, I initialized a) my main array, and b) a method for collecting user input.

JSL-exercise-code1
Initializing an array…and a method for collecting input

The array is created with a simple [] — and then assigned to the variable name friend_data.

My method is called ask, and the argument it accepts is called question.  It prints question, and collects answer with gets.chomp.

(Note:  I used to think I’d need to add return answer…but Ruby automatically does this for us.  Neat!)

Collecting input

Next, I collected and stored input from the user.

JSL-exercise-code2
Code for collecting input about user’s friends

After printing a message to the user, I call my ask method.  The argument is a question asking about the number of friends.

User input is then assigned to variable number_of_friends.

Here’s what that looks like:

JSL-exercise-output1
Asking the user for number of friends

After that, I start a .times loop.  The value inside number_of_friends determines how many times the loop runs.  (Index is represented by i.)

I call my ask method three times — to ask about and collect values for name, age and favorite_color.  (.to_i converts age to an integer, while .downcase converts all answers for favorite_color into lowercase letters.)

Lastly, the .times loop creates a new hash inside the friend_data array.  Each hash represents a single friend (and is assigned to index i inside friend_data).

Key :name is connected to the value inside name, key :age is connected to the value inside age, and key :favorite_color is connected to the value inside favorite_color.

Why did I use an array of hashes?

Hashes are good for storing pairs of information.  An array of hashes means I can use the same keys for each friend — which makes it easier to juggle friends with, say…the same name.

The loop ends when it finishes collecting data for each friend.

Here’s what that looks like:

JSL-exercise-output2
Asking for each friends’ name, age and favorite color

Friends under 18

Next…

  • Calculating and printing number of friends under 18
  • Printing their names
JSL-exercise-code3
Code for 1) calculating number of friends under 18, and 2) printing their names

First, I printed a message that interpolates the number of friends who’re under 18.

Ruby finds this number by:

  • Calling the .count method on friend_data
  • Passing a block that:
    • Iterates over each element in the array (friend)
    • Only counts friend if friend[:age] is under 18

Okay, so now we know how many friends are under 18.  But what about their names?

I wanted to give the printed names an array-like format.  For simplicity’s sake, I decided to use arrays!

First, I initialized a minor_friends array with [].  Then, I iterated over each hash in friend_data with the .each method.

Passing a block, I told Ruby to send friend[:name] into minor_friends — but only if that friend’s age is under 18.

Then, I printed the contents of minor_friends onto a single line (with print).

How?  By:

  • Converting the array to a string (with .to_s)
  • Using gsub to erase each instance of " in the list

Here’s the result:

JSL-exercise-output4
Friends who are under 18!

Number of unique colors

Finally, I needed to:

  • Calculate and print the number of unique favorite colors
  • Print a list of each unique color
JSL-exercise-code4
Code for 1) calculating number of unique colors, and 2) printing the list of colors

Like the original assignment prompt suggested, I turned to the .uniq method.  (Read more about here.)

Wrestling with uniq

The .uniq method returns a new array by removing duplicate values in self.

So, for example,  [1, 1, 2, 2, 3, 3, 4, 4].uniq would return a new array of [1, 2, 3, 4].

However, friend_data.uniq won’t behave quite the same way.  Why?  Because each element is a hash with multiple key-value pairs.

What do I mean?  Well, friend_data.uniq will return an array of hashes…for each friend with a unique color:

JSL-uniq

Combining this syntax with .count tells us how many unique colors we’ve got:

JSL-uniq2

Cool!  (This is how I interpolated the number of unique colors in my array.)

Based on the above, I expected to be able to print out an array of just the colors.  HOWEVER…

JSL-uniq3

You’ll notice blue appears twice.  These aren’t unique colors.

Moreover, this doesn’t even return an array!  AHHHHH.

JSL-uniq4

Pretty frustrating, to say the least!

This is what I ended up doing (for now):

  • Call the .each method on friend_data
  • Pass a block that shovels friend[:favorite_color] into unique_colors
    • …IF friend[:favorite_color] wasn’t already included in unique_colors

How did I figure out if the current color was already included in unique_colors?  With an include? statement!

After that, I used .to_s and gsub to print the array in a pretty list.

Here’s what the output looked like:

JSL-exercise-output5
Unique colors!

Summary

I made a program to collect names, ages and favorite colors of the user’s friends.

I asked the user for a number of friends, and creating a .times loop that runs based on that number.

Then, I collected info for each friend — and stored that information inside an array of hashes.  Each hash represented one friend.

(Arrays of hashes make it easier to store pairs of info, without requiring each friend to have unique keys.)

After that, I created two more arrays to neatly print a) friends who are under 18, and b) unique colors inside of the initial array.

This exercise was a fun way to practice iterating over an array of hashes, and accessing certain values from those hashes.

It was also a cool introduction to the uniq method (which returns a new array without any duplicates).

JumpStart Live Day 6: Symbols and Hashes

JSL Day 6 covers the following topics:

  • Symbols
  • Arrays vs. Hashes
  • Hashes

Symbols

Symbols are Ruby objects with specific names.  In a program’s execution, you can only have one symbol with the same name.

For example, let’s say we assign the symbol :age to variables x and y.  Variables x and y will have the same object ID number.

Meanwhile, we could also assign the string "age" to variables a and z.

Even though a and z hold the same sequence of characters (and they’ll evaluate as the same if we compare them), they’re actually different objects.  We know this because they have different object ID numbers.

In a smaller program, it’s not such a big of a deal.

But symbols are a great way to save memory, since they’re the same object — no matter how many times you call them!  That’s why, when making hash keys, we typically use symbols instead of strings.

Good rule of thumb:

  • If the contents of individual characters are important:  Use a string!
  • If you’re just naming something:  Use a symbol!

Convert string to symbol

We can actually convert strings to symbols.  Here’s how:

With the .to_sym method!  For example, "apple".to_sym creates an :apple symbol.

Symbols and hashes

Normally, you need a preceding colon when making a symbol by itself.

However, with hashes, there’s a handy shortcut!

symbols1
Shortcut for creating new keys (and values) inside a hash

In this case, the colon connects each key and value.

(Note: Combining this syntax with preceding colons will give you an error.)

HOWEVER, when accessing keys?  You DO need the preceding colon.

symbols2
Accessing the key with a preceding colon ( : )

In short…

  • DON’T put the preceding colon when defining a symbol inside a hash
  • DO put the colon when accessing it

Arrays vs. Hashes

This section talks about arrays and hashes — how they’re different, how they’re the same, and when to use what!

Arrays

Arrays are a list of ordered items.

(I personally like to imagine them as a grocery list of items.)

They have integer indices starting from 0…which cannot be changed.  In other words, if we want to access an element inside an array, we must use an integer.

Hashes

Hashes are a collection of paired information — often called key-value pairs.

(I personally like to imagine them as dictionaries!)

In this case, an object (the key) becomes the index.   Keys in a hash are unique (they cannot be repeated).  Values are not unique (so they can be repeated).

Unlike arrays, hashes are NOT ordered.

Similarities

Both are collections that store and retrieve data.

In either case, we will get nil back when trying to access an element that doesn’t exist.

Differences

Arrays have a fixed index (based on integers, starting at 0).

Hashes let you DEFINE the index.  That index is your key that’s connected to a value.

Tips

  • Storing single pieces of info?  Use an array!
  • Data better described as a pair?  Use a hash!

 

Examples

Here are some examples of how to use: arrays, hashes, and…arrays and hashes!

Example 1: Storing names inside an array

1-array
Storing names of students inside an array

We’re only storing people’s names here.

In other words, we’re collecting single pieces of information.  So, we keep them inside an array!

Example 2: Storing names and ages inside a hash

2-hash
Storing names and ages inside a hash

This example stores students’ names and ages.

Each person has both a name and an age.  In other words, we’re working with pairs of information.

When working with pairs of info, we store them inside a hash.

In this case?  Names (assuming they’re all unique) are the keys.  Ages are the values.

What if the names AREN’T unique?  In that case, an array of hashes could work.  (See last example.)

Example 3.1: Storing names, ages and favorite colors (inside a hash)

3-hash_in_hash
Storing names, ages and favorite colors inside a hash…with hashes for values

In this case, each student’s name functions as a key.

But!  Each key’s value is a hash.  The hash stores each student’s age and favorite color.

If the names aren’t unique, we could potentially store this information inside an array.  Like so…

 Example 3.2: Storing names, ages and favorite colors (inside an array of hashes)

3-array_of_hashes
Storing names, ages and favorite colors inside an array…with hashes for elements

 

Hashes

Like we talked about above, hashes are a collection of paired information (or key-value pairs).

Any object can be the key.  However, keys inside a hash must be unique.

Information is stored in the order it was entered — however, you shouldn’t rely on this order when working with hashes.

Creating a hash

There are a few ways we can create a hash.

Example 1: Creating an empty hash

1-hash creation
Curly braces create an empty array assigned to “students”

What we need:  Some sweet curly braces.  That’s it!

Example 2:  Creating a hash with values

2-hash creation

We can also create an array already populated with values.

Here’s how:  We simply combine a symbol and a colon ( : ), followed by the value.

If we want multiple values, we separate them with a comma and a space.

Example 3:  Creating a hash without symbols

3-hash creation

Keys don’t have to be symbols.  They can be any other object, actually.

But!  We can’t use the notation in Example 3 if our key isn’t a symbol.  Instead, we use the hash rocket notation ( => ).

We could make the values symbols.  In that case, we still need to use the preceding colon ( : ).

(Note: If your keys are Fixnums, it’s probably better to use an array.)

Storing and retrieving data from a hash

Here’s one way to store data into an already-existing hash:

hash[key] = value

Once we create a hash, we can access the key-value pairs stored inside.

Here’s an example:

5-hash access
Storing and accessing key-value pairs inside a hash called “students”

In this case, students[:Riley] returns the value of 29.

Iterating over a hash

Iterating over a hash is similar to an array.  The main difference is, we can work with keys and their values (instead of elements and their indices).

Here’s an example:

iteration-1
Two ways to iterate over key,value pairs

These loops go over each item in the hash, and return both the key and value.  (In this case, name represents the key, and age represents the value.)

We can also iterate over keys only.  Like so:

iteration-2
Two ways to iterate over keys only

These loops go over each item in the hash, and return just the key.  (In this case, name represents the key.)

Similarly, we can also iterate over values only.  Like so:

iteration-3
Two ways to iterate over values only

These loops go over each item in the hash, and return just the key.  (In this case, age represents the key.)

Useful hash methods

Here are some commonly-used hash methods…

  • h.clear — Remove all key-value pairs from hash h
  • h.empty? — Return true if hash h contains no key-value pairs
  • h.length — Return the number of key-value pairs in hash h
  • h.keys — Return a new array with the keys from hash h
  • h.values — Return a new array with the values from hash h
  • h.key(value) — Return the key of an occurrence of a given value in hash h
  • h.key?(key) — Return true if key is present in hash h
  • h.value?(value) — Return true if value is present in hash h

 

Examples

The original instructions say to do these a) in pairs and b) on paper.

I did them on paper, at least.  But since my phone takes blurry pictures, I went ahead and did them on my computer too.  So here we go!

Example 1

We want to be able to quickly determine the state abbreviation for the states in the United States.

Determine whether it is best to use an array or a hash, and create it storing at least 4 states and their abbreviations.

We’re storing two pieces of information: state names and abbreviations.  Hashes are the best way to go!

example-1 hash
Storing state names and abbreviations inside a hash called “states”

 

Then write code to print out only the states, then only the abbreviations, and finally nicely formatted output displaying both the states and their abbreviations (e.g., The abbreviation for Nebraska is NE)

example-1 printing
Printing each state and abbreviation in “states”

Example 2

We want to be able to quickly determine the amount of different types of food items you have in your house.

Determine whether it is best to use an array or a hash, and create it storing at least 4 food items and their quantities.

We’re storing two pieces of information:  types of food, and their respective amounts.  So, we definitely want to use a hash…

example-2 hash
Storing food items and quantity inside a hash called “foods”

Then write code to print out all the items and their quantities using nicely formatted output.

example-2 printing
Printing each food item and amount inside “foods”

Summary

This lesson covers symbols, how arrays compare to hashes, and hashes themselves.

In Ruby, symbols are objects with specific names.  In a program’s execution, you can only have one symbol with the same name.

They’re a great way to conserve memory in larger programs (unlike using different strings).

If the content of individual characters are important, we use strings.  If we’re just naming something, though, symbols are the way to go!

Arrays are an ordered list — kind of like a list of grocery items.  Elements follow a 0-based index made up of integers.  This index cannot be changed.

Hashes store pairs of information — kind of like a dictionary.  Values are connected to keys (instead of an index).

Use an array if you’re storing a single piece of information.  If info is better described in pairs, use a hash.

Hashes are created with curly braces  — with or without symbols.  The syntax we use depends on whether our keys are symbols.

Similar to arrays, we can iterate over the contents of a hash.  However, we have a few more options, namely:

  • Iterate over keys only
  • Iterate over values only
  • Iterate over both keys and values

 

Some cool things I learned

In no particular order:

  • We can convert strings into symbols with .to_sym (handy for user input)
  • Keys can be considered the “index” inside of a hash
  • Making a hash of hashes is one way to bypass the “keys must be unique” restriction
  • We can create arrays of keys or values (with .keys and .values, respectively)

JumpStart Live Day 5: Optional Problems

You KNOW I’m gonna do those optional problems!

And since my last post got pretty long, I decided to do a separate entry for optional stuff.

So, here we go!

Exercise 1

Create an array of people that are invited to a party. Allow the user to ask if a certain person is invited to the party. If the person is on the invitation list respond INVITED otherwise respond NOT INVITED.

Here’s my code:

exercise1

What my code does:

  • Create an array of people invited to the party
  • Prompts user to enter a name
  • Collects user input
  • Based on user input, prints INVITED or NOT INVITED

Checking whether a name is on the list is fairly straightforward.

First, I assign user input to variable name.

Then, using an if-else statement, I check whether name is included in the invitees array.  An .include? method (with name entered as the argument) does the job quite nicely!

If invitees.include?(name) evaluates as true, then the program prints INVITED.  Otherwise, it prints NOT INVITED.

Sample run:

exercise1_output1
Claire is invited to the party!

Since “Claire” is one of the elements inside the invitees array, the program prints INVITED.

Another sample run:

exercise1_output2
Kathleen is not invited to the party.

“Kathleen” is NOT an element inside the invitees array, so the program prints NOT INVITED.

Exercise 2

Have the user enter in a sentence. Then, using an array, store the frequency of each letter of the alphabet from the sentence. Print out the frequency of each letter. Do not count uppercase and lowercase letters differently.

Here’s my code:

exercise2_code
Printing frequency of letters inside user input

What my code does:

  • Collect user input
  • Checks the frequency of each letter of the alphabet
  • Stores each letter’s frequency inside an array
  • Prints the frequency of each letter that actually appears inside the sentence.

After prompting the user to enter a sentence, I assign the string to variable sentence.

Since we’re not supposed to count uppercase and lowercase letters differently, I convert all letters to lowercase with .downcase.

Then, I pass "a".."z" as a range for an .each loop.  Each letter is represented by the letter variable.

Here’s how I actually calculate the frequency of letters:  By entering letter as an argument for the .count method…which I called on sentence.

The resulting value goes into my frequency_of_letters array.

After that, I use the .each_with_index method with a range of "a".."z".  Each letter is represented by letter, and i represents the current letter’s index number.

Then, in curly braces, I tell the program to print a) the current letter, and b) its corresponding frequency inside frequency_of_numbers .

However, if the current letter appears 0 times in the sentence, then it won’t be printed (courtesy of a quick unless statement).

Sample run:

Exercise2_output
Every letter of the alphabet appears at least once in this sentence!

Another sample run:

exercise2_output2
Fewer letters appear in this sentence.

 

Exercise 3

Create an array of size 8. Fill the array randomly with 0’s and 1’s. Print out the array so that it appears as a binary number. Calculate and print out the decimal value of that binary number.

Here’s my code:

exercise3
Creating a random binary number, and printing out its decimal value.

First, I create a new array for 8 elements with Array.new(8).  The following block uses rand() — and tells Ruby to generate a random number between 0 and 1 for each position.

The resulting array is assigned to variable binary.

Here’s how I printed the list as a single binary number: Call the .join method on binary…and print the result on a single line!

Now, to calculate the random binary number’s decimal value:

  1. Initialize a new variable decimal with the value 0 (for the upcoming loop)
  2. Tell an .each_with_index method to cycle through each element in binary
  3. Use .reverse to iterate through each element — from last to first position
  4. Assign current number in binary to num, and its index number to i
  5. Tell Ruby to calculate 2 to the power of the number’s current index…
  6. …And add the result to the current value inside decimal!
  7. ONLY  perform the above calculations if num equals 1

Finally, I print the result by using puts on decimal.

Sample run:

exercise3_output
Prints a random binary number and its decimal value

Summary

These optional exercises gave more opportunities to store, print and calculate information with arrays!

References

JumpStart Live Day 5: Exercises Pt. 1

Today, I did the required problems for JSL Day 5.  (Stay tuned for the optional problems!)

Exercise 1

Create an array to store 5 names. Have the user enter in the 5 names and then print out the 5 names in all UPPERCASE all on the same line. Note that the user may not enter all the names in uppercase.

Here’s my code:

exercise1
Collecting 5 names…and printing them (in uppercase) on the same line!

Here’s what my code does:

  • Prompts the user to enter five names
  • In a single loop:  Collects, then stores names inside of a new array called people
  • Prints the names on the same line, in uppercase

Collecting input and creating an array

Okay, so…I wanted to try something a little different.

First, I prompted the user for input.  (Nothing new there.)

Here’s what I’d normally do after that:  Assign the input to a variable…and then shovel it on over to the array.

This time, however, I inserted a handy-dandy gets.chomp inside the loop that’s populating my array — and it worked!!

For formatting, curly braces probably aren’t the best.  Because if you’re printing stuff and collecting input with each iteration, a regular do...end block would be better (since it’s good for multiple lines of code).

But…man!  It’s just so cool to do all that in a single line of code.  (I’m officially in love with passing blocks with curly braces.  ❤ ❤ ❤  )

AHEM…anyway.

My loop ran 5 times (once for each element in the new array).  The resulting list was assigned to variable people.

Printing ALL the names

These names need to be 1) on a single line, and 2) all UPPERCASE.

I used a .times loop.  With i as the index, it iterates through each item in the people array (inside some curly braces).  Each element is printed, and changed to uppercase with the .upcase method.

The loop is set to run a number of times equal to people.length (or, 5) minus 1.  In other words, this .times loop runs 4 times.

But, wait…aren’t there 5 elements in the array we’re printing?  So, why is this loop only running 4 times?

I’ll tell you why:  We’re fence-posting it!

In other words, I’m printing one name (in this case, the last element) outside of the block.  I’m doing this so the names can be spaced properly (and there won’t be a rogue space hanging out after the final name is printed).

Of course, I need everything on the same line.  Thankfully, prints has me covered.

(Note to self:  Looking back, the section on Fencepost Problems only gives .each loops as an example.  Will need to investigate that later…)

Here’s a sample run:

exercise1_output
Exercise 1 output

 

++++++

Exercise 2

Create an array to store 3 boolean values entered in by the user. Print out YES if all the values are true and NO if at least one value is false.

Here’s my code:

 

exercise2
Printing NO or YES based on boolean values (entered by the user)

Here’s a breakdown of what my code does:

  • Collect three strings (either "true" or "false") from user
  • Keep prompting user for input if string doesn’t equal “true” or “false” (my idea)
  • Convert strings into boolean values
  • Store boolean values in an array
  • Print YES if all values are true; print NO if at least one value is false

Collecting user input

Before doing anything, I created an empty array using [].  This array is called boolean_values.

Next, I initialized a variable called true_or_false.  It stores user input during the next step.

Right below that, there’s a .times loop — set to run 3 times, since that’s how many boolean values we need from the user.

What happens if the user doesn’t want to cooperate?

Well, I’m glad you asked.  That’s why I nested an until loop in there.

This until loop prompts the user to enter either “true” or “false”…and assigns the input to variable true_or_false.

Until true_or_false equals "true" OR "false", the program keeps asking for input.  In other words, the user MUST enter "true" or "false" if they want to continue.

For consistency (and ease of evaluation later), I went ahead and converted the input to lowercase using the .downcase method.

Converting input to boolean values

After that, an if-elsif statement evaluates true_or_false.  If it contains the string "true", then it converts to true — a true-blue boolean value!

Likewise, if true_or_false equals "false", then it’s converted to the boolean value false.

After that, the current value of true_or_false is shoveled into the boolean_values array.

…And the cycle continues two more times!

Because true_or_false no longer contains a string, the nested until loop works the same as before.

Printing YES or NO

Pretty straightforward!  An if-else statement evaluates each element in the boolean_values array

Here’s how:  In the first line, a .include? statement checks boolean_values includes false.  If so, then it prints NO — even if only one value is false.

Otherwise, it just prints YES.  (All values must equal true for the program to execute this line.)

Here are some sample runs:

exercise2_output1
User is forced to enter “true” or “false”.  Prints NO because values include false

 

exercise2_output2
Works the same as above — even if user types input in all caps

 

exercise2_output3
Prints YES if all values equal true

 

++++++

Exercise 3

Create an array to store the following words: firetruck, fire drill, fire hydrant, firefighter, fireproof, fire station, fire hose. Then write code that uses the array to print out truck, drill, hydrant, fighter, proof, station, hose without modifying the array.

Here’s my code:

exercise3
Printing the list of words — sans “fire” (without modifying the array)

Curly braces make another appearance in this one!

But first, I create the array of words — named fire_words, in this case.

After that, I write a single-line .each loop using curly braces.  Iterating over each word in fire_words, it prints each element without the word “fire”.

How?  First, .gsub substitutes all instances of "fire" with "".  For formatting purposes, the .split method removes any leading whitespaces (that words like “fire drill” or “fire hydrant” end up with).

For my own reference, I printed out the array — and verified that the contents of fire_words are unchanged.

Here’s the output:

exercise3_output
Each words is printed without “fire”.  Meanwhile, no elements in “fire_words” were modified.

++++++

Exercise 4

Create an array to store the amount of money spent on 4 people during the Holidays. Have the user enter in the amount spent on each person. Print the total spent on all the people. Total money spent should be displayed with a dollar sign, decimal point, and only 2 digits after the decimal.

Here’s my code:

exercise4
Collecting dollar amounts and adding them together

 

Collecting input and creating an array

First, I create a new array with 4 elements.

Passing a single block as a parameter, I fill each position with input from the user.  (The method .to_f converts these values to a float)

The result is a list assigned to holiday_spending.

Calculating the total

The .reduce method reduces the values inside an array to a single number.  (It can add them together, in other words.)

Our starting value of 0 is entered as an argument.  Then, a single block adds each element inside holiday_spending to 0.  The total is represented as result, which is then assigned to variable total.

Printing the total

Last, we print a message to the user.  While we could simply refer to total, that alone won’t give us two decimals.

Instead, we must put '%.2f' % total to convert total to a float with only two digits.

A sample run:

exercise4_output
Collects four dollar amounts from user, then prints the total.

++++++

Exercise 5

Create an array to store 5 random numbers (between 1 and 10, including both 1 and 10) generated by the computer. Print out the square of each of the elements in the array.

Here’s my code:

exercise5
Creates an array with 5 random numbers (between 1 and 10).  Prints out the square of each one.

Creating an array

First, I use Array.new.  I pass 5 (the number of elements) and a block (that generates random numbers for all 5 positions) as parameters.

How do I generate the random numbers themselves?  With rand(1..10), of course!  In this case, I’m passing (1..10) as the range.  (Two dots means 10 is included.)

The resulting list is assigned to variable numbers.

Printing the square of each element

Calling the .each method on numbers, I iterate over each number (represented by num).

For each element in numbers, the loop prints a string — that includes num, as well as the square of num.  (The square of num is calculated by interpolating num * num.)

Sample run:

exercise5_output
Printing the square of 5 randomly-generated numbers (stored inside an array)

++++++

Exercise 6

Create an array to store 5000 decimal numbers. Randomly generate numbers from between 0 – 1 (including 0, but not including 1) to fill the array. Calculate and print the mean of all the elements in the array.

Here’s my code:

exercise6
Stores 5,000 random decimal numbers inside an array.  Calculates and prints the mean.

Creating an array of 5,000 numbers

Calling Array.new, I pass 5,000 and a single-block as parameters.  (Note: I type 5_000 for readability.)

Our single-block parameter consists of rand(0...1.00).  Two thing to note here:

  • In order to generate decimals, 1 must be a float (or 1.00)
  • Three dots excludes 1.00

The result is a new array with 5,000 randomly-generated decimal numbers between 0 and 1.

Calculating and printing the mean

Next, I print the mean.  But first…I’ve got to calculate the dang thing!

Here’s how…

Step one:  Reduce the values inside numbers to a single value with .reduce(0).

This also requires a block, with result starting out as 0.  The loop increments result by the current value (or current, in this case).

I’ve wrapped this process in parentheses…so Ruby will know to calculate this before doing the next step.

Step two: Divide the resulting value from step one, by the number of elements inside numbers.

In this case, we need to divide by 5,000.

Although I certainly could have hard-coded 5,000, I used something more flexible:  numbers.length (or, the number of elements inside numbers…which happens to be 5,000).

Inserting puts before these calculations prints our mean to the screen!

A sample run:

exercise6_output
Printing the mean of 5,000 decimal numbers between 1 and 0.

Summary

Today’s exercises relied on arrays — and included several opportunities to use material covered in previous lessons

Some things I practiced:

  • Generating random numbers using rand() — with exclusive and inclusive ranges
  • Populating a new array…by passing a block as a parameter for Array.new
  • Altering an array’s elements without changing the array itself
  • Performing calculations on elements inside an array
  • Nested loops
  • if-statements and boolean values

References

JumpStart Live Day 5: nil and Arrays

JSL Day 5 introduces the following topics:

  • nil
  • Arrays

nil

In Ruby, everything is an object — including nil.

Sometimes we create a variable without storing anything in them.  When a variable doesn’t have anything stored in it, it automatically has a value of nil.

The .nil? method lets us check if something is nil.

Let’s look at some examples!

nil_example1
Variables don’t automatically hold nil — they need to be declared first!

Things aren’t automatically nil in the beginning.

In this example, puts x triggers an error (instead of printing nil).

Why?  Because x hasn’t been declared.

For x to hold nil, we must declare it…without giving x the value we want.

Here’s an object that returns nil:

nil_example2
Checking if nums[1] returns nil
This code prints There is no value in index 1

nums[1] points to index position 1.  However, the single element in nums actually occupies position 0.

In other words, there is currently no value stored inside nums[1].  That’s why it returns nil.

But what happens if there is a value inside nums[1]?

nil_example3
Checking if nums[1] returns nil (it doesn’t!)
This time, nums has two elements — 1 (in position 0) and 2 (in position 1).

The thing inside nums[1] is 2.  …And so nums[1].nil? returns false.

As a result, our program executes the statement under else — and prints 2 is in index 1.

Arrays

Arrays are a container of things.  They are organized in order from first to last…with a 0-based index.  (Documentation here!)

Why Arrays?

Well, the alternative is to create individual variables.

That’s all well and good for smaller bits of data — but a huge pain if you’re, say…recording daily temperatures for the month of December.

Managing 31 separate variables just for temperatures would be annoying, sure.

But scale it to 365, 730, or 1,095.  Now you’ve got a real nightmare on your hands!

That’s where arrays come in handy.  We can easily assign all of December’s temperatures to a single name.  Best of all, we can access a specific day’s temperature if we need it.

Array Indices

An array’s index starts at 0, and increases by 1.

If you’re new to programming, that might sound weird.  (It did to me!)

Zed Shaw compares arrays to a deck of cards — because you can pick any element at random.  Consequently, having the indices start at 0 makes the math much easier in the long run.

arrays_index_example1
Accessing elements by index number

The array nums has three elements.  The first is 34 (in position 0), the second is 78 (in position 1), and the third is 45 (in position 2).

However, nums[3] returns nil in Ruby.  Why?  Because there’s no fourth element (and nothing in position 3).

Negative index numbers are also a thing!

arrays_index_sample2
Accessing elements with negative index numbers

The very last element in nums is at nums[-1].

The second-to-last element in nums is at nums[-2].

Third from the end is nums[-3].

However, nums[-4] returns a value of nil.  That’s because we only have three elements stored in nums.

Create

You can create new arrays several different ways.  Here are some of the basic methods:

  • Using []
  • Array.new

arrays_create_example1
Creating an empty array with []
Using [] is the most basic way to create a new array.

If we leave [] empty, it creates an empty array.  We can also store elements inside [] when we create the array.

Here’s another way to create an array:

arrays_create_example2
Creating an empty array with Array.new

Using Array.new by itself will create a new, empty array.

Something cool:  You can fill your array with nifty things if you pass stuff into the parentheses!

For example, Array.new(3) creates an array with a length of 5.  (It stores nil in each index.)

What if we want to start our array with something other than nil?  Just pass a second value!

Here’s how:  Array.new(3, "Ada") creates an array with a length of 5.  It stores "Ada" in each index.

The final bit of code is an example of passing a block.

Array.new(5) makes a new array with a length of 5, which is assigned to mult2.  As a second parameter, we pass { |i| i * 2 }.

What’s going on?  Well, i gets the indexes of the array (in this case, 0 through 4).

Then, it takes that i and multiplies it by 2.  So we get…

  • 0 * 2 (returns 0)
  • 1 * 2 (returns 2)
  • 2 * 2 (returns 4)
  • 3 * 2 (returns 6)
  • 4 * 2 (returns 8)

The result?  A new array populated with five even numbers!

Printing an Array

If we puts an array, it’ll display each element on its own line.  (For smaller sets of data, that’s fine…but for larger sets, it’s a hassle.)

If we print an array, we’ll get a neat list with square brackets and commas.  (Pretty!)

arrays_printing
Printing an array with puts, print and string interpolation combined with puts

Lastly, we can also combine puts with string interpolation.  This gives us the same square-brackets-and-commas layout.  (Pretty!)

Change and Access

We can change and access an array with its indices.

For example, it’s possible to assign new values to a specific index number.

In this case, list[0] originally holds a value of 0.  However, 7 is assigned to list[0] — and replaces 0 as the value.

We can also replace list[1] and list[2] in the same way:

arrays_change_access
Changing and accessing an array

Afterward, we access these new values via their respective index numbers.

Add to End

There are two ways to add elements to the end of an array:

  • .push
  • shovel operator ( << )

Here are some examples:

arrays_push
Adding to the end of an array with .push

If we pass "banana" into .push, we can add that string onto the end of list.

Something cool about .push:  You can pass multiple values at once.  They’ll get pushed onto the end of the array in the same order.  (RAD!)

Now let’s take a look at shovel…

arrays_shovel1
Adding to the end of an array with shovel

The << operator can shovel a value to the end of an array.

BUT!  You’ll get an error if you try passing more than one value (unlike .push).

arrays_shovel2
Adding an array to the end of an array (also with shovel)

Be careful not to accidentally stick a new array onto the end of your existing array!

Iterating over an Array

Iterating is another way of saying “looking at each one of the elements and performing some sort of action with them”.

Two different ways to iterate over an array:

  • do ... end block (for multi-line blocks)
  • curly braces {}   (for single-line blocks)

Let’s look at a couple of examples:

arrays_iterate1
Iterating over an array with .each — both ways

The do ... end block and curly braces do the exact same thing here.

Style-wise, the curly braces are better.  The reason is because we’re using a single-line block.

They both print out 1, 2 and 5 (or each element currently inside nums).

Another example:

arrays_iterate2
Iterating over an array with .each_with_index — both ways

While .each gives us each element in a collection, .each_with_index actually gives us both the element and its index number.  Nifty!

This example prints out:

  • 0: 1
  • 1: 4
  • 2: 6

Style-wise, the curly braces are the better choice.  That’s because we’ve only got one line of code in our block.

Useful Array Methods

Here’s a list of handy-dandy methods for arrays:

  • arr.length —  Returns number of elements inside arr
  • arr.empty? —  Returns true if there aren’t any elements in arr (false, otherwise)
  • arr.first —  Returns the first element in arr
  • arr.last —  Returns the last element in arr
  • arr.take(n) —  Returns the first n elements in arr
  • arr.include?(element) —  Returns true if element is stored in arr (false, otherwise)

There are plenty of other methods too…but I probably use these the most!

Exercises

Apparently, JSL participants go over these in person.  But I figure I may as well do these too.

Exercise 1

Create an array which will store the square of each value between 2 and 5, inclusive.

arrays_exercise1
Exercise 1 code

Both examples do the same thing.  They create an array, and store the square of each value between 2 and 5, inclusive.

In the first case, we use a do...end block.  The range is set with (2..5), and .each is used on the collection.  We use the .push method to add the square of each value being passed through i.

In the second case, we use curly braces to pass a block through Array.new.  The 4 tells Ruby we want 4 elements inside of list.

Using i as the index number, the curly braces calculate the square of each number between 2 and 5.

It does this by adding 2 to i (which starts at 0)…twice.  Then, the block multiplies both sums together — and pushes the new value into the corresponding position of i.

For example, the first index is 0.  And (0 + 2) * (0 + 2) equals 4.  Therefore, my first element is the square of 2: that is, 4.

Exercise 2

Given an array that contains three people, Ada Lovelace, Annie Easley, and Margaret Hamilton (1) Add one new person of your choice, (2) Output Annie Easley using the array, (3) Replace Ada Lovelace with Megan Smith

arrays_exercise2
Exercise 2 code

First, the array people is defined with a list of three strings.

Next, I pushed “Frances Spence” into the array with shovel.

After that, we output Annie Easley by referencing its index number (1, in this case).

Lastly, we assign "Megan Smith" to people[0]…which was previously occupied by “Ada Lovelace".  In other words, Ada Lovelace is replaced by Megan Smith.

Array people now consists of four elements — “Megan Smith”, “Annie Easley”, “Margaret Hamilton”, and “Frances Spence”.

Exercise 3

On paper, create an array which stores the names of people that inspire you. Then write down two different ways you can access the second-to-last name in your array?

arrays_exercise3
Exercise 3 code

In this case, my people array consists of three names: “Rebecca Sugar”, "Robert Clary" and "Leslie Odom, Jr.".

The second-to-last name is Robert Clary.  We can access Robert Clary two ways:

  • people[-2] (second-to-last position)
  • people[1] (second position)

Exercise 4

On paper, create an array which stores the numbers 1 – 15. Then write down two different ways of accessing the middle number?

arrays_exercise4
Exercise 4 code

I create an array called num, and assign the result of Array.new(15) { |i| i + 1 } to it.

In this case, I’m telling Ruby:  “Hey, I want a new array with 15 elements”.  Inside the curly braces (where i equals the current index number), I add 2 to i.  This gives me a list of numbers 1 – 15.

In this case, I’m just gonna say the middle number is 8. (That’s what you get when you divide num.length by 2, anyway).

Two different ways of accessing 8:

  • num[-8]
  • num[7]

Exercise 5

On paper, write code that will create an array named powers_of_2, and stores the fist 10 powers of 2

arrays_exercise5
Exercise 5 code

I assign the result of Array.new(10) { |i| 2 ** (i + 1) } to the variable powers_of_2.

In this case, I pass 10 as a parameter into Array.new.  This tells Ruby:  “Hey, I want 10 elements in my new array”.

Next, I use curly braces to populate powers_of_2.  With i as the current index number, I give 2 to the power (i + 1) by using the ** operator.

For example:  With i as index 0, I give 2 to the power (0 + 1) …or just 1.  The result is 2, which becomes my first element.

After the code exectues, powers_of_2 consists of 10 integers: 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024

Summary

This lesson introduces nil and arrays.

In Ruby, a variable automatically returns nil when it doesn’t have a value stored inside it.

Arrays are a container of things.  They are ideal when managing data that would otherwise require too many variables to manage.

Array indices start at 0 and increase by 1.

Here’s what we can do with arrays:

  • Create them (with [] or Array.new)
  • Print them (with puts, print or puts "#{arr}")
  • Change and access them (by referencing an element’s index)
  • Add to the end (with .push or shovel)
  • Iterate over them (with a do ... end block or curly braces)

Cool things I learned in JSL Day 5

In no particular order:

  • We can pass up to two parameters into Array.new
  • We can also pass a block as a parameter with curly braces (to populate our new array with particular values)
  • Curly braces are a great way to execute a single line of code for .each
  • .each_with_index gives us both the element and its index

JumpStart Live Day 4: Exercises

JSL Day 4 includes only one exercise:  A password verification program!

My program follows this structure:

  • while loop (continues as long as variable confirmed is false)
    • until loop (continues until password meets requirements)
      • Multiple if-statements (tells user what they did wrong)
    • if-else-statement (user input determines if while loop breaks or continues)

Below is the first part of my program.  You can see the following:

  • Assignment of user input to variable password
  • Start of the while loop (which runs as long as confirmed evaluates as false)
  • Entire until loop (which runs until password meets all the requirements)
password_maker1
Assigns user input to “password”, starts while loop, and uses until loop to evaluate password.

Let me break this down into smaller parts…

First, user input collection:  Outside of any loops, I prompt the user for a password.  User input is assigned to variable password.

Next, I set a new variable — confirmed.  It’s initialized with a value of false.  (This is important for the while loop below it.)

Looping the program

I needed my program to do the following:

  • Evaluate whether password meets all criteria
  • Keep prompting user for password until it meets all criteria
  • Ask user to re-enter their password
  • Start the whole process over if the re-entered password doesn’t match the original

Simply put, my program’s end goal is:  Get the user to enter the same, approved password twice.

My confirmed variable will only switch over to true if the user successfully meets this goal.

That’s why my larger while loop hinges on confirmed — and whether it’s true or false.  Basically, I’m telling Ruby:  “As long as confirmed stays false, keep running this program.”

Evaluating user input

My first step is evaluating whether password meets all the criteria.  (In fact, I actually wrote this part first!)

An until loop keeps running until password has at least:

  • Eight characters
  • One number
  • One symbol
  • One uppercase letter
  • One lowercase letter

Because there are so many boolean statements, I indented them for readability.

(Note:  I made sure to leave logical operators at the end of each line.  Why?  So Ruby knows to keep going for more boolean statements.)

How my program evaluated user input:

Does password have at least eight characters?
Evaluates whether password.length is greater than or equal 8.

If it evaluates as true, then password has at least eight characters.

Does password have at least one number?
Uses =~ method on password with /\d/ as the argument.  (Found this here.)

If it evaluates as true, then password has at least one number.

Does password have at least one symbol?
Individually evaluates each possible symbol by calling the .include? method on password, and entering its respective symbol as an argument.

I only need one symbol.  Or (||) only needs one statement to be true.  If one of them is true, then the whole statement to evaluate as true.

When that happens, it means password has at least one symbol.

Does password have at least one uppercase letter?
Uses =~ method on password with /[A-Z]/ as the argument.  (Found this here.)

If it evaluates as true, then password has at least one uppercase letter.

Does password have at least one lowercase letter?
Evaluates whether password is equal to password.upcase.

If it is NOT equal, then the statement returns true.

(Note:  I wanted to use =~ like I did for the uppercase condition…but couldn’t find anything for it.  This was the other solution I came up with.)

WHEW!  That was a lot to comb through!

Operator “and” (&&) requires ALL adjoining statement to be true.  So until the above conditions are ALL true, then the loop will continue prompting the user for another password.

Aaaand here’s what that looks like:

password_conditions
Checking whether “password” meets our criteria

Alright, so what if the user needs to re-enter a password?  How will they know what they did wrong?

Through the power of FRIENDSHIP?  No!  The power of if-statements!

A series of if-statements a) figures out what the user did wrong, and b) prints a message telling them what they need.

Here’s what that looks like:

password_conditions2
Telling the user what they did wrong (if their password didn’t meet the criteria)

Why did I use five if-statements?  Why not if-elsif-else?

(Geez, does Jansen really love if-statements that much?  Close, but not quite!)

Our user will most likely botch up multiple things in their password.  In other words, we need the flexibility for multiple conditions to evaluate as true.

In an if-elsif-else (or if-elsif) block?  A totally different story.

How come?  Because the second our program comes across one true statement, it’ll drop the whole thing like it’s hot!

This behavior is also known as short circuit evaluation.

The if-statements are checking for passwords that do NOT meet the criteria.  As a result, my conditions are generally an inversion of my first set of boolean statements.

Here’s an example:  Unlike before, we’re not checking if password.length is greater than or equal to 8.   Instead, we’re now checking if password.length is less than 8.

These if-statements determine which messages (if any) are shown to the user.

After that, the until loop these statements are nested under prompts the user to try again.

password_user_input
Getting a new value for “password” if the user’s password doesn’t meet the criteria

New user input is assigned to variable password.  The until loop once again checks to see if the new string meets our criteria.

Here’s what that looks like:

 

password_sample_1
Sample run: Collecting input until all conditions are met

Verifying the password

So our password meets all the requirements established in the until loop.  Great!

Now we just have to “verify” the password…by prompting the user to enter their password a second time.

If they successfully type the same password a second time, the while loop breaks (and the program ends).

Here’s how that works:

password_maker2
Verifying the user’s password (by making them enter it a second time)

First, we prompt the user to re-enter the password.  The input is assigned to a new variable called confirmation.

If confirmation has the same value as password, then it prints a congratulatory message for the user.  Variable confirmed switches to true, and the while loop breaks (since it runs as long as confirmed is false).

Otherwise, we tell the user that they didn’t succeed.  After prompting them to enter another password, we assign it to variable password.

Our program throws it back to the beginning of the while loop, which kicks it down to the until loop for evaluation.  The cycle begins anew!

Here’s what that looks like:

password_sample_2
Sample Run: Verifying password

 

Summary

This exercise let me practice working with nested loops, loops with logical operators, boolean zen, and if-statements.

Cool things I learned from JSL Day 4:

In no particular order:

  • Boolean zen is another way of saying “writing clean, concise boolean statements”.
  • A good rule of thumb:  Never compare a variable to true or false
  • Fencepost problems require an extra line of code outside of the loop

References

  • How to check if a string has at least one number in Ruby [Stack Overflow]
  • How to check if a string contains uppercase characters in Ruby [java2s.com]

JumpStart Live Day 4: Boolean Zen and Advanced Loops

JSL Day 4 covers the following:

  • Boolean zen
  • Advanced loops

Boolean Zen

The code we write is just as important as the way we write it.

Boolean zen describes code using boolean values written in the most concise way possible.

If you are comparing to true or false in an if-statement, while loop or until loop, that’s not boolean zen.

In other words, ==true or ==false false is no good!

Why?  We don’t need it!  Things will automatically evaluate as true or false without the comparison.

Here are some examples:

example 1
Example 1

We don’t need to write if-statements that print true or false.

Instead, we can just puts the boolean statement itself…since it automatically evaluates as true or false on its own!

The if-else structure is wholly unnecessary.

example 2
Example 2

We don’t need to compare correct to true.  That’s because correct by itself will either evaluate to true or false.

example 3
Example 3

This is similar to Example 2, except it uses a while loop.

We still don’t need to compare not_correct to true!  That’s because the variable not_correct alone already holds a value of true or false.

This will come up more when I start writing functions.

Advanced Loops

This section explains a little bit about:

  • Fencepost problems
  • Loops with logical operators

Fencepost Problems

Imagine building fences with posts and wire.

In fact, let’s draw a picture:  |-|-|-|-| with the | representing a fence post and the - representing the wire of the fence

You’ll need one more post than you do wire sections.

Loops follow a similar structure.  However, when writing loops, it’s easy to have a bit of unwanted “wire” just hanging off the end.

In programming, this is also known as a “loop-and-a-half”.

A common solution?  Make the loop run one fewer times than needed — and handle that last “post” outside of the loop itself.

Here’s an example:

example 1
Fencepost problem: Example 1

If the user enters 3 as max, we’d want the loop to print 1, 2, 3 — three numbers, but only two commas.

 

This solution prints the first “fencepost” outside of the loop (with print 1 ).

Inside the loop, we print commas…followed by the next number.

Another example:

example 2
Fencepost problem:  Example 2

You can also do the loop first…and then print the last “fencepost” outside the loop.

Let’s say the user enters 3 as max again.

The loop goes up from 1 to max - 1.  That means it will print 1, 2, …and then the loop ends.

But outside the loop, we’ve got print max.  That prints 3…and the fence is complete!

Loops with Logical Operators

Let’s take a closer look at using logical operators with loops — specifically, while loops and until loops.

An example:

example 1

 

While the number is:

  • less than 1  (not greater than 0)
  • OR greater than 99 (not less than 100)…

    We’ll prompt the user to re-enter their number.

We cannot put AND — because it’s not possible for a number to be less than 1 AND greater than 99.

Another example:
example 2

 

Until the number is:

  • Greater than 0
  • AND less than 100…

We’ll prompt the user to re-enter their number.

We cannot put OR — because you could enter 101, and 101 is greater than 0.  That means 101 would stop the loop, even though it doesn’t meet both requirements.

Summary

This lesson talks about boolean zen and advanced loops!

Boolean zen is another way of saying “writing clean, concise boolean statements”.

Here’s a good rule of thumb:  Never compare a variable to true or false.

Why?  Because the variables will automatically evaluate to true or false on their own.

When working with advanced loops, we’ll encounter fencepost problems (aka loop-and-a-half).

To avoid unwanted “wire”, we can make the loop run one less round than needed…and insert an additional “fencepost” outside of the loop.  We can insert these extra “fenceposts” either before or after the loop in question.

Lastly, we must pay attention to using logical operators inside loops — namely, until and while loops.

Here’s why:  Because similar problems will require different operators, depending on how you frame the condition for breaking the loop.

…And that’s all for now!  Stay tuned for the Day 4 Exercise.  🙂

JumpStart Live Day 3: Exercises

Exercise 1

Write a program that allows a user to play a guessing number game. Your program should generate a random number between 0 – 1000 (including 0, but not including 1000). Allow the user to make a guess until they guess the answer. After each guess you should print “higher” or “lower”. When they guess it correctly print a winning message along with their total number of guesses.

My solution:

exercise1

Since 1000 is excluded, I used ... for the range.

(Note:  Pretty sure rand(1000) does the same thing, but I wanted to practice the syntax covered in JSL.)

The random number generated by rand() is assigned to rand_number.

User input is converted into an integer and assigned to guess.  I initialized a variable named number_of_guesses with a value of 1.

Next, I created a while loop.  While guess does NOT equal rand_number, the loop will continuously run.

Inside the loop, an if-statement checks whether guess is higher or lower than rand_number.  Depending on which statement is true, the program prints a helpful hint (HIGHER or LOWER) for the user.

After printing the hint, the program collects input from the user again.  The new value is stored in guess.

Next, number_of_guesses increments by 1 with a compound assignment statement.

When the user guesses the correct number, they receive a congratulatory message.  It tells them how many guesses they made.

Sample run:

exercise1_output


Exercise 2

Write a program that plays duck duck goose. Allow the user to enter the player’s number they want to call goose on, and then say “duck” for each player before the “goose”, then say “goose” for the chosen player.

My solution:

exercise2

First, I print a message for the user.  Then, I convert user input to an integer — and assign it to variable goosed_player.

Next, I use range.each for the duck-duck-duck” portion of the game.  The range is between 1 and the number assigned to goosed_player.  However, ... excludes goosed_player from the loop.

Since each number represents a player, I assign the variable player to the current iterator.

For every player (except the one being Goosed), it prints “Duck”.

The loop stops before it reaches the value assigned to goosed_player.  Then, I print a message that “Gooses” whichever player the user selected.

Sample run:

exercise2_output


Exercise 3

Write a program that allows a user to enter the number of petals on a flower. Then one by one, print “plucking petal #1: they love me!”. Alternate “They love me” and “They love me not” as well as increase the petal number for each petal.

My solution:

exercise3

User input is collected, converted to an integer, and then assigned to the variable named petals.

An each loop iterates over a range of 1 to the value stored inside petals.  This range is inclusive.

The current iterator is assigned to the variable num.

Inside the loop, an if-statement evaluates what to print.  If the current num is odd, it prints “They love me!”  If the current num is even, it prints “They love me not.”

The loop ends after it prints the statement associated with the number stored inside petals.

Sample run:

exercise3_output


Exercise 4

You don’t trust your users. Modify the program below to require the user to enter the same value twice in order to add that value to the total.

Original code:

exercise4_original

 

My solution:
exercise4

First, I initialized a third variable named verification — setting it at 0.

Next, I changed the while loop to an until loop.

Why?  Personally, until made it easier for me to imagine what conditions to place on the loop — especially since I’m now juggling a second condition.

(Note:  I certainly could have used while, but with inverted conditions instead.)

My program checks if input <= -1 and input == verification both evaluate as true.

In other words, I’m telling Ruby: “Until input is -1 or less, AND input equals verification, keep running this loop.”

The loop makes the user give input twice.  One value is assigned to input, the other is assigned to verification.

Next, an if-statement evaluates whether to add the user’s number to total.

If input and verification are the same, AND input isn’t a negative number, then input is added to the current value stored inside total.

When the loop ends, the program prints total.

Sample run:

exercise4_output

 

Summary

These exercises let me practice working with scope, loops and iterators.  I also used if-elsif-else statements and conditionals.

Cool things I learned from JSL Day 3:

In no particular order:

  • We can use .times as a regular loop or an iterator (with its own variable assigned between pipes)
  • .times refers to the number of elements inside the collection.
  • range.each passes a specific range into the code as a collection.  This range can either include or exclude the final value.