Learn Ruby the Hard Way, Exercise 35: Branches and Functions

Exercise 35 was all about practicing using combinations of functions with if-statements together to make a little game below.

Right first off there is a deliberate bug in the code on line 8 I’ll discuss a bit further on as it took me quite some time and use of my scarce brain power to figure out.  Below is the fully working code for the the exercise and the output:

ex35 1ex35 2

ex 35 3

At the start of the game you are given routes to follow so here is the output if you go right:

ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-linux]
You are in a dark room.
There is a door to your right and left.
Which one do you take?
>  right
Here you see the great evil Cthulhu.
He, it, whatever stares at you and you go insane.
Do you flee for your life or eat your head?
>  flee
You are in a dark room.
There is a door to your right and left.
Which one do you take?
>  right
Here you see the great evil Cthulhu.
He, it, whatever stares at you and you go insane.
Do you flee for your life or eat your head?
>  dance
Here you see the great evil Cthulhu.
He, it, whatever stares at you and you go insane.
Do you flee for your life or eat your head?
>  eat head
Well that was tasty!
Good job!

And the output if you choose to go left:

ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-linux]
You are in a dark room.
There is a door to your right and left.
Which one do you take?
>  left
There is a bear here.
The bear has a bunch of honey.
The fat bear is in front of another door.
How are you going to move the bear?
>  taunt bear
The bear has moved from the door. You can go through it now.
>  open door
This room is full of gold.  How much do you take?
>  555555555
You greedy bastard!
Good job!


Study Drills

1. Draw a map of the game and indicate how you flow through it

Sure thing

Untitled Diagram

2. Fix all of your mistakes, including spelling mistakes.

I’m pretty sure I did that as i went along

3. Write comments  for the function you do not understand.

I’m good fam.

4. Add more to the game.  What can you do to both simplify and expand it.

I added a bridge between the Cthulu room and the gold room by having a third option where Cthulu sends you straight there (calls the gold room function.)


5. The gold_room has a weird way of getting you to type a number.  What are all the bugs in this way of doing it?  Can you make it better than what I’ve written.  Look at how =~ works for clues.

ex35 4.jpg

The first if statement is a way of getting a a number from the user and creating a variable if the user has entered numerical data correctly, and calling the dead function if not.

The problem with this was that it only recognized combinations of the 0 and 1.  I tried endless ways to add the digits 2-9 as input the program could recognize and convert to integer values without success, in the end I repeated the choice.include?(” “) section of code repeatedly to include every digit from 0-9.

ex35 5



This is…ugly. And inefficient I know.  After getting to the study drills the author gives you a hint to look at regex or regular expressions for more eloquent ways to solve the problem.  Some googling led to a very helpful answer from a dude on stack overflow who solved it thus on line 9:

ex35 6

That’s it for this exercise.  The expression above helped to make the code a lot more succinct but I don’t yet understand anything about regular expressions.  I do vaguely get the expression here which broken down into stages can be understood as:   =~ is the match operator, the expression to be evaluated is written inside the pair of /  / forward slashes and the \d means ‘any digit.’   The + plus  means ‘0 or greater than zero.’





C4D render using hair module

I have no idea what this thing is actually called but it’s a character from some japanese thing so  I modelled a quick copy and tested out the Cinema 4d hair module.   I think it’s kind of cool.

monster final.jpg

Learn Ruby the Hard Way, Exercise 33: While Loops

This exercise was all about while loops, here is the code…

ex33 1


…and the output

ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-linux]
At the top i is 0
Numbers now: 
At the bottom i is 1
At the top i is 1
Numbers now: 
At the bottom i is 2
At the top i is 2
Numbers now: 
At the bottom i is 3
At the top i is 3
Numbers now: 
At the bottom i is 4
At the top i is 4
Numbers now: 
At the bottom i is 5
At the top i is 5
Numbers now: 
At the bottom i is 6
The numbers: 
=> [0, 1, 2, 3, 4, 5]

What I learned was basically a while loop is a piece of code that keeps running and doing whatever you tell it to while the conditions for it to run are not true, that is false, as soon as they are true it stops running.


If you’re not careful you can end up writing a infinite while loop that will totally crash which will suck.  The author gives tips for things to check

  1.  Make sure that you use while-loops sparingly.  Usually a for-loop is better.
  2.  Review your while statements and make sure that the Boolean test will become false at some point.
  3. When in doubt, print out your test variable at the top and bottom of the while-loop to see what it’s doing

