Forum: Ruby Issues from an extreme beginner

Posted by Bruce Palmer (bruceyspruce)
on 2013-02-07 05:08
Hey guys, great to be part of such a great community! I look forward to
learning Ruby alongside all of you!

I've very recently picked up ruby and have been reading a book called
"Learn to Program"(2005) by Chris Pine. Basically, it's a hands on guide
to Ruby. So I've been going through the basic programs with no problem,
up until now. I've been trying at a program for about an hour now, to no
prevail and was hoping you guys could lend me a hand.

The program asks the user to input their first, middle and last names in
separate strings and displays how many characters are in the combined
three names, in theory. I have no issues obtaining the string and
displaying them, but somewhere along the path of converting the string
to an integer I get messed up.

Now, I'll share some versions of this failed program that have yielded
errors (dashed line's indicate another program):

I get the "Can't convert Fixnum into string (Type error)" for the first
two

-------------------------------------------

puts 'Enter your first, middle and last name:'
name1 = gets.chomp
name2 = gets.chomp
name3 = gets.chomp
names1 = name1.length
names2 = name2.length
names3 = name3.length
puts 'There are ' + names1.to_i + names2.to_i + names3.to_i
puts ' character\'s in your name!'

------------------------------------------

puts 'Enter your first, middle and last name:'
name1 = gets.chomp
name2 = gets.chomp
name3 = gets.chomp
puts 'There are ' + (name1.length).to_i + (name2.length).to_i +
(name3.length).to_i
puts ' character\'s in your name!'

-------------------------------------

And I also had another one (I must have accidently overwritten it) that
converted the strings to integers, by the ".length" method, and back to
strings and added them. Which yielded no error, but instead simply added
the string numbers together (5+6+4=564 instead of 5+6+4=15)

I was just wondering if somebody could take a look at this code and
point me in the right direction.

Much appreciated,
Bruce
Posted by Matthew Kerwin (mattyk)
on 2013-02-07 07:12
(Received via mailing list)
Here's a small hint:

(((str + int => str) + int => str) + int => str)

(str + (int + (int + int => int) => int) => str)

Also, String#length returns an int, so you should never need to call 
.to_i
on it.

Sent from my phone, so excuse the typos.
Posted by Matthew Kerwin (mattyk)
on 2013-02-07 07:15
Matthew Kerwin wrote in post #1095671:
> Here's a small hint:
>
> (((str + int => str) + int => str) + int => str)
>
> (str + (int + (int + int => int) => int) => str)
>
> Also, String#length returns an int, so you should never need to call
> .to_i
> on it.
>
> Sent from my phone, so excuse the typos.

Er, that's a conceptual hint, by the way. You can't actually add an int 
to a string.

(However,  `str + int.to_s`  works fine...)
Posted by Bruce Palmer (bruceyspruce)
on 2013-02-07 07:43
Ahh, thank you Matthew! That was just the push I needed!

I don't know what I was thinking before, brain fart perhaps, but I was
unnecessarily converting back and forth between string and integer.

Anyway, this is the winning program:

puts 'Enter your first, middle and last name:'
name1 = gets.chomp
name2 = gets.chomp
name3 = gets.chomp
names = name1.length + name2.length + name3.length
puts 'There are ' + names.to_s + ' character\'s in your name!'

---------------------------------------------

Now onto greater obstacles! Once more, thanks Matthew!
Posted by Harry Kakueki (Guest)
on 2013-02-07 07:44
(Received via mailing list)
> And I also had another one (I must have accidently overwritten it) that
> converted the strings to integers, by the ".length" method, and back to
> strings and added them. Which yielded no error, but instead simply added
> the string numbers together (5+6+4=564 instead of 5+6+4=15)
>
> I was just wondering if somebody could take a look at this code and
> point me in the right direction.
>

A hint.

p "Bruce".length.class  #> Fixnum
p (1+2+3).to_s.class  #> String



Harry
Posted by "Hajdú Zoltán" <janicetr@fastmail.fm> (Guest)
on 2013-02-07 08:11
(Received via mailing list)
On Thu, Feb 7, 2013, at 7:43, Bruce Palmer wrote:
> puts 'There are ' + names.to_s + ' character\'s in your name!'

puts "There are #{names} character\'s in your name!"

is more efficient imho.

Best Regards:

Zoltan
Posted by Bruce Palmer (bruceyspruce)
on 2013-02-07 08:55
Harry, Zoltan: Thank you both! This book that I'm reading is a pretty 
barebones, basic introduction to the Ruby language.

Shortcuts and different approaches are always as helpful as anything!
Posted by Joel Pearson (virtuoso)
on 2013-02-07 10:02
FYI, you don't need to escape the single quote when inside double 
quotes.
"\'" is the same as "'"
Posted by Hassan Schroeder (Guest)
on 2013-02-07 16:26
(Received via mailing list)
On Wed, Feb 6, 2013 at 10:43 PM, Bruce Palmer <lists@ruby-forum.com> 
wrote:

> I don't know what I was thinking before, brain fart perhaps, but I was
> unnecessarily converting back and forth between string and integer.

> names = name1.length + name2.length + name3.length

Or just:   (name1 + name2 + name3).length
Or:          [name1, name2, name3].join.length

> puts 'There are ' + names.to_s + ' character\'s in your name!'

Uh, there's no apostrophe in the plural of "character". FWIW.
(Sorry, personal pet peeve.)
Posted by Love U Ruby (my-ruby)
on 2013-02-07 16:34
"Hajdú Zoltán" <janicetr@fastmail.fm> wrote in post #1095676:
> On Thu, Feb 7, 2013, at 7:43, Bruce Palmer wrote:
>> puts 'There are ' + names.to_s + ' character\'s in your name!'
>
> puts "There are #{names} character\'s in your name!"
>
> is more efficient imho.
>
> Best Regards:
>
> Zoltan


This is fine one :)
Posted by Bruce Palmer (bruceyspruce)
on 2013-02-07 21:39
Hassan Schroeder wrote in post #1095774:
> On Wed, Feb 6, 2013 at 10:43 PM, Bruce Palmer <lists@ruby-forum.com>
> wrote:
>
>> I don't know what I was thinking before, brain fart perhaps, but I was
>> unnecessarily converting back and forth between string and integer.
>
>> names = name1.length + name2.length + name3.length
>
> Or just:   (name1 + name2 + name3).length
> Or:          [name1, name2, name3].join.length
>
>> puts 'There are ' + names.to_s + ' character\'s in your name!'
>
> Uh, there's no apostrophe in the plural of "character". FWIW.
> (Sorry, personal pet peeve.)

