Hi, I slept but I am still exhausted. In any case, I am driven to keep working. I added more to Exercise 19’s Study Drill. I added by asking for user input!

I typed:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
def dresden(wizard_count, vampire_count) puts "We have #{wizard_count} wizards able to defend the city!" puts "There are #{vampire_count} vampires plaguing the populace." end puts "Here we go:" dresden(20, 30) puts "Let's define them as variables:" number_of_wizards = 25 number_of_vampires = 35 dresden(number_of_wizards, number_of_vampires) dresden(43 * 45, 65 / 6) puts "Another way!" dresden(number_of_wizards * 0.05, number_of_vampires * 5) puts "How many wizards are there? " wizard_members = gets.chomp.to_i puts "How about vampires?" vampire_members = gets.chomp.to_i dresden(wizard_members, vampire_members) |

PS C:\ruby> ruby studydrill19a.rb

Here we go:

We have 20 wizards able to defend the city!

There are 30 vampires plaguing the populace.

Let’s define them as variables:

We have 25 wizards able to defend the city!

There are 35 vampires plaguing the populace.

We have 1935 wizards able to defend the city!

There are 10 vampires plaguing the populace.

Another way!

We have 1.25 wizards able to defend the city!

There are 175 vampires plaguing the populace.

How many wizards are there?

56

How about vampires?

36

We have 56 wizards able to defend the city!

There are 36 vampires plaguing the populace.

Awesome!

So, on to **Exercise 20: Functions and Files**

I typed this:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
input_file = ARGV.first def print_all(f) puts f.read end def rewind(f) f.seek(0) end def print_a_line(line_count, f) puts "#{line_count}, #{f.gets.chomp}" end current_file = open(input_file) puts "First let's print the whole file:\n" print_all(current_file) puts "Now let's rewind, kind of like a tape." rewind(current_file) puts "Let's print three lines:" current_line = 1 print_a_line(current_line, current_file) current_line = current_line + 1 print_a_line(current_line, current_file) current_line = current_line + 1 print_a_line(current_line, current_file) |

Nick@WASHBUCKET /c/ruby

$ ruby ex20.rb test.txt

First let’s print the whole file:

Line One

Line Two

Line Three

Now let’s rewind, kind of like a tape.

Let’s print three lines:

1, Line One

2, Line Two

3, Line Three

**1. Write English comments for each line to understand what that line does.**

# Asks for the name of the file at the command line

input_file = ARGV.first

# Creates functions to read the file and rewind through the file, and print each line individually

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
def print_all(f) puts f.read end def rewind(f) f.seek(0) end def print_a_line(line_count, f) puts "#{line_count}, #{f.gets.chomp}" end # Asks to open the file inputed at the command line current_file = open(input_file) # Opens and displayes the whole file. puts "First let's print the whole file:\n" print_all(current_file) # Then opens and rewinds the file puts "Now let's rewind, kind of like a tape." rewind(current_file) # Prints each line individually and puts a line number in front of each puts "Let's print three lines:" current_line = 1 print_a_line(current_line,current_file) current_line = current_line + 1 print_a_line(current_line,current_file) current_line = current_line + 1 print_a_line(current_line,current_file) |

**2. Each time print_a_line is run, you are passing in a variable current_line. Write out what current_line is equal to on each function call, and trace how it becomes line_count in print_a_line.**

1 2 3 4 5 6 |
current_line = 1 # Line One print_a_line(current_line,current_file) current_line = current_line + 1 # Line Two print_a_line(current_line,current_file) current_line = current_line + 1 # Line Three print_a_line(current_line,current_file) |

**3. Find each place a function is used, and check its def to make sure that you are giving it the right arguments.**

All looks good.

**4. Research online what the seek function for file does. Try ri File and see if you can figure it out from there.**

Found here. and here.

**5. Research the shorthand notation += and rewrite the script to use += instead.**

This was harder to find. I finally found it at TestHead (I like this site. He did the same thing I am doing).