Study Drills

1. Convert the while-loop to a function that you can call, and replace 6 in the test (i < 6) with a variable

I cut out out some of the extra stuff just for the sake of space and making this simple.

ex 33 3.png

This output:

At the top i is 0
At the top i is 1
At the top i is 2
At the top i is 3
At the top i is 4
At the top i is 5
At the top i is 6
At the top i is 7
At the top i is 8
At the top i is 9
=> nil

2. Use this function to rewrite the script to try different numbers.

See above.

3. Add another variable to the function arguments that you can pass in that lets you change the + 1 on line 8 so you can change the size of the increment.

The first parameter when you call custom_loop is the value that will make the while loop evaluate to true ending the loop, the second replaces the integer after the += operator so we can give it any value we want.

ex 33 4.png

4. Rewrite the script again to use this function to see what effect that has.


5. Write it to use for-loops and the (0 .. 6) range operator.  Do you need the incrementor in the middle anymore?  What happens if you do not get rid of it?

ex 33 5.png

I added a for-loop as above replacing the while-loop, the increment operator makes no difference as Ruby reads the for loop and carries that out.  Interestingly I googled around how you could increment through a range and found you could do it using the .step method thus:

ex 33 final

which output:

At the top i is 0
At the top i is 2
At the top i is 4
At the top i is 6
At the top i is 8
At the top i is 10
[0, 2, 4, 6, 8, 10]
=> nil

Learn Ruby the Hard Way Exercise 32: Loops and Arrays

Exercise 32 shows….Arrays.  Arrays are indexed lists of stuff that can be assigned to a variable.   So far as I know at this point they can contain basically any object- stirngs (and string interpolation), integers and floast, true or false values and hashes and others arrays.

Objects inside arrays are referenced using numbered indices

arr = Array.new
arr.push([“Cat”, “Pig”, “Duck”])

The items inside the array will be indexed and can be access this way (starting at 0)

puts arr[0]  #=> Cat
puts arr[1]  #=> Pig
puts arr[2]  #=> Duck

Here is the code for exercise 32:

ex32 code

On line 3-5 we created a bunch of different arrays that have Integers and stringes applied to them.

The looping part of the title of the exercise refers to creating code that goes through and does stuff to each item in an array. There are two different ways of doing this given above – on lines 7-9 we have a for loop, a more common way of doing this is in ruby is given on lines 12-14 using the .each method.  On Line 26 a similar loop is written using {} curly braces instead of do-end keywords. In Ruby the curly braces are generally interchangable with the do-end keywords.

Here is the output:

This is the count: 1
This is the count: 2
This is the count: 3
This is the count: 4
This is the count: 5
A fruit of type: apples
A fruit of type: oranges
A fruit of type: pears
A fruit of type: apricotes
I got 1
I got pennies
I got 2
I got dimes
I got 3
I got quaters
adding 0 to the list
adding 1 to the list
adding 2 to the list
adding 3 to the list
adding 4 to the list
adding 5 to the list
Element was: 0
Element was: 1
Element was: 2
Element was: 3
Element was: 4
Element was: 5
=> [0, 1, 2, 3, 4, 5]

Study Drills

1. Take a look at how you used (0..5) in the last for-loop.  Look up Ruby’s “range operator” (.. and …) online to see what it does.

A range object represents the values between the start and end value.  It saves memory as you can store a huge a amount of data without having to put each individual value in so for example if we wanted to represent the number 1-ten zillion we could write 0..10000000.

We can assign the results to a variable and use it to compare stuff.

years_range = 1980..2017
my_birthday = 1985

=> true

Behind the scenes this uses the .succ method that returns the next element in a data type range so

1.succ #=>2,

B.succ #=> C

This doesn’t work with floats(decimals.) Interestingly you can also use the .to_a method on arrays that contain ranges to fill them up. I suppose this is faster.

test=  (‘a’..’d’).to_a
print test

[“a”, “b”, “c”, “d”]=> nil

2. Change the first for number in the_count to be a more typical .each style loop like the others.

the_count= [1,2,3,4,5]

