A method for summing several variables

Hi everyone,

Just wanted to say thank you for all of your suggestions and coding examples. I will be studying your ideas closely to see if I can implement them in our product. I really
do not have the leeway to alter our product's code structure, I have to live with this fact (argh!!).

Our field variables (the ones we do arithematic on) are set up like:

box1_1 = ''
box1_2 = ''
box1_3 = ''
box1_4 = ''
box1_5 = ''
box1_6 = ''
box1_7 = ''
box1_8 = ''
box1_9 = ''
box1_10 = ''
box1_11 = ''
etc.

The actual amount and thus naming of these variables vary from application to application. Some of the summing operations are quite lengthy as in:

box5_189 = $CUR % (box5_5.to_f + box5_10.to_f + box5_15.to_f + box5_20.to_f + box5_25.to_f + box5_30.to_f + box5_35.to_f + box5_40.to_f + box5_45.to_f + box5_50.to_f + box5_55.to_f + box5_60.to_f + box5_65.to_f + box5_70.to_f + box5_75.to_f + box5_80.to_f + box5_85.to_f + box5_90.to_f + box5_95.to_f + box5_100.to_f + box5_105.to_f + box5_110.to_f + box5_115.to_f + box5_120.to_f + box5_125.to_f + box5_130.to_f + box5_135.to_f + box5_140.to_f + box5_145.to_f + box5_150.to_f + box5_155.to_f + box5_160.to_f + box5_165.to_f + box5_170.to_f + box5_175.to_f + box5_180.to_f + box5_185.to_f + box5_187.to_f)

I will try to find a shortcut method to handle this based on your suggestions, but if I have to manually type in each box name in setting up the implementation, I may
as well just type in the lengthy sum operation as shown above.

Thanks again for all of your help,

Harry Truax

I didn't participate in the initial round, but why not do a generator
and then eval your generated string in the current binding?

  s = (5..185).to_a.select { |e| e % 5 == 0 }.map { |e| "box5_#{e}.to_f" }
  s << "box5_187.to_f"
  box5_189 = $CUR % [eval("(#{s.join(' + ')})", binding)]

This will work so long as there's some kind of pattern you can deal
with (I don't get the box5_187 in your example, but I added it as an
exception).

I tested in irb with:

  v = (5..187).to_a
  v = v.select { |e| (e % 5 == 0) or (e == 187) }.map { |e| "box5_#{e}" }
  v << "box5_187"
  b = binding
  v.each_with_index { |e, i| eval("#{e} = 1.25", b) }
  puts box5_10 # => 1.25
  $CUR = "%020.10f"

    # the above set the test data; the below is the implementation
  s = (5..187).to_a.select { |e| (e % 5 == 0) or (e == 187) }
  s.map! { |e| "box5_#{e}.to_f" }
  box5_189 = $CUR % [eval("(#{s.join(' + ')})", binding)
  puts box5_189 # => 000000047.5000000000
  puts v.size * 1.25 # => 47.5

-austin

···

On Tue, 17 Aug 2004 01:48:09 +0900, Harry Truax <htruax@stf.com> wrote:

Hi everyone,

Just wanted to say thank you for all of your suggestions and coding examples. I will be studying your ideas closely to see if I can implement them in our product. I really
do not have the leeway to alter our product's code structure, I have to live with this fact (argh!!).

Our field variables (the ones we do arithematic on) are set up like:

box1_1 = ''
box1_2 = ''
box1_3 = ''
box1_4 = ''
box1_5 = ''
box1_6 = ''
box1_7 = ''
box1_8 = ''
box1_9 = ''
box1_10 = ''
box1_11 = ''
etc.

The actual amount and thus naming of these variables vary from application to application. Some of the summing operations are quite lengthy as in:

box5_189 = $CUR % (box5_5.to_f + box5_10.to_f + box5_15.to_f + box5_20.to_f + box5_25.to_f + box5_30.to_f + box5_35.to_f + box5_40.to_f + box5_45.to_f + box5_50.to_f + box5_55.to_f + box5_60.to_f + box5_65.to_f + box5_70.to_f + box5_75.to_f + box5_80.to_f + box5_85.to_f + box5_90.to_f + box5_95.to_f + box5_100.to_f + box5_105.to_f + box5_110.to_f + box5_115.to_f + box5_120.to_f + box5_125.to_f + box5_130.to_f + box5_135.to_f + box5_140.to_f + box5_145.to_f + box5_150.to_f + box5_155.to_f + box5_160.to_f + box5_165.to_f + box5_170.to_f + box5_175.to_f + box5_180.to_f + box5_185.to_f + box5_187.to_f)

I will try to find a shortcut method to handle this based on your suggestions, but if I have to manually type in each box name in setting up the implementation, I may
as well just type in the lengthy sum operation as shown above.

--
Austin Ziegler * halostatue@gmail.com
               * Alternate: austin@halostatue.ca

Austin,

The $SAFE level has to be set to 3 for Harry's project (per the thread
last week), so 'eval' is out.

