Forum: Ruby calcaulation with unknown numbers of numbers and options fail

Posted by Roelof Wobben (roelof)
on 2012-09-28 09:41
(Received via mailing list)
Hello,

I have this script:

def calculate (options , *numbers)
  options << "add" if options.empty?
  numbers.inject(0) { |sum, number| sum + number } if options == "add"
  numbers.inject() { |sum, number| sum - number } if options == 
"subtract"
end

But now I see this output in Rubymonks :

defaults to addtion when no option is specifiedNoMethodErrorundefined 
method `empty?' for 4:Fixnuminvoking calculate(4, 5, add: true) returns 
9NoMethodErrorundefined method `empty?' for 4:Fixnuminvoking 
calculate(-10, 2, 3, add: true) returns -5NoMethodErrorundefined method 
`empty?' for -10:Fixnuminvoking calculate(0, 0, 0, 0, add: true) returns 
0NoMethodErrorundefined method `empty?' for 0:Fixnum
I think the problem is that I cannot take care that the right values are 
in the right variable.
Anyone a tip how to solve this ?
Roelof
Posted by "Jesús Gabriel y Galán" <jgabrielygalan@gmail.com> (Guest)
on 2012-09-28 10:11
(Received via mailing list)
On Fri, Sep 28, 2012 at 9:40 AM, Roelof Wobben <rwobben@hotmail.com> 
wrote:
> But now I see this output in Rubymonks :
>
>
> Anyone a tip how to solve this ?

The options hash is the first parameter to your function, so pass it
as the first parameter:

calculate({:add => true}, 4,5)

and also, you shouldn't check options == "add", but options[:add] ==
true or just options[:add]

Jesus.
Posted by Roelof Wobben (roelof)
on 2012-09-28 10:19
(Received via mailing list)
> > def calculate (options , *numbers)
> > 2, 3, add: true) returns -5NoMethodErrorundefined method `empty?' for
> as the first parameter:
>
> calculate({:add => true}, 4,5)
>
> and also, you shouldn't check options == "add", but options[:add] ==
> true or just options[:add]
>
> Jesus.
>

Thanks,

I can't change the function call because I try to learn  ruby by a 
interactive website.

I don't understand one remark. You say I shouldn't check the options 
=="add" .
What I' trying to do is to add the word "add" to options if the options 
array = empty.
So the function defaults to "add" when nothing is entered.

Roelof
Posted by "Jesús Gabriel y Galán" <jgabrielygalan@gmail.com> (Guest)
on 2012-09-28 10:32
(Received via mailing list)
On Fri, Sep 28, 2012 at 10:18 AM, Roelof Wobben <rwobben@hotmail.com> 
wrote:
>> > Hello,
>> >
>> > in
>> and also, you shouldn't check options == "add", but options[:add] ==
>> true or just options[:add]
>>
>> Jesus.
>>
>
> Thanks,
>
> I can't change the function call because I try to learn  ruby by a
> interactive website.

Then you have to modify how you declare the function.

>
> I don't understand one remark. You say I shouldn't check the options
> =="add" .
> What I' trying to do is to add the word "add" to options if the options
> array = empty.
> So the function defaults to "add" when nothing is entered.

Options is not an array, it's a hash. but in any case it's never going
to be equal to "add". It will contain an element or a key "add".

Jesus.
Posted by Roelof Wobben (roelof)
on 2012-09-28 10:37
(Received via mailing list)
> >> Subject: Re: calcaulation with unknown numbers of numbers and options fail
> >> > options << "add" if options.empty?
> >> > calculate(-10,
> >>
> >
> > Thanks,
> >
> > I can't change the function call because I try to learn  ruby by a
> > interactive website.
>
> Then you have to modify how you declare the function.

I can declare it as this  def calculate (*arguments)
So i will be one hash but then I have to figure out how to seperate the 
options part and the numbers parts.
back to irb how then arguments will look like and figure it out later.

Roelof
Posted by Jan E. (jacques1)
on 2012-09-28 11:08
Hi,

Roelof Wobben wrote in post #1077862:
> I can declare it as this  def calculate (*arguments)
> So i will be one hash but then I have to figure out how to seperate the
> options part and the numbers parts.

Then why do you do it? Just set the parameter list according to the 
method call:

def calculate *numbers, options
  ...
end

I'm also quite sure that you're not supposed to subtract the numbers 
from 0 but rather from each other. So calculate(1, 2, {}) should yield 1 
- 2 = -1 and not 0 - 1 - 2 = -3.

In this case you must omit the "0" parameter for "inject". And you 
should use the short form:


def calculate *numbers, options
  operator = options[:add] ? :+ : :-
  numbers.reduce operator
end

puts calculate 3, 5, add: true
puts calculate 3, 5, add: false
puts calculate(3, 5, {})
Posted by Roelof Wobben (roelof)
on 2012-09-28 11:16
(Received via mailing list)
> > options part and the numbers parts.
> - 2 = -1 and not 0 - 1 - 2 = -3.
> puts calculate 3, 5, add: true
> puts calculate 3, 5, add: false
> puts calculate(3, 5, {})
>
> --
> Posted via http://www.ruby-forum.com/.
>


Thanks for the help but your code is for me not understandable as 
beginner.
Can you explain the how the operator and the reduce work.

Roelof
Posted by Jan E. (jacques1)
on 2012-09-28 11:25
Roelof Wobben wrote in post #1077868:
> Can you explain the how the operator and the reduce work.

First of all, I must correct the code: It should be

operator = options.empty? || options[:add] ? :+ : :-

to make addition the default.

What I've written down is simply the short form of "inject":

http://ruby-doc.org/core-1.9.3/Enumerable.html#met...

Instead of passing a block, you can also pass a method name or operator
(as a symbol). The elements will then be aggregated using this
method/operator.

So

[1, 2, 3].inject :+

is the same as

[1, 2, 3].inject {|sum, element| sum + element}

But it's obviously shorter. When you use the short form, it's common to
use the method name "reduce" instead of "inject" (but both are the same
method).

And the "operator" variable is used to specify the operator for "reduce"
according to the option hash.
Posted by Roelof Wobben (roelof)
on 2012-09-28 11:39
(Received via mailing list)
> operator = options.empty? || options[:add] ? :+ : :-
>
> method).
>
> And the "operator" variable is used to specify the operator for "reduce"
> according to the option hash.
>
> --
> Posted via http://www.ruby-forum.com/.


Thanks
So if I understand this well then you are saying when  options is empty 
or options = add then  add the numbers otherwise subtract the numbers ?

Roelof
Posted by Jan E. (jacques1)
on 2012-09-28 11:59
Roelof Wobben wrote in post #1077872:
> So if I understand this well then you are saying when  options is empty
> or options = add then  add the numbers otherwise subtract the numbers ?

Yes. But the subtraction was just a guess. I don't know the actual 
assignment.
Posted by Roelof Wobben (roelof)
on 2012-09-28 12:58
(Received via mailing list)
Thanks,

I now finisched Ruby Monks and will go back to ruby koans now.

Roelof
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.