the_count.each {|x| puts “This is the count: #{x}”}

This is the count: 1
This is the count: 2
This is the count: 3
This is the count: 4
This is the count: 5
=> [1, 2, 3, 4, 5]


3. Find the Ruby documentation on arrays and read about them.  What other operations can you do beside the push function? Try <<, which is the same as push but is an oeprator. Fruits MM x is the same as fruits.push(x)

There are tons of array methods but here are some of the ones I found out about:

  • The .size and. length methods can return the number of elemenents in an array
  • An you can compare to arrays to remove duplicates thus:
  • .clear will empty an array of elements
  • .empty? will return true if an array is empty
  • .compact will removes all nil values from an array
  • .pop removes last elements, can be given ( ) parameters to specify how many elements to pop
  • .reverse – reverses the order of elements
  • .sort sorts lists of integers or strings, cannot compare the two or true/fals
  • .to_a to array method, we can use it like this

alphabet = (‘a’..’z’).to_a

#=> assigns all letters in alphabet to the the variable on the left.



Learn Ruby the Hard way Exercise 31: Making Decisions

This exercise expanded on the last and showed a simple fun text game that uses nests of if-statements within if-statements to create more branching output based on the users choices. What caught my eyes was the % symbol used on line 19. Here is can be used reference the users input (assuming none of the conditions for the if/elsif were met.)

Here is the code for exercise 31:


Exercise 31 code

The code above is basically two if-statements nested within the if and elsif keywords of a larger if-statement.

Study Drills

Make new parets of the game and change which decisions people can make. Expand the game out as much as you can before it gets ridiculous.

I didn’t do much apart from add a third elsif branch if the users picks a third door I added.  One of the options prints the entire lyrics for the song Safety Dance. No joke. But seriously you could add millions of elsif options to the top level if-statement and if your text editor allows you to collapse these branches it will still be kind of legible.

Write a completely new game. Maybe you don’t like this one. so make your own. This is your computer, do what you want!

Ok. I made this game based on this song. I made it quite lengthy before I got bored and moved onto the next exercise.

puts “””
You’re walking in the woods
There’s no one around and your phone is dead


puts “””Out of the corner of your eye, you spot him
(Shia LaBeouf)

He’s following you about thirty feet back
He gets down on all fours and breaks into a sprint
He’s gaining on you.
What do you do?

1.Get to the car!
2.Run for your life!


part1 == “1”
puts “Shia Labeouf catches you while your fumbling for your keys. Goood Job!”
part1 == “2”
puts “He’s almost upon you now, and you can see there’s blood on his face”
puts “My God, there’s blood everywhere!”
part2 = gets.chomp

puts “””
Now it’s dark and you seem to have lost him
You see a cabin in the woods

1. creep silently through the underbrush away from the cabin.
2. Move toward the cottage, quietly.”””

part2 = gets.chomp

part2 == “1”
puts “You move stealthily toward it
But your leg! AH! It’s caught in a bear trap!”

puts “> ”
puts “What do you do?
1. Saw off your leg
2. Try to pry the bear trap open”
part2_sub =gets.chomp
part2_sub == “1”
puts “You gnaw off your leg and limp towards the cottage”

elsif part2_sub == “2”
puts “You try to escape the bear trap but it’s too strong and Shia LaBeouf heard that and caught you. Good job!”
puts “You tried %s but Shia LaBeouf heard that and caught you. Good job!” %part2_sub

part2 == “2”
puts “Now you’re on the doorstep but sitting inside is Shia Labeouf
Sharpening an axe!”
puts “You tried %s but Shia LaBeouf heard that and caught you. Good job!” %part2

puts “> ”
puts “But wait he doesn’t here you:”
puts “What do you do? ”
puts “1. Sneak up and strangle him”
puts “2. Wrestle the axe from him”

part3 = gets.chomp
if part3 == “1”
puts “You strangle him. Your safe at last from Shia Labeouf”
elsif part3 == “2”
puts “Shia LaBeouf overpowers you. Good job!”
puts “You tried %s but Shia LaBeouf heard you and attacks you with his axe. Your dead….good job!” %part3
puts “You tried to %s but Shia Labeouf caught you. Good job!” %part1



Learn Ruby the Hard Way, Exercise 29: What if

This exercise introduced the if keyword which checks to see if a condition is true or false, if true the if keyword tells the program to execute the following code block.

Here is the code for exercise 29.

people = 20
cats = 30
dogs = 15

if people < cats
puts “Too many cats! the world is doomed!”

if people > cats
puts “Not many cats! The world is saved!”

if people < dogs
puts “The world is drooled on!”

if people > dogs
puts “The World is dry!”

dogs +=5

if people >=dogs
puts “People are greater than or equals to dogs”

if people <= dogs
puts “People are less than or equal to dogs.”

if people == dogs
puts “People are dogs”


Running this script returned:

Too many cats! the world is doomed!
The World is dry!
People are greater than or equals to dogs
People are less than or equal to dogs.
People are dogs
=> nil


Study Drills

In this study drill, try to guess what you think the if-statement is and what it does. Try to answer these questions in your own words before moving on to the next exercise:

1. What do you think the if does to the code under it?

If the condition is true we run it, if not we move onto the next block of code.

2.Why does the code under the if need to be indented two spaces?

It doesn’t but it does make the code more legible and I’m pretty sure its a Ruby convention.

3. What happens if it isn’t indented

Nothing will happen and the code will run the same

4. Can you put other Boolean expression from Exercise 27

Yes you can. You can make a whole entire complex medley with boolean expression if you wanted to.  I added ‘&& !(true && false)’ to the code below and it evaluated to true.

if people < cats  && !(true && false)
puts “Too many cats! the world is doomed!”

This basically says, if people are less than cats equals true and the other operand equals true (it does) then puts the string below.

5. What happens if you change the initial value for people, cats and dogs.

Changing the values will make the if statemetns react differently depending on which we change.

E.g. changing people = 20 to people = 1 on line one will return

Too many cats! the world is doomed!
The world is drooled on!
People are less than or equal to dogs.
=> nil

Increment operators

This exercise also introduced new assignment operators which update values by incrementation.  So for example X=X+1 could be rewritten more efficiently using the increment operator, assuming X =1.  X+=1  will return 2.










Learn Ruby the Hard Way, Exercise 30: Else and If

The last exercise introduced the if statements that create branches in the code that run when a boolean expression is true.

So for example we could have the code that just prints stuff  e.g. puts “Bananas” encapsulated inside an if statement that will only run and puts a string if the condition is true.


x = 1
if x == 1
puts “Bananas”

This excercise adds the else and elsif keywords that can be added to an if statement like below



Which output the following:

We should take the cars.
Maybe we could take the trucks.
Alright, let's just take the trucks.
=> nil


Study Drills

1. Try to guess what elsif and else are doing

an elsif keyword adds a second condition to check if the first condition is not true, ruby will jump to the elsif keyword and check if the conditions it supplies are true, you can add bazillions of elsif’s to an if statement. An else will run if all the conditions provided by the if and elsif are not met.

2. Change the number of cars, people, and trucks and then trace through each if-statement to see what will be printed.

Like before in the last exercise, changing the values  of the variables meant different parts of the if statements were true and others weren’t so different strings were printed out.

3. Try some more complex Boolean expressions like cars > people || trucks < cars.

I added this to line 5 of the code as below

if cars > people || trucks < cars
puts “We should take the cars.”

elsif cars < people
puts “We should not take the cars.”
puts “We can’t decide.”

As cars has a higher value than people the first part of the || expression was evaluated and ruby never checked the second half to see if trucks < cars. Either operand in a || expression can be true for it to evaluate to true.

4. Above each line write an English description of what the line does.

Sure here you go

ex30 annotated


A few other bits I picked up:

If none of the conditions in an if statement are true the program will continue to run and jump the end keyword and carry on. If two or more conditions are true, Ruby will just evaluate the first one it finds that is true, execute the associate code block and move to the end keyword.

Also on an unrelated point about the to_integer string method; whilst making an experiment (below) when I supplied gets.chomp with ‘bananas’ instead of either an integer the .to_i  returned the integer 0!



number = gets.chomp.to_i

if number > 0
puts “Number is greater than zero”
elsif number < 0
puts “Number is less than zero”
elsif number == 0
puts “Number is zero”


Number is zero
=> nil

Learn Ruby the Hard Way, Exercise 28: Boolean Practice.

This exercise has you go through using the Boolean and comparison operators from the last exercise ( &&, ||,  !,  !=,  =) and solve a table of Boolean logic expressions below:

  1. true && true
  2. false && true
  3. 1 == 1 && 2 == 1
  4. "test" == "test"
  5. 1 == 1 || 2 != 1
  6. true && 1 == 1
  7. false && 0 != 0
  8. true || 1 == 1
  9. "test" == "testing"
  10. 1 != 0 && 2 == 1
  11. "test" != "testing"
  12. "test" == 1
  13. !(true && false)
  14. !(1 == 1 && 0 != 1)
  15. !(10 == 1 || 1000 == 1000)
  16. !(1 != 10 || 3 == 4)
  17. !("testing" == "testing" && "Zed" == "Cool Guy")
  18. 1 == 1 && (!("testing" == 1 || 1 == 0))
  19. "chunky" == "bacon" && (!(3 == 4 || 3 == 3))
  20. 3 == 3 && (!("testing" == "testing" || "Ruby" == "Fun"))


I wrote down what I thought each would evaluate to  ran it through Irb to get he answers. Spoilers ahead!

  • true && true   #=> TRUE
  • false && true  #=> FALSE
  • 1 == 1 && 2 == 1  #=> FALSE
  • "test" == "test"   #=>  TRUE
  • 1 == 1 || 2 != 1   #=>  TRUE
  • true && 1 == 1   #=> TRUE
  • false && 0 != 0  #=>  FALSE
  • true || 1 == 1   #=>  TRUE
  • "test" == "testing"  #=> FALSE
  • 1 != 0 && 2 == 1   #=> FALSE
  • "test" != "testing" #=> TRUE
  • "test" == 1  #=> FALSE
  • !(true && false)   #=> TRUE
  • !(1 == 1 && 0 != 1)   #=> FALSE 
  • !(10 == 1 || 1000 == 1000) #=> FALSE
  • !(1 != 10 || 3 == 4) #=> FALSE
  • !("testing" == "testing" && "Zed" == "Cool Guy") #=> TRUE. Lol
  • 1 == 1 && (!("testing" == 1 || 1 == 0)) #=> TRUE
  • "chunky" == "bacon" && (!(3 == 4 || 3 == 3)) #=> FALSE
  • 3 == 3 && (!("testing" == "testing" || "Ruby" == "Fun")) #=> FALSE

This exercise was actually fun and after a bit of practice (I had a lot on codecademy) you can whiz through these if you remember to evaluate stuff inside the parentheses first.




Learn Ruby the Hard Way, Exercise 27: memorising Logic.

This exercise was all about logic and the different operators you can use in  Ruby to determine if a statement is true or false. I get the idea (so far…) that pretty much everything in Ruby is either true or false and most of the time the statements written check to see if a condition is true, if it is then the block of code following will be evaluated and if false then the program moves onto the next block.

This exercise introduced three Boolean operators that we can use to check if something in Ruby is true or false:

&& – ‘AND’

&& checks evaluates to true when both operands are true, for example:

true && true     #=> true

true && false    #=> false

|| – ‘OR’

|| will evaluate to true if either of the operands are true

false || true      #=> true

true || true      #=> true

false || false     #=> false

! – ‘NOT’

! reverses true and false values which is pretty cool.

!(true && false)   #=> true

!true   #=> false

!false  #=> true

Ex27 also showed us some new comparison or relational operators:


Checks to see if two operands are equals like below

true == true   #=> true

false == true  #=> false

42 == 42  #=> true

‘thirty’ ==  30 #=> false


Checks to see if two operands are not equals like below:

40 != 41  #=> true

“Bananas” != true   #=> true

1 != 1   #=> false


This exercise introduced the truth table to memorise  below. Honesty I’ve spent a lot of time already on Codecademy memorizing these so skipped ahead to exercise 28.

NOT true?
!false true
!true false
OR (||) true?
true || false true
true || true true
false || true true
false || false false
AND (&&) true?
true && false false
true && true true
false && true false
false && false false
NOT OR true?
not (true || false) false
not (true || true) false
not (false || true) false
not (false || false) true
NOT AND true?
!(true && false) true
!(true && true) false
!(false && true) true
!(false && false) true
!= true?
1 != 0 true
1 != 1 false
0 != 1 true
0 != 0 false
== true?
1 == 0 false
1 == 1 true
0 == 1 false
0 == 0 true