![]() |
rand(-10..10)
Hi all,
wouldn't it make sense to allow rand -10..10 be aquivalent to -10 + rand(20) the first is by far more obvious. Of course rand -10...10 should work too. What do you think? -- Daniel |
Re: rand(-10..10)
one solution could be
irb(main):210:0* class Range irb(main):211:1> def rand irb(main):212:2> return self.begin + Kernel.rand(self.end-self.begin) irb(main):213:2> end irb(main):214:1> end => nil irb(main):215:0> (-10..10).rand => 2 irb(main):216:0> (-10..10).rand => 6 irb(main):217:0> (-10..10).rand => 4 irb(main):218:0> (-10..10).rand => -1 it's a matter of style to write rand(-10..10) or (-10..10).rand but since 10.sin doesn't work, as opposite tosin(10) non object oriented rand(-10..10) is also a nice thing to have. |
Re: rand(-10..10)
I had similar thoughts a while back. I decided that extending Kernel =20
and mimicing the behavior of rand was the way to go. My code follows: Regards, Morton ------ code starts #!/usr/bin/ruby # Extend Kernel with an enhanced uniform random number generator. # Has the same behavior as rand for a single argument. module Kernel URAND_ARG_ERR =3D "Arguments not valid for urand" # Return a pseudo-random number in the range 0.0...1.0, 0...m, or =20= m..n. def urand(m=3D0, n=3Dnil) case m when Range m, n =3D m.begin, m.end when Integer return rand(m) if n.nil? else raise ArgumentError, URAND_ARG_ERR end raise ArgumentError, URAND_ARG_ERR if n < m m + rand(n - m + 1) end end # Now for a little testing ... def test(times, m=3D0, n=3Dnil) r =3D Array.new(times) if n.nil? then if m =3D=3D 0 then r.collect! {urand} else r.collect! {urand(m)} end else r.collect! {urand(m, n)} end p r end test(3) # =3D> [0.0403243284672499, 0.875487065408379, =20 0.142408860381693] test(3, 11, 11) # =3D> [11, 11, 11] test(10, 3) # =3D> [0, 1, 2, 0, 1, 0, 1, 2, 0, 0] test(10, -1..1) # =3D> [0, 0, 1, -1, -1, 1, -1, 1, -1, 0] test(10, 100, 200) # =3D> [126, 148, 183, 140, 188, 175, 115, 157, 136, =20= 179] begin test(1, 3, -1) rescue ArgumentError =3D> error puts error.message end # =3D> Arguments not valid for urand ------ code ends On Jul 26, 2006, at 8:50 PM, Sch=FCle Daniel wrote: > one solution could be > > irb(main):210:0* class Range > irb(main):211:1> def rand > irb(main):212:2> return self.begin + Kernel.rand(self.end-self.begin) > irb(main):213:2> end > irb(main):214:1> end > =3D> nil > irb(main):215:0> (-10..10).rand > =3D> 2 > irb(main):216:0> (-10..10).rand > =3D> 6 > irb(main):217:0> (-10..10).rand > =3D> 4 > irb(main):218:0> (-10..10).rand > =3D> -1 > > it's a matter of style to write > > rand(-10..10) or (-10..10).rand > > but since 10.sin doesn't work, as opposite tosin(10) > non object oriented rand(-10..10) is also a nice thing to have. |
Re: rand(-10..10)
> irb(main):215:0> (-10..10).rand
> => 2 > irb(main):216:0> (-10..10).rand > => 6 > irb(main):217:0> (-10..10).rand > => 4 > irb(main):218:0> (-10..10).rand > => -1 *Sniff* God I love Ruby. -- Posted via http://www.ruby-forum.com/. |
Re: rand(-10..10)
"the first is by far more obvious."
I think it looks ugly. :-) (-10..10).rand looks much nicer IMHO. -- Posted via http://www.ruby-forum.com/. |
Re: rand(-10..10)
Marc Heiler wrote:
> "the first is by far more obvious." > > I think it looks ugly. :-) > > (-10..10).rand > looks much nicer IMHO. This should work with all enumerables: module Enumerable def rand entries = entries entries.at(Kernel.rand(entries.length)) end end I can't seem to get around the `entries = entries' part -- I don't want to convert the enumerable to an array more than once. Any ideas? Cheers, Daniel |
Re: rand(-10..10)
Daniel Schierbeck wrote:
.... > This should work with all enumerables: > > module Enumerable > def rand > entries = entries > entries.at(Kernel.rand(entries.length)) > end > end > > I can't seem to get around the `entries = entries' part -- I don't want > to convert the enumerable to an array more than once. Any ideas? Enumerable supports sort_by, so could just use: module Enumerable def rand self.sort_by{Kernel.rand}.last end end Cheers Chris |
Re: rand(-10..10)
ChrisH wrote:
> Daniel Schierbeck wrote: > ... >> This should work with all enumerables: >> >> module Enumerable >> def rand >> entries = entries >> entries.at(Kernel.rand(entries.length)) >> end >> end >> >> I can't seem to get around the `entries = entries' part -- I don't want >> to convert the enumerable to an array more than once. Any ideas? > > Enumerable supports sort_by, so could just use: > > module Enumerable > def rand > self.sort_by{Kernel.rand}.last > end > end I think sorting the entire enumerable may be slight overkill, although it of course is prettier :) Daniel |
Re: rand(-10..10)
Daniel Schierbeck <daniel.schierbeck@gmail.com> writes:
>>> This should work with all enumerables: >>> >>> module Enumerable >>> def rand >>> entries = entries >>> entries.at(Kernel.rand(entries.length)) >>> end >>> end >>> >>> I can't seem to get around the `entries = entries' part -- I don't want >>> to convert the enumerable to an array more than once. Any ideas? There's also this, which is possibly more memory-efficient (if the Enumerable in question chews large amounts of memory when being converted to an array, but not with each), but is almost certainly much slower, since it calls rand once per element: module Enumerable def rand ret, i = nil, 0 each {|v| ret = v if 0 == Kernel.rand(i += 1)} ret end end Test code for irb: h=Hash.new(0); 10000.times {h[%w{a b c d e}.rand] += 1}; h |
Re: rand(-10..10)
Daniel Martin wrote:
> module Enumerable > def rand > ret, i = nil, 0 > each {|v| ret = v if 0 == Kernel.rand(i += 1)} > ret > end > end > > Test code for irb: > > h=Hash.new(0); 10000.times {h[%w{a b c d e}.rand] += 1}; h > I think you shouldn't name this method rand. It shadows Kernel.rand in all classes, that already call rand and include Enumerable. The same is true for Range#rand, if people inherit from Range and already call rand. Ruby makes those things possible, but it's also very easy to shoot yourself or others into the foot, if you aren't careful. The Kernel#rand(-5..15) version wouldn't suffer from this problem. It would be a good idea to add this to ruby core, because this functionality is something, that is needed very often. -- Florian Frank |
| All times are GMT. The time now is 10:21 AM. |
Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.