So, +- is a shorthand notation for doing variable + 1. So a rewrite would be:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# Asks for the name of the file at the command line input_file = ARGV.first # Creates functions to read the file and rewind through the file, and print each line individually def print_all(f) puts f.read end def rewind(f) f.seek(0) end def print_a_line(line_count, f) puts "#{line_count}, #{f.gets.chomp}" end # Asks to open the file inputed at the command line current_file = open(input_file) # Opens and displayes the whole file. puts "First let's print the whole file:\n" print_all(current_file) # Then opens and rewinds the file puts "Now let's rewind, kind of like a tape." rewind(current_file) # Prints each line individually and puts a line number in front of each puts "Let's print three lines:" current_line = 1 print_a_line(current_line,current_file) current_line +- 1 print_a_line(current_line,current_file) current_line +- 1 print_a_line(current_line,current_file) |

**Exercise 21: Functions Can Return Something**

So, we are now going to learn how to use the = and a return to set variables to be a value from a function. Interesting!

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
def add(a,b) puts "ADDING #{a} + #{b}" return a + b end def subtract(a,b) puts "SUBTRACTING #{a} - #{b}" return a - b end def multiply(a,b) puts "MULTIPLYING #{a} * #{b}" return a * b end def divide(a,b) puts "DIVIDING #{a} / #{b}" return a / b end puts "Let's do some math with just functions!" age = add(30,5) height = subtract(78, 4) weight = multiply(90,2) iq = divide(100,2) puts "Age: #{age}, Height #{height}, Weight: #{weight}, IQ #{iq}" # A puzzle for the extra credit, type it in anyway. puts "Here is a puzzle." what = add(age, subtract(height, multiply(weight, divide(iq, 2)))) puts "That becomes #{what}. Can you do it by hand?" |

and it displays:

$ ruby ex21.rb

Let’s do some math with just functions!

ADDING 30 + 5

SUBTRACTING 78 – 4

MULTIPLYING 90 * 2

DIVIDING 100 / 2

Age: 35, Height 74, Weight: 180, IQ 50

Here is a puzzle.

DIVIDING 50 / 2

MULTIPLYING 180 * 25

SUBTRACTING 74 – 4500

ADDING 35 + -4426

That becomes -4391. Can you do it by hand?

So, the function is called with two arguments: a and b. We print what the function does, we then tell Ruby to return them. Ruby does so, the function ends and then it can be used by other lines as a variable.

**1. If you aren’t really sure what return does, try writing a few of your own functions and have them return some values. You can return anything that you can put to the right of an =.**

OK, so I wrote my own!

The code:

1 2 3 4 5 6 7 8 9 |
def max(a,b) puts "How many cars are chasing max?" puts "there are #{a} trucks and #{b} cars." return a + b end vehicles = max(30, 67) puts "There are #{vehicles} vehicles following Max and Furiosa!" |

Nick@WASHBUCKET /c/ruby

$ ruby sd21a.rb

How many cars are chasing max?

there are 30 trucks and 67 cars.

There are 97 vehicles following Max and Furiosa!

Nice! Witness me, brothers!

**2. At the end of the script is a puzzle. I’m taking the return value of one function and using it as the argument of another function. I’m doing this in a chain so that I’m kind of creating a formula using the functions. It looks really weird, but if you run the script you can see the results. What you should do is try to figure out the normal formula that would recreate this same set of operations.**

Not the greatest at math, but here goes:

