diff --git a/ch09-writing-your-own-methods/ask.rb b/ch09-writing-your-own-methods/ask.rb index 01716eb35..9e9760e37 100644 --- a/ch09-writing-your-own-methods/ask.rb +++ b/ch09-writing-your-own-methods/ask.rb @@ -1,3 +1,14 @@ def ask question - # your code here + # your code here + while true + puts question + reply = gets.chomp.downcase + if (reply == 'yes' || reply == 'no') + if reply == 'yes' + return true + else + return false + end + end + end end \ No newline at end of file diff --git a/ch09-writing-your-own-methods/old_school_roman_numerals.rb b/ch09-writing-your-own-methods/old_school_roman_numerals.rb index ca6589f2d..8f4d0714a 100644 --- a/ch09-writing-your-own-methods/old_school_roman_numerals.rb +++ b/ch09-writing-your-own-methods/old_school_roman_numerals.rb @@ -1,3 +1,17 @@ def old_roman_numeral num - # your code here + # your code here + num = num.to_i + (puts "Invalid input. Choose a number between 1 and 3000"; return) if ((num.to_i < 1) || (num.to_i > 3000)) + + numerals = {1000=>"M", 500=>"D", 100=>"C", 50=>"L", 10=>"X", 5=>"V", 1=>"I" } + roman = "" + + numerals.keys.each do |k| + n = num/k + if n > 0 + roman += (numerals[k]*n) + num = num % k + end + end + return roman end \ No newline at end of file diff --git a/ch09-writing-your-own-methods/roman_numerals.rb b/ch09-writing-your-own-methods/roman_numerals.rb index 5c93b59ac..95542d46a 100644 --- a/ch09-writing-your-own-methods/roman_numerals.rb +++ b/ch09-writing-your-own-methods/roman_numerals.rb @@ -1,3 +1,18 @@ def roman_numeral num - # your code here + # your code here + num = num.to_i + (puts "Invalid input. Choose a number between 1 and 3000"; return) if ((num.to_i < 1) || (num.to_i > 3000)) + + numerals = {1000=>"M", 500=>"D", 400=>"CD", 100=>"C", 90=>"XC", 50=>"L", 40=>"XL", 10=>"X", 9=>"IX", 5=>"V", 4=>"IV", 1=>"I" } + roman = "" + + numerals.keys.each do |k| + n = num/k + if n > 0 + roman += numerals[k]*n + num = num % k + end + end + + return roman end \ No newline at end of file diff --git a/ch10-nothing-new/dictionary_sort.rb b/ch10-nothing-new/dictionary_sort.rb index c9893d0fd..2b4fb62ec 100644 --- a/ch10-nothing-new/dictionary_sort.rb +++ b/ch10-nothing-new/dictionary_sort.rb @@ -1,3 +1,22 @@ def dictionary_sort arr # your code here + return recursive_sort(arr, []) +end + +def recursive_sort(unsorted_array, sorted_array) + return sorted_array if unsorted_array.empty? + #l = unsorted_array.length-1 + smallest = unsorted_array.pop + unsorted2 = [] + unsorted_array.each do |check| + if check.downcase < smallest.downcase + unsorted2 << smallest + smallest = check + else + unsorted2 << check + end + end + sorted_array << smallest + + recursive_sort(unsorted2, sorted_array) end \ No newline at end of file diff --git a/ch10-nothing-new/english_number.rb b/ch10-nothing-new/english_number.rb index c0129bc4e..aa007ad21 100644 --- a/ch10-nothing-new/english_number.rb +++ b/ch10-nothing-new/english_number.rb @@ -1,3 +1,123 @@ def english_number number - # your code here + if number < 0 # No negative numbers. + return 'Please enter a number that isn\'t negative.' + end + if number == 0 + return 'zero' + end + + # No more special cases! No more returns! + + numString = '' # This is the string we will return. + + onesPlace = ['one', 'two', 'three', 'four', 'five', + 'six', 'seven', 'eight', 'nine'] + tensPlace = ['ten', 'twenty', 'thirty', 'forty', 'fifty', + 'sixty', 'seventy', 'eighty', 'ninety'] + teenagers = ['eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', + 'sixteen', 'seventeen', 'eighteen', 'nineteen'] + nums = {'quindecillion'=>10**48, 'quattuordecillion'=>10**45, 'tredecillion'=>10**42, 'duodecillion'=>10**39, 'undecillion'=>10**36, + 'decillion'=>10**33, 'nonillion'=>10**30, 'octillion'=>10**27, 'septillion'=>10**24, 'sextillion'=>10**21, + 'quintillion'=> 10**18, 'quadrillion'=> 10**15, + 'trillion'=> 10**12, 'billion'=> 10**9, 'million'=> 10**6, 'thousand'=> 10**3, 'hundred'=> 10**2 } + + # "left" is how much of the number we still have left to write out. + # "write" is the part we are writing out right now. + # write and left... get it? :) + left = number + +nums.each do |name,value| + #print name + write = left/value # How many millions left to write out? + left = left - write*value # Subtract off those millions. + +if write > 0 + # trillions + trillions = english_number write + numString = numString + (english_number write) + " " + name.to_s + + if left > 0 + # So we don't write 'two hundredfifty-one'... + numString = numString + ' ' + end + end end + +=begin +write = left/1000000000000 # How many millions left to write out? + left = left - write*1000000000000 # Subtract off those millions. + + if write > 0 + # Now here's a really sly trick: + hundreds = english_number write + numString = numString + hundreds + ' hundred' + # That's called "recursion". So what did I just do? + # I told this method to call itself, but with "write" instead of + # "number". Remember that "write" is (at the moment) the number of + # hundreds we have to write out. After we add "hundreds" to + # "numString", we add the string ' hundred' after it. + # So, for example, if we originally called english_number with + # 1999 (so "number" = 1999), then at this point "write" would + # be 19, and "left" would be 99. The laziest thing to do at this + # point is to have english_number write out the 'nineteen' for us, + # then we write out ' hundred', and then the rest of + # english_number writes out 'ninety-nine'. + + if left > 0 + # So we don't write 'two hundredfifty-one'... + numString = numString + ' ' + end + end +=end +#### ------------> TENS + + write = left/10 # How many tens left to write out? + left = left - write*10 # Subtract off those tens. + + if write > 0 + if ((write == 1) and (left > 0)) + # Since we can't write "tenty-two" instead of "twelve", + # we have to make a special exception for these. + numString = numString + teenagers[left-1] + # The "-1" is because teenagers[3] is 'fourteen', not 'thirteen'. + + # Since we took care of the digit in the ones place already, + # we have nothing left to write. + left = 0 + else + numString = numString + tensPlace[write-1] + # The "-1" is because tensPlace[3] is 'forty', not 'thirty'. + end + + if left > 0 + # So we don't write 'sixtyfour'... + numString = numString + '-' + end + end + + write = left # How many ones left to write out? + left = 0 # Subtract off those ones. + + if write > 0 + numString = numString + onesPlace[write-1] + # The "-1" is because onesPlace[3] is 'four', not 'three'. + end + + # Now we just return "numString"... + return numString +end + +puts english_number( 0) +puts english_number( 9) +puts english_number( 10) +puts english_number( 11) +puts english_number( 17) +puts english_number( 32) +puts english_number( 88) +puts english_number( 99) +puts english_number(100) +puts english_number(101) +puts english_number(234) +puts english_number(3211) +puts english_number(999999) +puts english_number(1000000000000) diff --git a/ch10-nothing-new/ninety_nine_bottles_of_beer.rb b/ch10-nothing-new/ninety_nine_bottles_of_beer.rb index 801de24bd..763950176 100644 --- a/ch10-nothing-new/ninety_nine_bottles_of_beer.rb +++ b/ch10-nothing-new/ninety_nine_bottles_of_beer.rb @@ -1 +1,176 @@ -# your code here \ No newline at end of file +=begin +https://pine.fm/LearnToProgram/chap_08.html + +Expand upon englishNumber. First, put in thousands. +So it should return 'one thousand' instead of 'ten hundred' +and 'ten thousand' instead of 'one hundred hundred'. +Expand upon englishNumber some more. +Now put in millions, so you get 'one million' instead of +'one thousand thousand'. Then try adding billions and trillions. +How high can you go? + +=end + + +def weddingNumber number + if number < 0 # No negative numbers. + return 'Please enter a number that isn\'t negative.' + end + if number == 0 + return 'zero' + end + + # No more special cases! No more returns! + + numString = '' # This is the string we will return. + + onesPlace = ['one', 'two', 'three', 'four', 'five', + 'six', 'seven', 'eight', 'nine'] + tensPlace = ['ten', 'twenty', 'thirty', 'forty', 'fifty', + 'sixty', 'seventy', 'eighty', 'ninety'] + teenagers = ['eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', + 'sixteen', 'seventeen', 'eighteen', 'nineteen'] + + # "left" is how much of the number we still have left to write out. + # "write" is the part we are writing out right now. + # write and left... get it? :) + left = number + +#### ------------> TRILLIONS + +write = left/1000000000000 # How many millions left to write out? + left = left - write*1000000000000 # Subtract off those millions. + +if write > 0 + # trillions + trillions = weddingNumber write + numString = numString + trillions + ' trillion' + + if left > 0 + # So we don't write 'two hundredfifty-one'... + numString = numString + ' and ' + end + end + +#### ------------> BILLIONS + +write = left/1000000000 # How many millions left to write out? + left = left - write*1000000000 # Subtract off those millions. + +if write > 0 + # billions + billions = weddingNumber write + numString = numString + billions + ' billion' + + if left > 0 + # So we don't write 'two hundredfifty-one'... + numString = numString + ' and ' + end + end + +#### ------------> MILLIONS + write = left/1000000 # How many millions left to write out? + left = left - write*1000000 # Subtract off those millions. + +if write > 0 + # millions + millions = weddingNumber write + numString = numString + millions + ' million' + + if left > 0 + # So we don't write 'two hundredfifty-one'... + numString = numString + ' and ' + end + end + +#### ------------> THOUSANDS + + write = left/1000 # How many thousands left to write out? + left = left - write*1000 # Subtract off those thousands. + +if write > 0 + # for thousands + hundreds = weddingNumber write + numString = numString + hundreds + ' thousand' + + if left > 0 + # So we don't write 'two hundredfifty-one'... + numString = numString + ', ' + end + end + +#### ------------> HUNDREDS + + write = left/100 # How many hundreds left to write out? + left = left - write*100 # Subtract off those hundreds. + + if write > 0 + # Now here's a really sly trick: + hundreds = weddingNumber write + numString = numString + hundreds + ' hundred' + # That's called "recursion". So what did I just do? + # I told this method to call itself, but with "write" instead of + # "number". Remember that "write" is (at the moment) the number of + # hundreds we have to write out. After we add "hundreds" to + # "numString", we add the string ' hundred' after it. + # So, for example, if we originally called englishNumber with + # 1999 (so "number" = 1999), then at this point "write" would + # be 19, and "left" would be 99. The laziest thing to do at this + # point is to have englishNumber write out the 'nineteen' for us, + # then we write out ' hundred', and then the rest of + # englishNumber writes out 'ninety-nine'. + + if left > 0 + # So we don't write 'two hundredfifty-one'... + numString = numString + ' and ' + end + end + +#### ------------> TENS + + write = left/10 # How many tens left to write out? + left = left - write*10 # Subtract off those tens. + + if write > 0 + if ((write == 1) and (left > 0)) + # Since we can't write "tenty-two" instead of "twelve", + # we have to make a special exception for these. + numString = numString + teenagers[left-1] + # The "-1" is because teenagers[3] is 'fourteen', not 'thirteen'. + + # Since we took care of the digit in the ones place already, + # we have nothing left to write. + left = 0 + else + numString = numString + tensPlace[write-1] + # The "-1" is because tensPlace[3] is 'forty', not 'thirty'. + end + + if left > 0 + # So we don't write 'sixtyfour'... + numString = numString + '-' + end + end + + write = left # How many ones left to write out? + left = 0 # Subtract off those ones. + + if write > 0 + numString = numString + onesPlace[write-1] + # The "-1" is because onesPlace[3] is 'four', not 'three'. + end + + # Now we just return "numString"... + numString +end + + +def ninety_nine_bottles_of_beer num +while (num > 0) + puts weddingNumber(num) + " bottles of beer on the wall, " + weddingNumber(num) + " bottles of beer." + puts "Take one down and pass it around, " + weddingNumber(num-1) + " bottles of beer on the wall." + num -= 1 +end +end + +ninety_nine_bottles_of_beer 99 diff --git a/ch10-nothing-new/shuffle.rb b/ch10-nothing-new/shuffle.rb index a486ad94c..86a73d6a1 100644 --- a/ch10-nothing-new/shuffle.rb +++ b/ch10-nothing-new/shuffle.rb @@ -1,3 +1,20 @@ def shuffle arr # your code here + shuff = [] + + while !arr.empty? + rand_index = rand(arr.length) + #curr_index = 0 + new_arr = [] + arr.length.times do |i| + if i == rand_index + shuff << arr[rand_index] + else + new_arr << arr[i] + end + end + arr = new_arr + end + + shuff end \ No newline at end of file diff --git a/ch10-nothing-new/sort.rb b/ch10-nothing-new/sort.rb index 44c6deb58..0b8fc4be5 100644 --- a/ch10-nothing-new/sort.rb +++ b/ch10-nothing-new/sort.rb @@ -1,3 +1,12 @@ -def sort arr +def sort (arr) # your code here + print arr + puts "" + return arr if arr.length <= 1 + m = arr.pop + + left = arr.select {|x| x <= m} + right = arr.select{|x| x > m} + + sort(left) + [m] + sort(right) end \ No newline at end of file diff --git a/ch11-reading-and-writing/build_a_better_playlist.rb b/ch11-reading-and-writing/build_a_better_playlist.rb index 3b31bd241..59313080c 100644 --- a/ch11-reading-and-writing/build_a_better_playlist.rb +++ b/ch11-reading-and-writing/build_a_better_playlist.rb @@ -1,3 +1,41 @@ def music_shuffle filenames - # your code here -end + + arr = filenames.sort + l = filenames.length + mid = l/2 + + 5.times do |i| + li = 0 + ri = mid + shuf = [] + while shuf.length < l + if shuf.length%2 == 0 + shuf << arr[li] + li+=1 + else + shuf << arr[ri] + ri+=1 + end + + end #while + #puts shuf + #print shuf + arr = shuf +end # times do + + + cut = rand(l) + l.times do |i| + filenames[(cut+i)%l] = arr[i] + end + filenames +end # end of def + +songs = ['aa/bbb', 'aa/ccc', 'aa/ddd', +'AAA/xxxx', 'AAA/yyyy', 'AAA/zzzz', 'foo/bar'] + +puts(music_shuffle(songs)) + +=begin + +=end diff --git a/ch11-reading-and-writing/build_your_own_playlist.rb b/ch11-reading-and-writing/build_your_own_playlist.rb index 801de24bd..5af13b23c 100644 --- a/ch11-reading-and-writing/build_your_own_playlist.rb +++ b/ch11-reading-and-writing/build_your_own_playlist.rb @@ -1 +1,31 @@ -# your code here \ No newline at end of file +def shuffle arr + # your code here + shuff = [] + + while !arr.empty? + rand_index = rand(arr.length) + #curr_index = 0 + new_arr = [] + arr.length.times do |i| + if i == rand_index + shuff << arr[rand_index] + else + new_arr << arr[i] + end + end + arr = new_arr + end + shuff +end + +def build_your_own_playlist +tracks = shuffle(Dir['**/*.{ogg,mp3,m4a,wma}']) +File.open 'playlist.m3u', 'w' do |f| + tracks.each do |track| + f.write track+"\n" + end +end +puts "Playlist made!" +end + +build_your_own_playlist \ No newline at end of file diff --git a/ch11-reading-and-writing/playlist.m3u b/ch11-reading-and-writing/playlist.m3u new file mode 100644 index 000000000..d4d6328b2 --- /dev/null +++ b/ch11-reading-and-writing/playlist.m3u @@ -0,0 +1,5 @@ +Herbie hancock/02 Watermelon Man.wma +Herbie hancock/03 Sly.wma +Herbie hancock/04 Vein Melter.wma +Herbie hancock/01 Chameleon.wma +Herbie hancock/Head Hunters/02 Watermelon Man.wma diff --git a/ch11-reading-and-writing/safer_picture_downloading.rb b/ch11-reading-and-writing/safer_picture_downloading.rb index 801de24bd..8d6abd485 100644 --- a/ch11-reading-and-writing/safer_picture_downloading.rb +++ b/ch11-reading-and-writing/safer_picture_downloading.rb @@ -1 +1,114 @@ -# your code here \ No newline at end of file +# your code here +=begin +Safer picture downloading. Adapt the picture-downloading/file-renaming +program to your computer by adding some safety features to make sure +you never overwrite a file. A few methods you might find useful are +File.exist? (pass it a filename, and it will return true or false) and exit (like if +return and Napoleon had a baby—it kills your program right where it stands; +this is good for spitting out an error message and then quitting). +=end +# This is where she stores her pictures before +# she gets her YAML on and moves them to the server. +# Just for my own convenience, I'll go there now. +#Dir.chdir '/Photos/PictureInbox' +# First we find all of the pictures to be moved. + +pic_names = Dir["**/*\.{jpg,JPG}"] + +puts 'What would you like to call this batch?' + +batch_name = gets.chomp + +puts + +print "Downloading #{pic_names.length} files: " + +# This will be our counter. We'll start at 1 today, + +# though normally I like to count from 0. + +pic_number = 1 + +pic_names.each do |name| + +print '.' # This is our "progress bar". + +# Make sure we don't save over another file!! + + + +new_name = if pic_number < 10 + +"#{batch_name}0#{pic_number}.jpg" + +else + +"#{batch_name}#{pic_number}.jpg" + +end + +i=0 +while File.exist?(new_name) + puts "That file already exists, renaming new file." + new_name = new_name[0..-5] + (i+=1).to_s + ".jpg" +end +i=0 + + + +# This renames the picture, but since "name" +# has a big long path on it, and "new_name" +# doesn't, it also moves the file to the +# current working directory, which is now +# Katy's PictureInbox folder. +# Since it's a *move*, this effectivey +# downloads and deletes the originals. +# And since this is a memory card, not a +# hard drive, each of these takes a second +# or so; hence, the little dots let her +# know that my program didn't hose her machine. +# (Some marriage advice from your favorite +# author/programmer: it's all about the +# little things.) +=begin +The first time I wrote +this program, I forgot +that little line that +increments the +counter. What +happened? It copied +every picture to the +same new filename... +over the previous +picture! This +effectively deleted +every picture except +for the last one to be +copied. Good thing I +always, always, +always make +backups. Because, +you know, the thing +about computers.... +=end + +# Now where were we? Oh, yeah... + +File.rename name, new_name + +# Finally, we increment the counter. + +pic_number = pic_number + 1 + +end + +puts # This is so we aren't on progress bar line. + +puts 'Done, cutie!' +=begin +Nice! Of course, the full program I wrote for her also downloads the movies, +deletes the thumbnails from the camera (since only the camera can use them), +extracts the time and date from the actual .jpg or .avi file, and renames the file +using that. It also makes sure never to copy over an existing file. Yep, it’s a +pretty fancy program, but that’s for another day. +=end \ No newline at end of file diff --git a/ch12-new-classes-of-objects/birthday_helper.rb b/ch12-new-classes-of-objects/birthday_helper.rb index 801de24bd..b7988515f 100644 --- a/ch12-new-classes-of-objects/birthday_helper.rb +++ b/ch12-new-classes-of-objects/birthday_helper.rb @@ -1 +1,43 @@ -# your code here \ No newline at end of file +# your code here +filename = 'birthdays.csv' +birth_dates = { } +months ={'Jan'=>1, 'Feb'=>2, 'Mar'=>3, 'Apr'=>4, 'May'=>5, 'Jun'=>6, 'Jul'=>7, 'Aug'=>8, 'Sep'=>9, 'Oct'=>10, 'Nov'=>11, 'Dec'=>12} + +(puts "Could not load birthdays from #{filename}"; exit) if !File.exists?(filename) +puts "Loading birthdays from #{filename}..." + +File.open filename do |f| +f.each_line do |entry| +name = entry.slice(0, entry.index(",")) +date = entry.slice(entry.index(",")+2, entry.length) +birth_dates[name] = date +end +end + +puts 'Enter a name and their next birthday will be returned' +name = gets.chomp +(puts "Name not found in file, exiting..."; exit) if !birth_dates.keys.include?(name) + +date = birth_dates[name] +date = date.split(" ") +date[1] = date[1].chomp(",") +year = date[2] +day = date[1] + +month_string = date[0] +month = months[month_string] + +today = Time.new +curr_year = today.strftime("%Y") +birthdate = Time.mktime(year,month,day) +birthday = Time.mktime(curr_year.to_i,month,day) + +age = ((birthday - birthdate)/(60*60*24*365)).to_i + +if birthday > today +puts name + '\'s next birthday will be ' + day.to_s + " " + month_string.to_s + ", #{curr_year}" +puts 'and he/she will be ' + age.to_s + ' years old' +else +puts name + '\'s next birthday will be ' + day.to_s + " " + month_string.to_s + ", #{curr_year.to_i + 1}" +puts 'and he/she will be ' + age.to_s + ' years old' +end \ No newline at end of file diff --git a/ch12-new-classes-of-objects/birthdays.csv b/ch12-new-classes-of-objects/birthdays.csv new file mode 100644 index 000000000..e5115be6a --- /dev/null +++ b/ch12-new-classes-of-objects/birthdays.csv @@ -0,0 +1,8 @@ +Christopher Alexander, Oct 4, 1936 +Christopher Lambert, Mar 29, 1957 +Christopher Lee, May 27, 1922 +Christopher Lloyd, Oct 22, 1938 +Christopher Pine, Aug 3, 1976 +Christopher Plummer, Dec 13, 1927 +Christopher Walken, Mar 31, 1943 +The King of Spain, Jan 5, 1938 \ No newline at end of file diff --git a/ch12-new-classes-of-objects/happy_birthday.rb b/ch12-new-classes-of-objects/happy_birthday.rb index 801de24bd..3da0e7dca 100644 --- a/ch12-new-classes-of-objects/happy_birthday.rb +++ b/ch12-new-classes-of-objects/happy_birthday.rb @@ -1 +1,24 @@ -# your code here \ No newline at end of file +# your code here +=begin +Happy birthday! Ask what year a person was born in, then the month, +and then the day. Figure out how old they are, and give them a big SPANK! +for each birthday they have had. +=end + +puts "What year were you born in?" +year = gets.chomp +puts "What month were you born in? (please enter 1-12 for month)" +month = gets.chomp +puts "What day of the month were you born?" +day = gets.chomp + +now = Time.new +birthday = Time.mktime(year.to_i, month.to_i, day.to_i) + +age = (now - birthday)/(60*60*24*365) + +puts "You are #{age.to_i} years old!" + +age.to_i.times do +puts 'spank' +end \ No newline at end of file diff --git a/ch12-new-classes-of-objects/one_billion_seconds.rb b/ch12-new-classes-of-objects/one_billion_seconds.rb index 801de24bd..b22fbb472 100644 --- a/ch12-new-classes-of-objects/one_billion_seconds.rb +++ b/ch12-new-classes-of-objects/one_billion_seconds.rb @@ -1 +1,3 @@ -# your code here \ No newline at end of file +birth_time = Time.mktime(1983, 9, 11, 7, 40, 54) +billion_seconds_old = birth_time + 1000000000 +puts billion_seconds_old \ No newline at end of file diff --git a/ch12-new-classes-of-objects/party_like_its_roman_to_integer_mcmxcix.rb b/ch12-new-classes-of-objects/party_like_its_roman_to_integer_mcmxcix.rb index 037b6cb09..9e6118f2a 100644 --- a/ch12-new-classes-of-objects/party_like_its_roman_to_integer_mcmxcix.rb +++ b/ch12-new-classes-of-objects/party_like_its_roman_to_integer_mcmxcix.rb @@ -1,3 +1,24 @@ def roman_to_integer roman # your code here + roman.upcase! + numerals = {"M"=>1000, "CM"=> 900, "D"=>500, "CD"=>400, "C"=>100, "XC"=>90, "L"=>50, "XL"=>40, "X"=>10, "IX"=>9, "V"=>5, "IV"=>4, "I"=>1 } + integer = 0 + i=0 + l = roman.length + until i == (l) do + if i < l-1 + r = roman[i]+roman[i+1] + if numerals.keys.include?(r) + integer += numerals[r] + i+=2 + else + integer += numerals[roman[i]] + i+=1 + end + else + integer += numerals[roman[i]] + i+=1 + end + end + return integer end \ No newline at end of file diff --git a/ch13-creating-new-classes/extend_built_in_classes.rb b/ch13-creating-new-classes/extend_built_in_classes.rb index c3e793933..a3b051534 100644 --- a/ch13-creating-new-classes/extend_built_in_classes.rb +++ b/ch13-creating-new-classes/extend_built_in_classes.rb @@ -1,3 +1,25 @@ class Integer # your code here + def factorial + return "Number needs to be more than 0" if self < 0 + return 1 if self <= 1 + self * (self-1).factorial + end + + def to_roman + num = self + (puts "Invalid input. Choose a number between 1 and 3000"; return) if ((num.to_i < 1) || (num.to_i > 3000)) + + numerals = {1000=>"M", 500=>"D", 100=>"C", 50=>"L", 10=>"X", 5=>"V", 1=>"I" } + roman = "" + + numerals.keys.each do |k| + n = num/k + if n > 0 + roman += numerals[k]*n + num = num % k + end + end + return roman + end end \ No newline at end of file diff --git a/ch13-creating-new-classes/interactive_baby_dragon.rb b/ch13-creating-new-classes/interactive_baby_dragon.rb index 801de24bd..c56dde19e 100644 --- a/ch13-creating-new-classes/interactive_baby_dragon.rb +++ b/ch13-creating-new-classes/interactive_baby_dragon.rb @@ -1 +1,165 @@ -# your code here \ No newline at end of file +# your code here +=begin +Write a program so that you can interact with your baby dragon. +You should be able to enter commands like feed and walk, +and have those methods be called on your dragon. Of course, +since what you are inputting are just strings, you will have +to have some sort of method dispatch, where your program checks +which string was entered, and then calls the appropriate method. +=end + +puts "Program starts" + +class Dragon + + def initialize name + @name = name + @asleep = false + @stuffInBelly = 10 # He's full. + @stuffInIntestine = 0 # He doesn't need to go. + @input = "" + + puts @name + ' is born.' + end + + def interact + puts "How do you want to interact with the baby dragon?" + puts "You can choose \"feed\", \"walk\", \"put to bed\", \"toss\" and \"rock\"." + @input = gets.chomp + + while @input != "end" + puts "How do you want to interact with the baby dragon?" + puts "You can choose \"feed\", \"walk\", \"put to bed\", \"toss\", \"rock\", or \"end\" to finish." + + case @input + + when "feed" + feed + + when "walk" + walk + + when "put to bed" + putToBed + + when "toss" + toss + + when "rock" + rock + + when "end" + break + + else + puts "That does not match any option." + end + @input = gets.chomp + end + puts "You say goodbye to the baby dragon" + end + + def feed + puts 'You feed ' + @name + '.' + @stuffInBelly = 10 + passageOfTime + end + + def walk + puts 'You walk ' + @name + '.' + @stuffInIntestine = 0 + passageOfTime + end + + def putToBed + puts 'You put ' + @name + ' to bed.' + @asleep = true + 3.times do + if @asleep + passageOfTime + end + if @asleep + puts @name + ' snores, filling the room with smoke.' + end + end + if @asleep + @asleep = false + puts @name + ' wakes up slowly.' + end + end + + def toss + puts 'You toss ' + @name + ' up into the air.' + puts 'He giggles, which singes your eyebrows.' + passageOfTime + end + + def rock + puts 'You rock ' + @name + ' gently.' + @asleep = true + puts 'He briefly dozes off...' + passageOfTime + if @asleep + @asleep = false + puts '...but wakes when you stop.' + end + end + + private + + # "private" means that the methods defined here are + # methods internal to the object. (You can feed + # your dragon, but you can't ask him if he's hungry.) + + def hungry? + # Method names can end with "?". + # Usually, we only do this if the method + # returns true or false, like this: + @stuffInBelly <= 2 + end + + def poopy? + @stuffInIntestine >= 8 + end + + def passageOfTime + if @stuffInBelly > 0 + # Move food from belly to intestine. + @stuffInBelly = @stuffInBelly - 1 + @stuffInIntestine = @stuffInIntestine + 1 + else # Our dragon is starving! + if @asleep + @asleep = false + puts 'He wakes up suddenly!' + end + puts @name + ' is starving! In desperation, he ate YOU!' + exit # This quits the program. + end + + if @stuffInIntestine >= 10 + @stuffInIntestine = 0 + puts 'Whoops! ' + @name + ' had an accident...' + end + + if hungry? + if @asleep + @asleep = false + puts 'He wakes up suddenly!' + end + puts @name + '\'s stomach grumbles...' + end + + if poopy? + if @asleep + @asleep = false + puts 'He wakes up suddenly!' + end + puts @name + ' does the potty dance...' + end + end + +end + +puts "You create a baby dragon" +pet = Dragon.new 'Norbert' +pet.interact \ No newline at end of file diff --git a/ch13-creating-new-classes/orange_tree.rb b/ch13-creating-new-classes/orange_tree.rb index 025d08907..4fe969ed6 100644 --- a/ch13-creating-new-classes/orange_tree.rb +++ b/ch13-creating-new-classes/orange_tree.rb @@ -7,5 +7,60 @@ class OrangeTree - # your code here -end + def initialize + @height = 0 + @age = 0 + @orange_ount = 0 + @alive = true + end + + def height + if @alive + @height.round(1) + else + 'A dead tree is not very tall. :(' + end + end + + def one_year_passes + #method, which, when called, ages the tree one year. + if @alive + @height += 0.4 + @age += 1 + @orange_count=0 + if @age <= 5 + "This year your tree grew to #{@height.round(1)}m tall," + + " but is still too young to bear fruit." + elsif @age > 5 && @age <= 25 + @orange_count = (@height * 15 - 25).to_i + "This year your tree grew to #{@height.round(1)}m tall, and produced #{@orange_count} oranges." + else + @alive = false + 'Oh, no! The tree is too old, and has died. :(' + end + else + 'A year later, the tree is still dead. :(' + end + end + + def count_the_oranges + if @alive + @orange_count + else + "A dead tree has no oranges. :(" + end + end + + def pick_an_orange + if @alive + if @orange_count == 0 + 'You search every branch, but find no oranges.' + else + @orange_count -= 1 + 'You pick a juicy, delicious orange!' + end + else + 'A dead tree has nothing to pick. :(' + end + end +end \ No newline at end of file diff --git a/ch14-blocks-and-procs/better_program_logger.rb b/ch14-blocks-and-procs/better_program_logger.rb index 0e2e18d57..9fd3a78e1 100644 --- a/ch14-blocks-and-procs/better_program_logger.rb +++ b/ch14-blocks-and-procs/better_program_logger.rb @@ -1,3 +1,9 @@ -def log desc, &block +$depth = 0 +def better_log desc, &block # your code here + puts "#{" "*$depth}Beginning \"#{desc}\"..." + $depth +=1 + result = block.call + $depth -=1 + puts "#{" "*$depth}...\"#{desc}\" finished, returning: #{ result.to_s}" end \ No newline at end of file diff --git a/ch14-blocks-and-procs/even_better_profiling.rb b/ch14-blocks-and-procs/even_better_profiling.rb index b01b78fd8..ece92afb4 100644 --- a/ch14-blocks-and-procs/even_better_profiling.rb +++ b/ch14-blocks-and-procs/even_better_profiling.rb @@ -1,3 +1,12 @@ +$profiling=true def profile block_description, &block # your code here + if $profiling + start_time = Time.new + block.call + duration = Time.new - start_time + puts "#{block_description}: #{duration} seconds" + else + block.call + end end \ No newline at end of file diff --git a/ch14-blocks-and-procs/grandfather_clock.rb b/ch14-blocks-and-procs/grandfather_clock.rb index 916f6d354..6173e2fc1 100644 --- a/ch14-blocks-and-procs/grandfather_clock.rb +++ b/ch14-blocks-and-procs/grandfather_clock.rb @@ -1,3 +1,6 @@ def grandfather_clock &block # your code here + Time.now.strftime("%I").to_i.times do + block.call + end end \ No newline at end of file diff --git a/ch14-blocks-and-procs/program_logger.rb b/ch14-blocks-and-procs/program_logger.rb index 0e2e18d57..de83c4699 100644 --- a/ch14-blocks-and-procs/program_logger.rb +++ b/ch14-blocks-and-procs/program_logger.rb @@ -1,3 +1,6 @@ -def log desc, &block +def program_log desc, &block # your code here + puts "Beginning \"#{desc}\"..." + result = block.call + puts "...\"#{desc}\" finished, returning: #{ result.to_s}" end \ No newline at end of file