Converting and adding variables - ruby

I am having trouble taking a variable given by gets.chomp and either adding it to another variable or to an integer.
puts 'Hello mate what is thy first name?'
name1 = gets.chomp
puts 'Your name is ' + name1 + ' eh? What is thy middle name?'
name2 = gets.chomp
puts 'What is your last name then ' + name1 + '?'
name3 = gets.chomp
Puts 'Oh! So your full name is ' + name1 + ' ' + name2 + ' ' + name3 + ' ?'
puts 'That is lovey!'
puts 'did you know there are ' ' + name1.length.to_i + '+' + 'name2.length.to_i + '+' + name3.length.to_i + '' in your full name
Any Ideas?

There's a few ways to clean this up in Ruby that I'll demonstrate here:
puts 'Hello mate what is thy first name?'
name1 = gets.chomp
# Inline string interpolation using #{...} inside double quotes
puts "Your name is #{name1} eh? What is thy middle name?"
name2 = gets.chomp
# Interpolating a single string argument using the String#% method
puts 'What is your last name then %s?' % name1
name3 = gets.chomp
# Interpolating with an expression that includes code
puts "Oh! So your full name is #{ [ name1, name2, name3 ].join(' ') }?"
puts 'That is lovey!'
# Combining the strings and taking their aggregate length
puts 'Did you know there are %d letters in your full name?' % [
(name1 + name2 + name3).length
]
# Using collect and inject to convert to length, then sum.
puts 'Did you know there are %d letters in your full name?' % [
[ name1, name2, name3 ].collect(&:length).inject(:+)
]
The String#% method is a variant of sprintf that's very convenient for this sort of formatting. It gives you a lot of control over presentation.
That last one might look a bit mind-bending but one of the powerful features of Ruby is being able to string together a series of simple transformations into something that does a lot of work.
That part would look even more concise if you used an array to store the name instead of three independent variables:
name = [ ]
name << gets.chomp
name << gets.chomp
name << gets.chomp
# Name components are name[0], name[1], and name[2]
# Using collect -> inject
name.collect(&:length).inject(:+)
# Using join -> length
name.join.length
It's generally a good idea to organize things in structures that lend themselves to easy manipulation, exchange with other methods, and are easy to persist and restore, such as from a database or a file.

#I think using "#{variable_name}" would be easier to achieve your goal, just
#stay away from the single quotes when using this form of string
#interpolation.
puts "Hello mate what is thy first name?"
name1 = gets.chomp
puts "Your name is #{name1} eh? What is thy middle name?"
name2 = gets.chomp
puts "What is your last name then #{name1}?"
name3 = gets.chomp
puts "Oh! So your full name is #{name1} #{name2} #{name3}?"
puts "That is lovey!"
puts "Did you know there are '#{name1.length + name2.length + name3.length}' letters in your full name?"

Related

Sorting and loops in ruby

This is a program that ask input from the user about the characteristics of a gemstone then prints to the screen. Things like color, price and name. I have written it to an extend where the user enters all this and prints them out. Am now stuck where I should loop and enable the user to enter any number of gemstones. Like if he/she enters 3 gemstones then it should loop and allow the user to enter the characteristics of the 3 gemstone types. I would also like to sort the resulting output of gemstone names in alphabetical order. Appreciated
class GemStones
# input variables
name = ""
color = ""
price = 0
gemstoneNumber = 0
# output variable
gemstoneNumber = 0
# processing
print "How many gemstones do you want to enter? "
gemstoneNumber = gets
print "What is the name of the gemstone? "
name = gets
print "What is the color of the gemstone? "
color = gets
print "What is the price of the gemstone? "
price = gets
puts " You entered #{gemstoneNumber} The name is #{name}, the color is #{color} and price is
$ #{price}"
end
You should not wrap the code in class in the first place. There is no OOP in your code, hence the class is not needed as well. Also, gets returns a string, while for number you likely need an integer.
Here would be a [more-or-less] rubyish version of your code:
print "How many gemstones do you want to enter? "
# ⇓⇓⇓⇓⇓ get rid of trailing CR/LF
# ⇓⇓⇓⇓ convert to integer
gemstoneNumber = gets.chomp.to_i
gemstones =
1.upto(gemstoneNumber).map do |i|
puts
puts "Please enter data for the gemstone ##{i}:"
print "What is the name of the gemstone? "
name = gets.chomp # shave the trailing CR/LF off
print "What is the color of the gemstone? "
color = gets.chomp
print "What is the price of the gemstone? "
price = gets.chomp.to_f # convert to float
# in Ruby we normally use hashes to store
# the named values
{name: name, color: color, price: price}
end
puts "You entered #{gemstoneNumber} gemstones. They are:"
gemstones.each do |gemstone|
puts "Name: #{gemstone[:name]}. " \
"Color: #{gemstone[:color]}. " \
"Price: $#{gemstone[:price]}."
end
Alternatively, you might use the class instead of hash to store the gemstone info.
To sort the gemstones by the name:
puts "You entered #{gemstoneNumber} gemstones. They are:"
# ⇓⇓⇓⇓⇓⇓⇓ HERE
gemstones.sort_by { |gemstone| gemstone[:name] }.each do |gemstone|
puts "Name: #{gemstone[:name]}. " \
"Color: #{gemstone[:color]}. " \
"Price: $#{gemstone[:price]}."
end
The good documentation on enumerations might be found in the official ruby docs: https://ruby-doc.org/core/Enumerable.html#method-i-sort_by (and around.)
You can try this as well.
def gem_stones num
#gem_stones = []
num.times do |a|
print "Enter the name of gemstone #{a+1} "
name=gets.chomp
print "Enter the color of gemstone #{a+1} "
color = gets.chomp
print "Enter the price of gemstone #{a+1} "
price = gets.chomp.to_f
#gem_stones.push({name: name, color: color, price: price})
end
puts #gem_stones.sort_by {|a| a[:name]}.map{|gem| "Name: #{gem[:name]}, Color: #{gem[:color]}, Price: #{gem[:price]}"}.join("\n")
end
puts "Ener the number of gem stones you want to enter?"
num = gets.to_i
gem_stones num

