Variable from array to function to array

anyone know if it is possible to pass elements from an array (eg 20,50 )
to the function
number_range(min,max) and have the returned value used in the variable

age> below...

def number_range(min,max) # Chooses a random number within
specified range.
  num = min + rand(max - min)
end

array = [ lambda { |age| "An #{age} year old..."}, 20, 50 ]

puts array[0][age returned from number_range method]

···

An 18 year old...

--
Posted via http://www.ruby-forum.com/\.

The obvious thing would be:

puts array[0][number_range(array[1], array[2])]

but this data structure starts to be too complicated. Why is it an
array? Will you have some (many) more entries (lambda + range)? If so,
you could be better off with a class to represent that information:

RangedInterpolation = Struct.new :lambda, :min, :max

array = [ RangedInterpolation.new(lambda { |age| "An #{age} year
old..."}, 20, 50) ]
array.each {|interpolation| puts
interpolation.lambda(number_range(interpolation.min,
interpolation.max))}

You could go one step further and make the pair min,max a Range
object, and even include the number_range method inside the class.

Jesus.

···

On Fri, Aug 17, 2012 at 2:39 AM, Dave Castellano <lists@ruby-forum.com> wrote:

anyone know if it is possible to pass elements from an array (eg 20,50 )
to the function
number_range(min,max) and have the returned value used in the variable
>age> below...

def number_range(min,max) # Chooses a random number within
specified range.
  num = min + rand(max - min)
end

array = [ lambda { |age| "An #{age} year old..."}, 20, 50 ]

puts array[0][age returned from number_range method]

An 18 year old...

anyone know if it is possible to pass elements from an array (eg 20,50 )
to the function
number_range(min,max) and have the returned value used in the variable
>age> below...

def number_range(min,max) # Chooses a random number within
specified range.
   num = min + rand(max - min)
end

This will never return max!

Use min + rand(max - min + 1) or simply rand(min..max)

array = [ lambda { |age| "An #{age} year old..."}, 20, 50 ]

puts array[0][age returned from number_range method]

This would work:

array = [lambda { |age| "An #{age} year old..."}, 20, 50]
puts array[0][rand(array[1]..array[2])]

But this approach seems very odd to me. What are you trying to do?
Why not do it like this:

def random_age_string(range)
   "A #{rand(range)} year old"
end

puts random_age_string(20..40)

But it is rather impossible to provide useful help
unless you give us the bigger picture.

···

Am 17.08.2012 02:39, schrieb Dave Castellano:

--
<https://github.com/stomar/&gt;

The bigger picture... I am saving multiple question templates in a
array and need to store all the info (the question, the min and max
ranges, the units of measure etc assoc with each question. The
associated info is used to build the question ... eg in question one,
need to pass 20,40 to number_range(min,max) and use the returned value
as u.

def number_range(min,max)
  min + rand(max - min + 1) **Thanks!
end

array =[
[ lambda {|u,u_unit| "A slide is placed #{u} #{u_unit} to the left of a
lens...", 20, 40, "cm"],
[ lambda {|v,v_unit| "An image is in focus #{v} #{v_unit} to the right
of a...", 10, 25, "mm],
[....
]

puts array[n][variable returned from number_range method]

A slide is placed 25 cm...

Also,
def random_age_string(range)
   "A #{rand(range)} year old"
end

puts random_age_string(20..40)

Does not work as I am not able to embed "#{}" in a string in an array...
it just returns the string without evaluating...

···

--
Posted via http://www.ruby-forum.com/\.

The bigger picture... I am saving multiple question templates in a
array and need to store all the info (the question, the min and max
ranges, the units of measure etc assoc with each question. The
associated info is used to build the question ... eg in question one,
need to pass 20,40 to number_range(min,max) and use the returned value
as u.

Ok... :slight_smile:

First: did you consider using a templating system for your
"question templates"? You could avoid the lambdas;
instead, you provide a template as a simple string that gets
evaluated later when the needed values are known.

Second: Instead of using nested arrays I would put all the
question-generating functionality into a class.

Assuming the structure of your questions is always the same,
below is one possible way to do it:

require 'erb'

class Question

   attr_reader :unit

   def initialize(text, range, unit)
     @text = ERB.new(text)
     @range = range
     @unit = unit
   end

   def val
     rand(@range)
   end

   def to_s
     @text.result(binding)
   end
end

questions = [
   Question.new('A slide is placed <%= val %> <%= unit %>...',
                20..40, 'cm'),
   Question.new('An image is in focus <%= val %> <%= unit %>...',
                10..15, 'mm')
]

questions.each {|q| puts q }
questions.each {|q| puts q } # results in different values

*BUT:*

- Can't you simply include the unit in the text part?
- Do you really need to have the same question with
   different values in the same run of your program?

How about:

questions = [
   "A slide is placed #{rand(20..40)} cm...",
   "An image is in focus #{rand(10..15)} mm..."
]
questions.each {|q| puts q }

···

Am 17.08.2012 14:15, schrieb Dave Castellano:

def number_range(min,max)
   min + rand(max - min + 1) **Thanks!
end

array =[
[ lambda {|u,u_unit| "A slide is placed #{u} #{u_unit} to the left of a
lens...", 20, 40, "cm"],
[ lambda {|v,v_unit| "An image is in focus #{v} #{v_unit} to the right
of a...", 10, 25, "mm],
[....
]

puts array[n][variable returned from number_range method]

--
<https://github.com/stomar/&gt;

If you're using ruby 1.9, you can use the new hash interpolation syntax:

  puts "Hello %{who}" % { :who => "world" }

outputs

  Hello world

For example:

  def number_range(min,max)
    min + rand(max - min + 1)
  end

  array =[
          [ "A slide is placed %{value} %{unit} to the left of a
lens...", 20, 40, "cm"],
          [ "An image is in focus %{value} %{unit} to the right of
a...", 10, 25, "mm" ],
         ]

  array.each do |item|
    text, min, max, unit = item
    puts text % { :value => number_range(min, max), :unit => unit }
  end

  puts "Hello %{who}" % { :who => "world" }

Regards,
Sean

···

On Fri, Aug 17, 2012 at 1:15 PM, Dave Castellano <lists@ruby-forum.com> wrote:

The bigger picture... I am saving multiple question templates in a
array and need to store all the info (the question, the min and max
ranges, the units of measure etc assoc with each question. The
associated info is used to build the question ... eg in question one,
need to pass 20,40 to number_range(min,max) and use the returned value
as u.

Here an improved version that allows you to use an arbitrary,
possible different set of properties for each question.
Random values are returned if you provide a Range or an Array.

(And it now uses the hash interpolation pointed out by Sean
instead of erb,)

class Question

   def initialize(text, substitutions)
     @text = text
     @substitutions = substitutions
   end

   def to_s
     subst = {}
     @substitutions.each do |k, v|
       if v.class == Range
         subst[k] = rand(v)
       elsif v.class == Array
         subst[k] = v.sample
       else
         subst[k] = v
       end
     end
     @text % subst
   end
end

# You can use arbitrary keys.
# For ranges or arrays a random number / element is used.
questions = [
   Question.new('A slide is placed %{val} %{unit} %{side} of...',
                {:val => 20..40, :unit => 'cm',
                :side => ['left', 'right']}),
   Question.new('An image is ... %{val} mm ... and %{factor} times...',
                {:val => 10..15, :factor => 2..9})
]

questions.each {|q| puts q }
questions.each {|q| puts q } # gives different values

···

--
<https://github.com/stomar/>

Nice, thanks!

···

Am 18.08.2012 01:15, schrieb Sean O'Halpin:

If you're using ruby 1.9, you can use the new hash interpolation syntax:

   puts "Hello %{who}" % { :who => "world" }

--
<https://github.com/stomar/&gt;