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
puts array[0][age returned from number_range method]
An 18 year old…
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:
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)
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…
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.
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
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…
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 }
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})
]