Ruby: no implicit conversion of fixnum into string

Trying to solve one of the problems in Chris Pine's book. Asks users to input their first and last names, then it should display the total number of characters of both.
Here's one of many solutions I've come up with:
puts "First name?"
first_name = gets.chomp
puts "Last name?"
last_name = gets.chomp
total = first_name.length.to_i + last_name.length.to_i
puts 'Did you know you have ' + total + ' characters in your name ' + first_name + last_name + '?'
Ruby is pretty strict about the difference between a String and an Integer, it won't convert for you automatically. You have to ask, but you can ask politely:
puts "Did you know you have #{total} characters in your name #{first_name} #{last_name}?"
You can also do the math this way:
puts "Did you know you have #{first_name.length + last_name.length} characters in your name?"
The #{...} interpolation only works inside "double-quoted" strings, but it does convert to a string whatever the result of that little block is. Single quoted ones avoid interpolation, which is sometimes handy.
If you do want to concatenate strings you have to convert manually:
"this" + 2.to_s
Length returns an integer (no need to convert to_i) so change your code to this:
total = first_name.length + last_name.length

How to insert and get name of multiple users

I am trying to accept the first_name, the middle name, and the last name of the user and then display the abbreviated first, middle name of the user with the unaltered last name. I've written the following code and managed to get for a single user.
h = Hash.new
puts "Enter the first name for user"
h["First_name"] = gets.capitalize
puts "Enter the Middle name for user"
h["Middle_name"] = gets.capitalize
puts "Enter the Last name for user"
h["Last_name"]= gets.capitalize
puts "The name entered is #{h["First_name"][0]}" +
"." + "#{h["Middle_name"][0]}" + "." + "#{h["Last_name"]}"
I want this to happen for five users repeatedly, and display all five name at the end. Can any one help me find a solution for this problem?
Put the whole thing in an array (and end the block with h):
a = Array.new(5) do
h = Hash.new
puts "Enter the first name for user"
h["First_name"] = gets.capitalize
puts "Enter the Middle name for user"
h["Middle_name"] = gets.capitalize
puts "Enter the Last name for user"
h["Last_name"] = gets.capitalize
h
end
In the end, a will have five hashes of the kind you had. You might want to put chomp after each gets to get rid of the newline character.
You can print each name by iterating over a.
a.each do |h|
puts "The name entered is " + h["First_name"][0] +
"." + h["Middle_name"][0] + "." + h["Last_name"]
end

Ruby variables in scripts

This seems to work correctly and display the results I want
Dir["/Users/ondrovic/RubyTest/**/*.txt"].each do |i|
puts i.green if File.readlines(i).grep(/test/).any?
end
Why when I try like this does it not populate info
print "Enter search dir"
src = gets
print "Enter search term"
trm = gets
puts "Looking in #{src} for #{trm}"
Dir["#{src}/**/*.txt"].each do |i|
puts i.green if File.readlines(i).grep(/"#{trm}"/).any?
end
I have also tried it this way
Dir[src + "/**/*.txt"].each do |i|
puts i.green if File.readlines(i).grep(/ + trm + /).any?
end
Working code
require 'colorize'
print "Enter search dir\n".green
src = gets.chomp
print "Enter search term\n".blue
trm = gets.chomp
puts "Looking in #{src} for #{trm}"
Dir["#{src}/**/*.txt"].each do |i|
puts i.green if File.readlines(i).grep(/#{trm}/).any?
end
The return value of the gets includes trailing newline:
>> gets
asdf
=> "asdf\n" # <----
>>
Remove it using String#chomp:
print "Enter search dir"
src = gets.chomp
print "Enter search term"
trm = gets.chomp
...
In addition to that, the pattern /"#{trm}"/ includes ". Remove them:
/#{trm}/
Alternatively, you can use Regexp::new:
Regexp.new(trm)

gets.chomp method excercise in learn to program book

I am doing excercise 5.6 out of "Learn to Program" for a class. I have the following:
puts 'What\'s your first name?'
first = gets.chomp
puts 'What\'s your middle name?'
middle = gets.chomp
puts 'What\'s your last name?'
last = gets.chomp
puts 'Hello, Nice to meet you first middle last'
And I have tried the following:
puts 'What is your first name?'
first = gets.chomp
puts 'What is your middle name?'
middle = gets.chomp
puts 'What is your last name?'
last = gets.chomp
puts 'Hello, Nice to meet you #{first} #{middle} #{last}'
When I get the last "puts" it won't get the first, middle and last name that I wrote in. It says, "Hello, nice to meet you first, middle, last....Instead of Joe John Smith for example. What am I doing wrong?
Thank you so much for your help! I really appreciate it!
When using interpolation, use double quotes " instead of single quotes '
Strings within single quotes ' do not replace variables with their values. Try using double quotes " like so:
puts "Hello, Nice to meet you #{first} #{middle} #{last}"
Single qoutes are nice if you want the string as you typed it, double quotes are useful when you want to replace variable names with their values.
You can also use %Q to have the same effect as you get with double quotes ":
x = 12
puts %Q(I need #{x} pens)
# >> I need 12 pens

Resources