I caught this after doing it in, maybe 6 of my prior programs.

I'm surprised nobody caught that sooner!
Posted by Joel Pearson (virtuoso)
on 2013-02-07 22:12
I should have spotted that :o
I guess I was thinking in strings rather than sentences :)
Posted by Matthew Kerwin (mattyk)
on 2013-02-07 22:35
(Received via mailing list)
On 8 February 2013 06:39, Bruce Palmer <lists@ruby-forum.com> wrote:

> > Or:          [name1, name2, name3].join.length
> >
> >> puts 'There are ' + names.to_s + ' character\'s in your name!'
> >
> > Uh, there's no apostrophe in the plural of "character". FWIW.
> > (Sorry, personal pet peeve.)
>
> I caught this after doing it in, maybe 6 of my prior programs.
>
> I'm surprised nobody caught that sooner!
>

Well, we're not marking your assignments for you.  ;)

Here is another approach that is Rubyish, albeit slightly excessive:

    [name1, name2, name3].inject(0) {|sum, name| sum + name.length  }

--
  Matthew Kerwin, B.Sc (CompSci) (Hons)
  http://matthew.kerwin.net.au/
  ABN: 59-013-727-651

  "You'll never find a programming language that frees
  you from the burden of clarifying your ideas." - xkcd
Posted by stomar (Guest)
on 2013-02-07 22:38
(Received via mailing list)
Am 07.02.2013 07:43, schrieb Bruce Palmer:
> name3 = gets.chomp
> names = name1.length + name2.length + name3.length
> puts 'There are ' + names.to_s + ' character\'s in your name!'