···

--
Lennon
rcoder.net

Thanks Austin,

But unfortunately $SAFE needs to be set to 3 which will preclude the use of
eval( ).

Harry

···

----- Original Message -----
From: "Austin Ziegler" <halostatue@gmail.com>
To: "ruby-talk ML" <ruby-talk@ruby-lang.org>
Sent: Monday, August 16, 2004 1:13 PM
Subject: Re: A method for summing several variables

On Tue, 17 Aug 2004 01:48:09 +0900, Harry Truax <htruax@stf.com> wrote:
> Hi everyone,
>
> Just wanted to say thank you for all of your suggestions and coding

examples. I will be studying your ideas closely to see if I can implement
them in our product. I really

> do not have the leeway to alter our product's code structure, I have to

live with this fact (argh!!).

>
> Our field variables (the ones we do arithematic on) are set up like:
>
> box1_1 = ''
> box1_2 = ''
> box1_3 = ''
> box1_4 = ''
> box1_5 = ''
> box1_6 = ''
> box1_7 = ''
> box1_8 = ''
> box1_9 = ''
> box1_10 = ''
> box1_11 = ''
> etc.
>
> The actual amount and thus naming of these variables vary from

application to application. Some of the summing operations are quite lengthy
as in:

>
> box5_189 = $CUR % (box5_5.to_f + box5_10.to_f + box5_15.to_f +

box5_20.to_f + box5_25.to_f + box5_30.to_f + box5_35.to_f + box5_40.to_f +
box5_45.to_f + box5_50.to_f + box5_55.to_f + box5_60.to_f + box5_65.to_f +
box5_70.to_f + box5_75.to_f + box5_80.to_f + box5_85.to_f + box5_90.to_f +
box5_95.to_f + box5_100.to_f + box5_105.to_f + box5_110.to_f + box5_115.to_f
+ box5_120.to_f + box5_125.to_f + box5_130.to_f + box5_135.to_f +
box5_140.to_f + box5_145.to_f + box5_150.to_f + box5_155.to_f +
box5_160.to_f + box5_165.to_f + box5_170.to_f + box5_175.to_f +
box5_180.to_f + box5_185.to_f + box5_187.to_f)

>
> I will try to find a shortcut method to handle this based on your

suggestions, but if I have to manually type in each box name in setting up
the implementation, I may

> as well just type in the lengthy sum operation as shown above.

I didn't participate in the initial round, but why not do a generator
and then eval your generated string in the current binding?

  s = (5..185).to_a.select { |e| e % 5 == 0 }.map { |e| "box5_#{e}.to_f" }
  s << "box5_187.to_f"
  box5_189 = $CUR % [eval("(#{s.join(' + ')})", binding)]

This will work so long as there's some kind of pattern you can deal
with (I don't get the box5_187 in your example, but I added it as an
exception).

