From: "Jesús Gabriel y Galán" Date: 2010-03-30T00:26:56+09:00 Subject: Re: Another noob question On Mon, Mar 29, 2010 at 4:55 PM, Omar Velez wrote: > Thanks to everyone that helped me a few days ago.  This time I am trying > to write a program that incorporates everything that I have learned in > the last week but I am more than sure that I am making mistakes > somewhere.  Also there is somethings I do not know how to do. > Everything is commented so it should be easy to find.  Also if anyone > has any suggestions about my syntax style please give me advice.  Thanks > again everyone! > > _______________________________________ > > # Program written by Dr. Omar Israel Velez > > # This program will try to integrate several concepts that I have > learned so far > #  The program will ask for some basic information and then it will ask > for a > # list of favorite books.  Afterwards it will sum up the total number of > # characters in the book titles and add how many of each letter there > are. > # finally it will offer a new book as a suggestion based on which letter > was the > # most popular. > > puts "What\s your first name?" ; first_name = gets.chomp ; puts > puts "What\'s your last name?" ; last_name = gets.chomp ; puts > > puts "Well, #{first_name} #{last_name}, tell me four books that you have > read:" > puts # > books_one = gets.chomp ; books_two = gets.chomp # > books_three = gets.chomp ; books_four = gets.chomp # > all_books = ["#{books_one.downcase}", "#{books_two.downcase}", # > "#{books_three.downcase}", "#{books_four.downcase}"].sort all_books = [] 4.times do all_books << gets.chomp.downcase end all_books.sort! > > # Is there a more efficient way to write this code where I don't have to > # isolate each one and I can downcase everything at once? > > puts > > puts "These are the books that you entered #{first_name}." ; puts # > all_books.each do |books| # >  puts books # > end puts books > > puts > > puts "#{first_name} are these books correct?" ; answer = gets.chomp ; > puts > > if answer == 'yes' >  puts "Ah, very good choice of books #{first_name}." > else >  puts "Well computers never make mistakes so it must be in your head." >  puts "Run the program again please." exit > end > > puts > # > a = books_one.length ; b = books_two.length # > c = books_three.length ; d = books_four.length > #  Same question as before, can I .length everything at the same time > and make > #  the code more efficient? > # > total_characters = a + b + c + d total_characters = all_books.inject(0) {|total, book| total + book.length} > > #  I cheated and just went with the total number of characters.  But how > do I > #  add up the total number of each letter and then suggest a book for > each letter? > #  just two or three examples will be ok I know asking for 26 examples > is just crazy. # The letter histogram h = Hash.new(0) all_books.each {|b| b.split(//).each {|letter| h[letter] += 1}} If you want to suggest a book for each letter, you'll have to have a list of books by letter. Something like: recommendations = {'a' => "A whatever", 'b' => "because..."} # Crazy ! I didn't come up with any book title !!!! (I'm not a native speaker) Then you can recommend based on the present letters, if I understood correctly: h.keys.each {|initial| puts "I recommend: #{recommendations[initial]}"} > puts "There are #{total_characters} total characters in the tittles you > read." > puts > > if total_characters >= 50 >  puts "I recommend reading The Hobbit." >  puts "There is a #{rand(101)}% chance you will like this book." >  puts "Would you like to read this book?" ; answer = gets.chomp ; puts >  if answer == 'yes' >    puts "I am sure that you will enjoy it #{first_name}" >  else >    puts "Oh that is too bad, how about Animal Farm then?" >    puts "There is a #{rand(101)}% chance you will like this book." >  end > else >  puts "I recommend you read The Tale of Two Cities." >  puts "There is a #{rand(101)}% chance you will like this book." >  puts "Would you like to read this book #{first_name}?" ; answer = > gets.chomp >  puts >  if answer == 'yes' >    puts "I am sure that you will have a great time reading it!" >  else >    puts "Ok then, how about A Day in the Life of Alex Jones?" >     puts "There is a #{rand(101)}% chance you will like this book." >  end > end Whenever you see duplicated code, that's a good place to refactor: def recommend(name, books) books.each do |book| puts "I recommend you read #{book}" puts "There's a #{rand(101)}% chance you'll like it" puts "Would you like to read this book #{name}?" answer = gets.chomp if answer == "yes" puts "I'm sure you'll like it" break end end end or something like that, then: if total_characters < 50 recommend(first_name, ["The Hobbit", "Animal Farm"]) else recommend(first_name, ["The Tale of Two Cities", "A Day in the Life of Alex Jones"]) end Well, this is not exactly equivalent to your code, but you get the idea. > > #  I also tried to create a global constant like so.. > #  percent =  "There is a #{rand(101)}% chance you will like this book." > #  and then point to it to make the code look cleaner but it would not > let me. > #  How would I do this? What didn't work? percent = "There is a #{rand(101)} chance you'll like it" puts percent works for me. If you mean that it's always the same percentage, then make it a method: def percentage_sentence "There is a #{rand(101)} chance you'll like it" end puts percent Jesus.