You should make it a habit from the start to use more accurate
variable names, like

   characters = name1.length + name2.length + name3.length
   # or: character_number, total_characters, total_character_number, ...

   puts "There are #{characters} characters in your name!"


stomar
Posted by stomar (Guest)
on 2013-02-07 22:41
(Received via mailing list)
Am 07.02.2013 22:25, schrieb Matthew Kerwin:
> Here is another approach that is Rubyish, albeit slightly excessive:
>
>      [name1, name2, name3].inject(0) {|sum, name| sum + name.length  }

IMHO maybe a little too cryptic for a complete newbie.

stomar
Posted by Timothy G. (timothy_g29)
on 2013-02-08 00:40
(Received via mailing list)
on the side-track in case the name has only one character then the word
'character' is usually written as character(s) rather than as an 
apostrophe
this visible abbreviation is a valid way to create two options.
to write it this way will (s) need to be escaped?
for singular and plural to be viable alternatives?
can (s) be escaped by either "\(s)" or " " ?
puts needs singular and plural pronouns and tense
to print 'there is one ,,' or else put 'there are..'
Posted by Hassan Schroeder (Guest)
on 2013-02-08 01:11
(Received via mailing list)
On Thu, Feb 7, 2013 at 3:40 PM, Timothy Gregory <tigre7t@gmail.com> 
wrote:
> on the side-track in case the name has only one character then the word
> 'character' is usually written as character(s) rather than as an apostrophe
> this visible abbreviation is a valid way to create two options.
> to write it this way will (s) need to be escaped?
> for singular and plural to be viable alternatives?
> can (s) be escaped by either "\(s)" or " " ?
> puts needs singular and plural pronouns and tense
> to print 'there is one ,,' or else put 'there are..'

In a pry console, including one Rails file:

1.9.3 (main):0 > require 'active_support/core_ext/string/inflections'
=> true
1.9.3 (main):0 > count = 1
=> 1
1.9.3 (main):0 > "there #{'is'.pluralize(count)} #{count}
#{'character'.pluralize(count)}."
=> "there is 1 character."
1.9.3 (main):0 > count = 3
=> 3
1.9.3 (main):0 > "there #{'is'.pluralize(count)} #{count}
#{'character'.pluralize(count)}."
=> "there is 3 characters."

!! oops, that's a surprising omission, but

1.9.3 (main):0 > ActiveSupport::Inflector.inflections{|inflect|
inflect.plural "is", "are" }
....
1.9.3 (main):0 > "there #{'is'.pluralize(count)} #{count}
#{'character'.pluralize(count)}."
=> "there are 3 characters."

HTH,
Posted by Timothy G. (timothy_g29)
on 2013-02-08 05:01
(Received via mailing list)
hay that is concise and explicit many thanks
 now i am reading docs about //inflections.rb
i grasp your steps under the heading
"String inflections define new methods on the String class"
where '../inflections.rb' has fifteen methods
your solution shows some neat ways it can be adapted
in our case both numbers and strings are in singular and plural
thankfully the output grammar can be corrected to suit either 
alternative
this was a hitch that is solved in ruby
it appears quite a fiddly issue more than it really is


On Fri, Feb 8, 2013 at 11:10 AM, Hassan Schroeder <
Posted by stomar (Guest)
on 2013-02-08 07:01
(Received via mailing list)
Am 08.02.2013 00:40, schrieb Timothy Gregory:
> on the side-track in case the name has only one character then the word
> 'character' is usually written as character(s) rather than as an apostrophe
> this visible abbreviation is a valid way to create two options.
> to write it this way will (s) need to be escaped?
> for singular and plural to be viable alternatives?
> can (s) be escaped by either "\(s)" or " " ?
> puts needs singular and plural pronouns and tense
> to print 'there is one ,,' or else put 'there are..'

1. You do not have to escape `(' and `)' in single or double
    quoted strings.

2. Generally, you can handle "decisions" with a conditional expression:

   if total_characters == 1
     message = "There is 1 character..."
   else
     message = "There are #{total_characters} characters..."
   end
   puts message

   (Just one of many ways to do it.)

You should first learn these basic language features before
playing around with Rails libraries.
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.