(74-180(50/2)+35

And Google verifies it is correct! Yay me and my math skills (first time someone wrote that about me, lol.)

**3. Once you have the formula worked out for the puzzle, get in there and see what happens when you modify the parts of the functions. Try to change it on purpose to make another value.**

I mean, the easy way is to change the 2 at the end. So you would get this:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
def add(a,b) puts "ADDING #{a} + #{b}" return a + b end def subtract(a,b) puts "SUBTRACTING #{a} - #{b}" return a - b end def multiply(a,b) puts "MULTIPLYING #{a} * #{b}" return a * b end def divide(a,b) puts "DIVIDING #{a} / #{b}" return a / b end puts "Let's do some math with just functions!" age = add(30,5) height = subtract(78, 4) weight = multiply(90,2) iq = divide(100,2) puts "Age: #{age}, Height #{height}, Weight: #{weight}, IQ #{iq}" # A puzzle for the extra credit, type it in anyway. puts "Here is a puzzle." what = add(age, subtract(height, multiply(weight, divide(iq, 100)))) puts "That becomes #{what}. Can you do it by hand?" |

$ ruby ex21.rb

Let’s do some math with just functions!

ADDING 30 + 5

SUBTRACTING 78 – 4

MULTIPLYING 90 * 2

DIVIDING 100 / 2

Age: 35, Height 74, Weight: 180, IQ 50

Here is a puzzle.

DIVIDING 50 / 100

MULTIPLYING 180 * 0

SUBTRACTING 74 – 0

ADDING 35 + 74

That becomes 109. Can you do it by hand?

But we can also mix up the order. Like so:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
def add(a,b) puts "ADDING #{a} + #{b}" return a + b end def subtract(a,b) puts "SUBTRACTING #{a} - #{b}" return a - b end def multiply(a,b) puts "MULTIPLYING #{a} * #{b}" return a * b end def divide(a,b) puts "DIVIDING #{a} / #{b}" return a / b end puts "Let's do some math with just functions!" age = add(30,5) height = subtract(78, 4) weight = multiply(90,2) iq = divide(100,2) puts "Age: #{age}, Height #{height}, Weight: #{weight}, IQ #{iq}" # A puzzle for the extra credit, type it in anyway. puts "Here is a puzzle." what = subtract(height, add(age, divide(iq, multiply(weight, 2)))) puts "That becomes #{what}. Can you do it by hand?" |

$ ruby ex21.rb

Let’s do some math with just functions!

ADDING 30 + 5

SUBTRACTING 78 – 4

MULTIPLYING 90 * 2

DIVIDING 100 / 2

Age: 35, Height 74, Weight: 180, IQ 50

Here is a puzzle.

MULTIPLYING 180 * 2

DIVIDING 50 / 360

ADDING 35 + 0

SUBTRACTING 74 – 35

That becomes 39. Can you do it by hand?

Gives one a new found respect for the order of operations, huh?

**4. Do the inverse. Write a simple formula and use the functions in the same way to calculate it.**

Hmm. This was rough but I got this to work:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
def add(a,b) puts "ADDING #{a} + #{b}" return a + b end def subtract(a,b) puts "SUBTRACTING #{a} - #{b}" return a - b end def multiply(a,b) puts "MULTIPLYING #{a} * #{b}" return a * b end def divide(a,b) puts "DIVIDING #{a} / #{b}" return a / b end puts "Let's do some math with just functions!" age = add(30,5) height = subtract(78, 4) weight = multiply(90,2) iq = divide(100,2) puts "Age: #{age}, Height #{height}, Weight: #{weight}, IQ #{iq}" # A puzzle for the extra credit, type it in anyway. puts "Here is a puzzle." what = subtract(height, add(age, divide(iq, multiply(weight, 2)))) puts "That becomes #{what}. Can you do it by hand?" # My very own formula my_own = height * iq / weight + age puts "And the answer is #{my_own}." |

Nick@WASHBUCKET /c/ruby

$ ruby ex21.rb

Let’s do some math with just functions!

ADDING 30 + 5

SUBTRACTING 78 – 4

MULTIPLYING 90 * 2

DIVIDING 100 / 2

Age: 35, Height 74, Weight: 180, IQ 50

Here is a puzzle.

MULTIPLYING 180 * 2

DIVIDING 50 / 360

ADDING 35 + 0

SUBTRACTING 74 – 35

That becomes 39. Can you do it by hand?

And the answer is 55.

**5. Remove the word return and see if the script still works. You’ll find that it does because Ruby implicitly returns whatever the last expression calculates. However, this isn’t clear so I want you to do it explicitly for my book.**

OK, that makes sense. I guess…

Well, two more exercise out of the way. I will be back tomorrow!