I tested in irb with:

  v = (5..187).to_a
  v = v.select { |e| (e % 5 == 0) or (e == 187) }.map { |e| "box5_#{e}" }
  v << "box5_187"
  b = binding
  v.each_with_index { |e, i| eval("#{e} = 1.25", b) }
  puts box5_10 # => 1.25
  $CUR = "%020.10f"

    # the above set the test data; the below is the implementation
  s = (5..187).to_a.select { |e| (e % 5 == 0) or (e == 187) }
  s.map! { |e| "box5_#{e}.to_f" }
  box5_189 = $CUR % [eval("(#{s.join(' + ')})", binding)
  puts box5_189 # => 000000047.5000000000
  puts v.size * 1.25 # => 47.5

-austin
--
Austin Ziegler * halostatue@gmail.com
               * Alternate: austin@halostatue.ca

"Harry Truax" <htruax@stf.com> schrieb im Newsbeitrag
news:019801c483b7$4b338d20$1000000a@corp.stf.com...

Thanks Austin,

But unfortunately $SAFE needs to be set to 3 which will preclude the use

of

eval( ).

You can set up an evaluator before you switch to $SAFE 3 if you know the
variables beforehand, IMHO that should work:

box1_1 = nil
box1_2 = nil
sum_up = eval( "lambda { " + ((1..2).map {|i| "(box1_#{i} ||
0).to_f" }.join( " + " )) + "}" )
$SAFE = 3
box1_1 = '10'
box1_2 = '20'
p sum_up.call

But personally, I'd prefer a different approach, where you store values
either in an array or you store the UI elements (or whatever your boxes are)
in some kind of container (array, matrix whatever). That's IMHO a better
soltution, but then again I don't know your exact scenario since I didn't
follow the original thread.

Regards

    robert

Harry

From: "Austin Ziegler" <halostatue@gmail.com>
To: "ruby-talk ML" <ruby-talk@ruby-lang.org>
Sent: Monday, August 16, 2004 1:13 PM
Subject: Re: A method for summing several variables

> > Hi everyone,
> >
> > Just wanted to say thank you for all of your suggestions and coding
examples. I will be studying your ideas closely to see if I can implement
them in our product. I really
> > do not have the leeway to alter our product's code structure, I have

to

live with this fact (argh!!).
> >
> > Our field variables (the ones we do arithematic on) are set up like:
> >
> > box1_1 = ''
> > box1_2 = ''
> > box1_3 = ''
> > box1_4 = ''
> > box1_5 = ''
> > box1_6 = ''
> > box1_7 = ''
> > box1_8 = ''
> > box1_9 = ''
> > box1_10 = ''
> > box1_11 = ''
> > etc.
> >
> > The actual amount and thus naming of these variables vary from
application to application. Some of the summing operations are quite

lengthy

as in:
> >
> > box5_189 = $CUR % (box5_5.to_f + box5_10.to_f + box5_15.to_f +
box5_20.to_f + box5_25.to_f + box5_30.to_f + box5_35.to_f + box5_40.to_f +
box5_45.to_f + box5_50.to_f + box5_55.to_f + box5_60.to_f + box5_65.to_f +
box5_70.to_f + box5_75.to_f + box5_80.to_f + box5_85.to_f + box5_90.to_f +
box5_95.to_f + box5_100.to_f + box5_105.to_f + box5_110.to_f +

box5_115.to_f

+ box5_120.to_f + box5_125.to_f + box5_130.to_f + box5_135.to_f +
box5_140.to_f + box5_145.to_f + box5_150.to_f + box5_155.to_f +
box5_160.to_f + box5_165.to_f + box5_170.to_f + box5_175.to_f +
box5_180.to_f + box5_185.to_f + box5_187.to_f)
> >
> > I will try to find a shortcut method to handle this based on your
suggestions, but if I have to manually type in each box name in setting up
the implementation, I may
> > as well just type in the lengthy sum operation as shown above.
>
> I didn't participate in the initial round, but why not do a generator
> and then eval your generated string in the current binding?
>
> s = (5..185).to_a.select { |e| e % 5 == 0 }.map { |e|

"box5_#{e}.to_f" }

> s << "box5_187.to_f"
> box5_189 = $CUR % [eval("(#{s.join(' + ')})", binding)]
>
> This will work so long as there's some kind of pattern you can deal
> with (I don't get the box5_187 in your example, but I added it as an
> exception).
>
> I tested in irb with:
>
> v = (5..187).to_a
> v = v.select { |e| (e % 5 == 0) or (e == 187) }.map { |e|

"box5_#{e}" }

···

----- Original Message -----
> On Tue, 17 Aug 2004 01:48:09 +0900, Harry Truax <htruax@stf.com> wrote:
> v << "box5_187"
> b = binding
> v.each_with_index { |e, i| eval("#{e} = 1.25", b) }
> puts box5_10 # => 1.25
> $CUR = "%020.10f"
>
> # the above set the test data; the below is the implementation
> s = (5..187).to_a.select { |e| (e % 5 == 0) or (e == 187) }
> s.map! { |e| "box5_#{e}.to_f" }
> box5_189 = $CUR % [eval("(#{s.join(' + ')})", binding)
> puts box5_189 # => 000000047.5000000000
> puts v.size * 1.25 # => 47.5
>
> -austin
> --
> Austin Ziegler * halostatue@gmail.com
> * Alternate: austin@halostatue.ca
>
>

In article <019801c483b7$4b338d20$1000000a@corp.stf.com>,

Thanks Austin,

But unfortunately $SAFE needs to be set to 3 which will preclude the use of
eval( ).

Harry

From: "Austin Ziegler" <halostatue@gmail.com>
To: "ruby-talk ML" <ruby-talk@ruby-lang.org>
Sent: Monday, August 16, 2004 1:13 PM
Subject: Re: A method for summing several variables

> Hi everyone,
>
> Just wanted to say thank you for all of your suggestions and coding

examples. I will be studying your ideas closely to see if I can implement
them in our product. I really

> do not have the leeway to alter our product's code structure, I have to

live with this fact (argh!!).

>
> Our field variables (the ones we do arithematic on) are set up like:
>
> box1_1 = ''
> box1_2 = ''
> box1_3 = ''
> box1_4 = ''
> box1_5 = ''
> box1_6 = ''
> box1_7 = ''
> box1_8 = ''
> box1_9 = ''
> box1_10 = ''
> box1_11 = ''
> etc.
>
> The actual amount and thus naming of these variables vary from

application to application. Some of the summing operations are quite lengthy
as in:

>
> box5_189 = $CUR % (box5_5.to_f + box5_10.to_f + box5_15.to_f +

box5_20.to_f + box5_25.to_f + box5_30.to_f + box5_35.to_f + box5_40.to_f +
box5_45.to_f + box5_50.to_f + box5_55.to_f + box5_60.to_f + box5_65.to_f +
box5_70.to_f + box5_75.to_f + box5_80.to_f + box5_85.to_f + box5_90.to_f +
box5_95.to_f + box5_100.to_f + box5_105.to_f + box5_110.to_f + box5_115.to_f
+ box5_120.to_f + box5_125.to_f + box5_130.to_f + box5_135.to_f +
box5_140.to_f + box5_145.to_f + box5_150.to_f + box5_155.to_f +
box5_160.to_f + box5_165.to_f + box5_170.to_f + box5_175.to_f +
box5_180.to_f + box5_185.to_f + box5_187.to_f)

>
> I will try to find a shortcut method to handle this based on your

suggestions, but if I have to manually type in each box name in setting up
the implementation, I may

> as well just type in the lengthy sum operation as shown above.

I didn't participate in the initial round, but why not do a generator
and then eval your generated string in the current binding?

  s = (5..185).to_a.select { |e| e % 5 == 0 }.map { |e| "box5_#{e}.to_f" }
  s << "box5_187.to_f"
  box5_189 = $CUR % [eval("(#{s.join(' + ')})", binding)]

This will work so long as there's some kind of pattern you can deal
with (I don't get the box5_187 in your example, but I added it as an
exception).

I tested in irb with:

  v = (5..187).to_a
  v = v.select { |e| (e % 5 == 0) or (e == 187) }.map { |e| "box5_#{e}" }
  v << "box5_187"
  b = binding
  v.each_with_index { |e, i| eval("#{e} = 1.25", b) }
  puts box5_10 # => 1.25
  $CUR = "%020.10f"

    # the above set the test data; the below is the implementation
  s = (5..187).to_a.select { |e| (e % 5 == 0) or (e == 187) }
  s.map! { |e| "box5_#{e}.to_f" }
  box5_189 = $CUR % [eval("(#{s.join(' + ')})", binding)
  puts box5_189 # => 000000047.5000000000
  puts v.size * 1.25 # => 47.5

-austin
--
Austin Ziegler * halostatue@gmail.com
               * Alternate: austin@halostatue.ca

Here's a crazy idea:
You can't do an 'eval' with $SAFE set to 3, but you could instead of
generating Ruby code, you could generate C code and use something like
RubyInline or Cgenerator (see: CGenerator ).
Either one of those can take C code and generate a shared lib (dll) that
can then be called from Ruby.

The idea is generally the same as Austin's. The only drawback is if
you're on a system that doesn't have a C compiler (*nix's generally do
have a C compiler available, Windows generally doesn't).

Phil

···

Harry Truax <htruax@stf.com> wrote:

----- Original Message -----

On Tue, 17 Aug 2004 01:48:09 +0900, Harry Truax <htruax@stf.com> wrote:

But unfortunately $SAFE needs to be set to 3 which will preclude the use of
eval( ).

Just switch to $SAFE = 4 (in a new thread), to make your eval

Guy Decoux

Or even set up a way to specify the formulae in as convenient a manner
as possible, then do a one time code-generation pass to generate ruby
code from those formulae. The code itself can be run at whatever safe
level you want, exactly as though you'd typed it in by hand.

This is assuming, of course, that the formulae are all known at compile
time - if they change at runtime, your code generation step will look
more like

1.upto(m) {|i| 1.upto(n) {|j|
  rubyfile.puts "box[#{i}][%{j}] = box_#{i}_#{j}"
}}

And then write your code after that using the box[i][j] references.

Neither of these use any form of runtime code generation, and should
therefore satisfy the pickiest of safe levels.

martin

···

Robert Klemme <bob.news@gmx.net> wrote:

"Harry Truax" <htruax@stf.com> schrieb im Newsbeitrag
news:019801c483b7$4b338d20$1000000a@corp.stf.com...
> Thanks Austin,
>
> But unfortunately $SAFE needs to be set to 3 which will preclude the use
of
> eval( ).

You can set up an evaluator before you switch to $SAFE 3 if you know the
variables beforehand, IMHO that should work:

Phil Tomson wrote:
...

Here's a crazy idea:
You can't do an 'eval' with $SAFE set to 3, but you could instead of generating Ruby code, you could generate C code and use something like RubyInline or Cgenerator (see: CGenerator ). Either one of those can take C code and generate a shared lib (dll) that can then be called from Ruby.

That's no better than generating ruby code. $SAFE=3 won't let you create or load a shared lib.

ts wrote:

> But unfortunately $SAFE needs to be set to 3 which will
> preclude the use of eval( ).

Just switch to $SAFE = 4 (in a new thread), to make your eval

We watch and learn, ts :slight_smile:

Guy Decoux

Harry,

With that advice from Guy, your original code can be changed
to something like this:

···

#------------------------------------------------------------
$SAFE=3

box1_1 = '12.9'; box1_2 = '-7'; box1_3 = '33.7'
box1_4 = '5.8'; box1_5 = '1244.66'; box1_6 = '38.8'
box1_7 = '200'; box1_8 = '4.4'; box1_9 = '-23'

#
# Use of lambda (formerly proc), allows direct access to
# the box00_00 variables -- (difficult from a method).
#
box_value = lambda do | box |
  ret_ = nil
  Thread.new { $SAFE=4; eval("ret_ = #{box}") }.join
  ret_.to_f
end

add_boxes = lambda do | box, step, last |
  box_pfx, box_num = box.match(/\A([a-z]+\d+_)(\d+)\z/)[1, 2]
  print 'Summing:'
  sum = 0
  box_num.to_i.step(last, step) do | box_n |
    box = "#{box_pfx}#{box_n}"
    print ' + ', box
    sum += box_value[box]
  end
  res = '%0.2f' % [sum]
  puts "\n = #{res}"
end

add_boxes['box1_1', 4, 9]
add_boxes['box1_2', 2, 8]

#-> Summing: + box1_1 + box1_5 + box1_9
#-> = 1234.56
#-> Summing: + box1_2 + box1_4 + box1_6 + box1_8
#-> = 42.00
#------------------------------------------------------------

I really think that other responses were encouraging you to
consider some much better ways of approaching this problem,
but you stated your constraints very clearly :frowning:

Using a combination of a hash with keys of (e.g.) :box1_6
and the trick below, you might be able to convince your
superiors that the constraints would still be intact.

#------------------------------------------------------------

HBox = {:box10_27 => 4.16, :box11_29 => 11.2}

class Object
  def method_missing(meth)
    bm = meth.to_s.match(/\A([a-z]+)(\d+)_(\d+)\z/) or super
      p bm.to_a
    HBox[meth]
  end
end

p box10_27
p box11_29
p box100_100
p blah

#-> ["box10_27", "box", "10", "27"]
#-> 4.16

#-> ["box11_29", "box", "11", "29"]
#-> 11.2

#-> ["box100_100", "box", "100", "100"]
#-> nil

#-> C:/TEMP/rb8270.TMP:6:in `method_missing': undefined local variable or method 'blah' ...

#------------------------------------------------------------

Hope that's of some help,

:daz

In article <412134AF.1060900@path.berkeley.edu>,

···

Joel VanderWerf <vjoel@PATH.Berkeley.EDU> wrote:

Phil Tomson wrote:
..

Here's a crazy idea:
You can't do an 'eval' with $SAFE set to 3, but you could instead of
generating Ruby code, you could generate C code and use something like
RubyInline or Cgenerator (see: CGenerator ).
Either one of those can take C code and generate a shared lib (dll) that
can then be called from Ruby.

That's no better than generating ruby code. $SAFE=3 won't let you create
or load a shared lib.

Ooops... I suppose that makes sense.

So basically, you can't use extensions when you're in $SAFE=3

Phil

"Phil Tomson" <ptkwt@aracnet.com> schrieb im Newsbeitrag
news:cfrg4e0283g@enews1.newsguy.com...

In article <412134AF.1060900@path.berkeley.edu>,
>Phil Tomson wrote:
>..
>> Here's a crazy idea:
>> You can't do an 'eval' with $SAFE set to 3, but you could instead of
>> generating Ruby code, you could generate C code and use something like
>> RubyInline or Cgenerator (see: CGenerator ).
>> Either one of those can take C code and generate a shared lib (dll)

that

>> can then be called from Ruby.
>
>That's no better than generating ruby code. $SAFE=3 won't let you create
>or load a shared lib.
>
>

Ooops... I suppose that makes sense.

So basically, you can't use extensions when you're in $SAFE=3

Not exactly: as long as you load them before switching $SAFE or from another
thread it should work.

    robert

···

Joel VanderWerf <vjoel@PATH.Berkeley.EDU> wrote: