-
Notifications
You must be signed in to change notification settings - Fork 0
Chapter 4
jhonndabi edited this page Sep 6, 2018
·
12 revisions
1) Assign variables city and state to your current city and state of residence. (If residing outside the U.S., substitute the analogous quantities.)
2.5.1 :001 > city = "Guarapuava"
=> "Guarapuava"
2.5.1 :002 > state = "Paraná"
=> "Paraná"
2) Using interpolation, print (using puts) a string consisting of the city and state separated by a comma and a space, as in “Los Angeles, CA”.
2.5.1 :003 > puts "#{city}, #{state}"
Guarapuava, Paraná
=> nil
2.5.1 :004 > puts "#{city}\t#{state}"
Guarapuava Paraná
=> nil
The interpolation doesn't work, and the 'backslashe t' is considered as literal.
2.5.1 :005 > puts '#{city}\t#{state}'
#{city}\t#{state}
=> nil
2.5.1 :001 > "racecar".length
=> 7
2) Confirm using the reverse method that the string in the previous exercise is the same when its letters are reversed.
2.5.1 :002 > "racecar".reverse
=> "racecar"
3) Assign the string “racecar” to the variable s. Confirm using the comparison operator == that s and s.reverse are equal.
2.5.1 :003 > s = "racecar"
=> "racecar"
2.5.1 :004 > s == s.reverse
=> true
4) What is the result of running the code shown in Listing 4.9? How does it change if you reassign the variable s to the string “onomatopoeia”? Hint: Use up-arrow to retrieve and edit previous commands
2.5.1 :005 > puts "It's a palindrome!" if s == s.reverse
It's a palindrome!
=> nil
2.5.1 :006 > s = "onomatopoeia"
=> "onomatopoeia"
2.5.1 :007 > puts "It's a palindrome!" if s == s.reverse
=> nil
1) By replacing FILL_IN with the appropriate comparison test shown in Listing 4.10, define a method for testing palindromes. Hint: Use the comparison shown in Listing 4.9.
2.5.1 :001 > def palindrome_tester(s)
2.5.1 :002?> if s == s.reverse
2.5.1 :003?> puts "It's a palindrome!"
2.5.1 :004?> else
2.5.1 :005?> puts "It's not a palindrome."
2.5.1 :006?> end
2.5.1 :007?> end
=> :palindrome_tester
2) By running your palindrome tester on “racecar” and “onomatopoeia”, confirm that the first is a palindrome and the second isn’t.
2.5.1 :008 > palindrome_tester "racecar"
It's a palindrome!
=> nil
2.5.1 :009 > palindrome_tester "onomatopoeia"
It's not a palindrome.
=> nil
3) By calling the nil? method on palindrome_tester("racecar"), confirm that its return value is nil (i.e., calling nil? on the result of the method should return true). This is because the code in Listing 4.10 prints its responses instead of returning them.
2.5.1 :010 > palindrome_tester("racecar").nil?
It's a palindrome!
=> true
1) Assign a to be to the result of splitting the string “A man, a plan, a canal, Panama” on comma-space.
2.5.1 :001 > a = "A man, a plan, a canal, Panama".split(", ")
=> ["A man", "a plan", "a canal", "Panama"]
2.5.1 :002 > s = a.join
=> "A mana plana canalPanama"
3) Split s on whitespace and rejoin on nothing. Use the palindrome test from Listing 4.10 to confirm that the resulting string s is not a palindrome by the current definition. Using the downcase method, show that s.downcase is a palindrome.
2.5.1 :003 > s = s.split(" ").join
=> "AmanaplanacanalPanama"
2.5.1 :004 > def palindrome_tester(s)
2.5.1 :005?> puts "It's a palindrome!" if s == s.reverse
2.5.1 :006?> puts "It's not a palindrome." if s != s.reverse
2.5.1 :007?> end
=> :palindrome_tester
2.5.1 :008 > palindrome_tester s
It's not a palindrome.
=> nil
2.5.1 :009 > palindrome_tester s.downcase
It's a palindrome!
=> nil
4) What is the result of selecting element 7 from the range of letters a through z? What about the same range reversed? Hint: In both cases you will have to convert the range to an array.
2.5.1 :001 > ("a".."z").to_a[7]
=> "h"
2.5.1 :002 > ("a".."z").to_a.reverse[7]
=> "s"
2.5.1 :001 > (0..16).map { |i| 2**i }
=> [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536
2) Define a method called yeller that takes in an array of characters and returns a string with an ALLCAPS version of the input. Verify that yeller(['o', 'l', 'd']) returns "OLD". Hint: Combine map, upcase, and join.
2.5.1 :002 > def yeller(items)
2.5.1 :003?> itemsUp = items.map { |item| item.upcase }
2.5.1 :004?> itemsUp.join
2.5.1 :005?> end
=> :yeller
2.5.1 :006 > yeller ['o', 'l', 'd']
=> "OLD"
3) Define a method called random_subdomain that returns a randomly generated string of eight letters.
2.5.1 :001 > def random_subdomain
2.5.1 :002?> ('a'..'z').to_a.shuffle[0..7].join
2.5.1 :003?> end
=> :random_subdomain
2.5.1 :004 > random_subdomain
=> "muiqoate"
2.5.1 :005 > random_subdomain
=> "agvsryho"
4) By replacing the question marks in Listing 4.12 with the appropriate methods, combine split, shuffle, and join to write a function that shuffles the letters in a given string.
2.5.1 :001 > def string_shuffle(s)
2.5.1 :002?> s.split('').shuffle.join
2.5.1 :003?> end
=> :string_shuffle
2.5.1 :004 > string_shuffle("foobar")
=> "boofar"
2.5.1 :005 > string_shuffle("foobar")
=> "orabof"
1) Define a hash with the keys 'one', 'two', and 'three', and the values 'uno', 'dos', and 'tres'. Iterate over the hash, and for each key/value pair print out "'#{key}' in Spanish is '#{value}'".
2.5.1 :001 > numbers = { :one => 'uno', :two => 'dos', :three => 'tres' }
=> {:one=>"uno", :two=>"dos", :three=>"tres"}
2.5.1 :002 > numbers.each do |key, value|
2.5.1 :003 > puts "'#{key}' in Spanish is '#{value}'"
2.5.1 :004?> end
'one' in Spanish is 'uno'
'two' in Spanish is 'dos'
'three' in Spanish is 'tres'
=> {:one=>"uno", :two=>"dos", :three=>"tres"}
2) Create three hashes called person1, person2, and person3, with first and last names under the keys :first and :last. Then create a params hash so that params[:father] is person1, params[:mother] is person2, and params[:child] is person3. Verify that, for example, params[:father][:first] has the right value.
2.5.1 :001 > person1 = { :first => 'José', :last => 'Silva' }
=> {:first=>"José", :last=>"Silva"}
2.5.1 :002 > person2 = { :first => 'Maria', :last => 'Silva' }
=> {:first=>"Maria", :last=>"Silva"}
2.5.1 :003 > person3 = { :first => 'João', :last => 'Silva' }
=> {:first=>"João", :last=>"Silva"}
2.5.1 :004 > params = { :father => person1, :mother => person2, :child => person3 }
=> {:father=>{:first=>"José", :last=>"Silva"}, :mother=>{:first=>"Maria", :last=>"Silva"}, :child=>{:first=>"João", :last=>"Silva"}}
2.5.1 :005 > params[:father][:first]
=> "José"
3) Define a hash with symbol keys corresponding to name, email, and a “password digest”, and values equal to your name, your email address, and a random string of 16 lower-case letters.
2.5.1 :001 > def random_password
2.5.1 :002?> ('a'..'z').to_a.shuffle[0..15].join
2.5.1 :003?> end
=> :random_password
2.5.1 :004 > user = { :name => "Jonadabe", :email => "[email protected]", :password => random_password }
=> {:name=>"Jonadabe", :email=>"[email protected]", :password=>"mgijhxqksyuncorl"}
4) Find an online version of the Ruby API and read about the Hash method merge. What is the value of the following expression?
2.5.1 :001 > { "a" => 100, "b" => 200 }.merge({ "b" => 300 })
=> {"a"=>100, "b"=>300}
2.5.1 :001 > 1..10
=> 1..10
2) What is the constructor using the Range class and the new method? Hint: new takes two arguments in this context.
2.5.1 :001 > Range.new(1, 10)
=> 1..10
3) Confirm using the == operator that the literal and named constructors from the previous two exercises are identical.
2.5.1 :001 > literal = 1..10
=> 1..10
2.5.1 :002 > constructor = Range.new(1, 10)
=> 1..10
2.5.1 :003 > literal == constructor
=> true
2.5.1 :001 > Range.superclass
=> Object
2.5.1 :002 > Range.superclass.superclass
=> BasicObject
2.5.1 :001 > Hash.superclass
=> Object
2.5.1 :002 > Hash.superclass.superclass
=> BasicObject
2.5.1 :001 > Symbol.superclass
=> Object
2.5.1 :002 > Symbol.superclass.superclass
=> BasicObject
2) Confirm that the method shown in Listing 4.15 works even if we replace self.reverse with just reverse.
2.5.1 :001 > class Word < String
2.5.1 :002?> def palindrome?
2.5.1 :003?> self == reverse
2.5.1 :004?> end
2.5.1 :005?> end
=> :palindrome?
2.5.1 :006 > s = Word.new("level")
=> "level"
2.5.1 :007 > s.palindrome?
=> true
1) Verify that “racecar” is a palindrome and “onomatopoeia” is not. What about the name of the South Indian language “Malayalam”? Hint: Downcase it first.
2.5.1 :001 > class String
2.5.1 :002?> def palindrome?
2.5.1 :003?> self.downcase == reverse.downcase
2.5.1 :004?> end
2.5.1 :005?> end
=> :palindrome?
2.5.1 :006 > "racecar".palindrome?
=> true
2.5.1 :007 > "onomatopoeia".palindrome?
=> false
2.5.1 :008 > "Malayalam".palindrome?
=> true
2) Using Listing 4.16 as a guide, add a shuffle method to the String class. Hint: Refer to Listing 4.12.
2.5.1 :001 > class String
2.5.1 :002?> def shuffle
2.5.1 :003?> self.split('').shuffle.join
2.5.1 :004?> end
2.5.1 :005?> end
=> :shuffle
2.5.1 :006 > "foobar".shuffle
=> "raoofb"
2.5.1 :007 > "foobar".shuffle
=> "bfroao"
2.5.1 :001 > class String
2.5.1 :002?> def shuffle
2.5.1 :003?> split('').shuffle.join
2.5.1 :004?> end
2.5.1 :005?> end
=> :shuffle
2.5.1 :006 > "foobar".shuffle
=> "oroafb"
2.5.1 :007 > "foobar".shuffle
=> "oabofr"
1) By running the Rails console in the toy app’s directory from Chapter 2, confirm that you can create a user object using User.new.
2.5.1 :001 > user = User.new
=> #<User id: nil, name: nil, email: nil, created_at: nil, updated_at: nil>
2.5.1 :002 > user.class
=> User(id: integer, name: string, email: string, created_at: datetime, updated_at: datetime)
2.5.1 :003 > user.class.superclass
=> ApplicationRecord(abstract)
2.5.1 :004 > user.class.superclass.superclass
=> ActiveRecord::Base
2.5.1 :005 > user.class.superclass.superclass.superclass
=> Object
2.5.1 :006 > user.class.superclass.superclass.superclass.superclass
=> BasicObject
1) In the example User class, change from name to separate first and last name attributes, and then add a method called full_name that returns the first and last names separated by a space. Use it to replace the use of name in the formatted email method.
class User
attr_accessor :first_name, :last_name, :email
def initialize(attributes = {})
@first_name = attributes[:first_name]
@last_name = attributes[:last_name]
@email = attributes[:email]
end
def full_name
"#{@first_name} #{@last_name}"
end
def formatted_email
"#{full_name} <#{@email}>"
end
end
2.5.1 :001 > require './example_user'
2.5.1 :002 > user = User.new(first_name: "João", last_name: "Silva", email: "[email protected]")
=> #<User:0x000055a0db8734b8 @first_name="João", @last_name="Silva", @email="[email protected]">
2.5.1 :003 > user.full_name
=> "João Silva"
2.5.1 :004 > user.formatted_email
=> "João Silva <[email protected]>"
2) Add a method called alphabetical_name that returns the last name and first name separated by comma-space.
class User
attr_accessor :first_name, :last_name, :email
def initialize(attributes = {})
@first_name = attributes[:first_name]
@last_name = attributes[:last_name]
@email = attributes[:email]
end
def full_name
"#{@first_name} #{@last_name}"
end
def alphabetical_name
"#{@last_name}, #{@first_name}"
end
def formatted_email
"#{full_name} <#{@email}>"
end
end
2.5.1 :001 > require './example_user'
=> true
2.5.1 :002 > user = User.new(first_name: "João", last_name: "Silva", email: "[email protected]")
=> #<User:0x000055a0db746928 @first_name="João", @last_name="Silva", @email="[email protected]">
2.5.1 :003 > user.alphabetical_name
=> "Silva, João"
2.5.1 :004 > user.full_name.split == user.alphabetical_name.split(', ').reverse
=> true