[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

RUBY DRY to replace 6 lines in 1

Josselin

10/30/2007 4:47:00 PM

I have a group of lines (used in Googlemaps display) based on 2 arrays :

zl = 9 if farthest_proposition.distance_to(origin) < = 25.0
zl = 10 if farthest_proposition.distance_to(origin) <= 15.0
zl = 11 if farthest_proposition.distance_to(origin) <= 10.0
zl = 12 if farthest_proposition.distance_to(origin) <= 5.0
zl = 13 if farthest_proposition.distance_to(origin) < =2.0
zl = 14 if farthest_proposition.distance_to(origin) <= 1.0

how could I replace it the dryest way possible ?

zl = [9, 10, 11, 12, 13, 14]
distance = [1.0, 2.0, 5.0, 10.0, 15.0, 25.0]
farthest_proposition.distance_to(origin) is never > 25 (eliminated before..)
farthest_proposition.distance_to(origin) can be 0.0, never negative

thanks for yoru suggestions...

joss

15 Answers

Sebastian probst Eide

10/30/2007 5:41:00 PM

0

Couldn't you write something like this?

def get_zl(origin)
temp_val = farthest_proposition.distance_to(origin)
[{:value=>1.0, :zl=>14}, {:value=>2.0, :zl=>13},
{:value=>5.0, :zl=>12}, {:value=>10.0, :zl=>11},
{:value=>15.0, :zl=>10}, {:value=>25.0, :zl=>9}].each {|pair| return
pair[:zl] if temp_val <= pair[:value]}
end

Maybe it is not the smartest way to solve the problem, but it is a
different solution none the less. Hope it helps and let's you find
the ultimate solution yourself!
I didn't replace it with one line as you requested, but with four...


Best regards
Sebastian

On 30. okt. 2007, at 13.50, Josselin wrote:

> I have a group of lines (used in Googlemaps display) based on 2
> arrays :
>
> zl = 9 if farthest_proposition.distance_to(origin) < = 25.0
> zl = 10 if farthest_proposition.distance_to(origin) <= 15.0
> zl = 11 if farthest_proposition.distance_to(origin) <= 10.0
> zl = 12 if farthest_proposition.distance_to(origin) <= 5.0
> zl = 13 if farthest_proposition.distance_to(origin) < =2.0
> zl = 14 if farthest_proposition.distance_to(origin) <= 1.0
>
> how could I replace it the dryest way possible ?
>
> zl = [9, 10, 11, 12, 13, 14]
> distance = [1.0, 2.0, 5.0, 10.0, 15.0, 25.0]
> farthest_proposition.distance_to(origin) is never > 25 (eliminated
> before..)
> farthest_proposition.distance_to(origin) can be 0.0, never negative
>
> thanks for yoru suggestions...
>
> joss
>
>


Josselin

10/30/2007 6:23:00 PM

0

On 2007-10-30 18:41:01 +0100, Sebastian Probst Eide
<sebastian.probst.eide@gmail.com> said:

> Couldn't you write something like this?
>
> def get_zl(origin)
> temp_val = farthest_proposition.distance_to(origin)
> [{:value=>1.0, :zl=>14}, {:value=>2.0, :zl=>13}, {:value=>5.0,
> :zl=>12}, {:value=>10.0, :zl=>11}, {:value=>15.0, :zl=>10},
> {:value=>25.0, :zl=>9}].each {|pair| return pair[:zl] if temp_val <=
> pair[:value]}
> end
>
> Maybe it is not the smartest way to solve the problem, but it is a
> different solution none the less. Hope it helps and let's you find the
> ultimate solution yourself!
> I didn't replace it with one line as you requested, but with four...
>
>
> Best regards
> Sebastian
>
> On 30. okt. 2007, at 13.50, Josselin wrote:
>
>> I have a group of lines (used in Googlemaps display) based on 2 arrays :
>>
>> zl = 9 if farthest_proposition.distance_to(origin) < = 25.0
>> zl = 10 if farthest_proposition.distance_to(origin) <= 15.0
>> zl = 11 if farthest_proposition.distance_to(origin) <= 10.0
>> zl = 12 if farthest_proposition.distance_to(origin) <= 5.0
>> zl = 13 if farthest_proposition.distance_to(origin) < =2.0
>> zl = 14 if farthest_proposition.distance_to(origin) <= 1.0
>>
>> how could I replace it the dryest way possible ?
>>
>> zl = [9, 10, 11, 12, 13, 14]
>> distance = [1.0, 2.0, 5.0, 10.0, 15.0, 25.0]
>> farthest_proposition.distance_to(origin) is never > 25 (eliminated before..)
>> farthest_proposition.distance_to(origin) can be 0.0, never negative
>>
>> thanks for yoru suggestions...
>>
>> joss

thanks a lot.. when trying to get DRY, I just wonder if it helps in
performance ..
in both cases we perform 6 IF..

Konrad Meyer

10/30/2007 6:28:00 PM

0

Quoth Josselin:
> I have a group of lines (used in Googlemaps display) based on 2 arrays :
>
> zl = 9 if farthest_proposition.distance_to(origin) < = 25.0
> zl = 10 if farthest_proposition.distance_to(origin) <= 15.0
> zl = 11 if farthest_proposition.distance_to(origin) <= 10.0
> zl = 12 if farthest_proposition.distance_to(origin) <= 5.0
> zl = 13 if farthest_proposition.distance_to(origin) < =2.0
> zl = 14 if farthest_proposition.distance_to(origin) <= 1.0
>
> how could I replace it the dryest way possible ?
>
> zl = [9, 10, 11, 12, 13, 14]
> distance = [1.0, 2.0, 5.0, 10.0, 15.0, 25.0]
> farthest_proposition.distance_to(origin) is never > 25 (eliminated before..)
> farthest_proposition.distance_to(origin) can be 0.0, never negative
>
> thanks for yoru suggestions...
>
> joss

zl = case farthest_proposition.distance_to(origin)
when 0..1
14
when 1..2
13
when 2..5
12
when 5..10
11
when 10..15
10
when 15..25
9
end

HTH,
--
Konrad Meyer <konrad@tylerc.org> http://konrad.sobertil...

Martin DeMello

10/30/2007 6:28:00 PM

0

On 10/30/07, Josselin <josselin@wanadoo.fr> wrote:
> I have a group of lines (used in Googlemaps display) based on 2 arrays :
>
> zl = 9 if farthest_proposition.distance_to(origin) < = 25.0
> zl = 10 if farthest_proposition.distance_to(origin) <= 15.0
> zl = 11 if farthest_proposition.distance_to(origin) <= 10.0
> zl = 12 if farthest_proposition.distance_to(origin) <= 5.0
> zl = 13 if farthest_proposition.distance_to(origin) < =2.0
> zl = 14 if farthest_proposition.distance_to(origin) <= 1.0
>
> how could I replace it the dryest way possible ?
>
> zl = [9, 10, 11, 12, 13, 14]
> distance = [1.0, 2.0, 5.0, 10.0, 15.0, 25.0]

s = farthest_proposition.distance_to(origin)
zl = distance.zip(zl.reverse) {|d, z| break [z,d] if s <= d}

martin

Martin DeMello

10/30/2007 6:31:00 PM

0

On 10/30/07, Martin DeMello <martindemello@gmail.com> wrote:
> On 10/30/07, Josselin <josselin@wanadoo.fr> wrote:
> > I have a group of lines (used in Googlemaps display) based on 2 arrays :
> >
> > zl = 9 if farthest_proposition.distance_to(origin) < = 25.0
> > zl = 10 if farthest_proposition.distance_to(origin) <= 15.0
> > zl = 11 if farthest_proposition.distance_to(origin) <= 10.0
> > zl = 12 if farthest_proposition.distance_to(origin) <= 5.0
> > zl = 13 if farthest_proposition.distance_to(origin) < =2.0
> > zl = 14 if farthest_proposition.distance_to(origin) <= 1.0
> >
> > how could I replace it the dryest way possible ?
> >
> > zl = [9, 10, 11, 12, 13, 14]
> > distance = [1.0, 2.0, 5.0, 10.0, 15.0, 25.0]
>
> s = farthest_proposition.distance_to(origin)
> zl = distance.zip(zl.reverse) {|d, z| break [z,d] if s <= d}

oops, that should be break z, of course, not break [z,d]

The basic idea is this: the block form of as.zip(bs) {|a, b|} iterates
over as and bs in parallel, and break argument both exits the current
iterator and returns its argument as the return value of the iterator.

martin

MenTaLguY

10/30/2007 6:41:00 PM

0

On Wed, 31 Oct 2007 01:50:08 +0900, Josselin <josselin@wanadoo.fr> wrote:
> I have a group of lines (used in Googlemaps display) based on 2 arrays :
>
> zl = 9 if farthest_proposition.distance_to(origin) < = 25.0
> zl = 10 if farthest_proposition.distance_to(origin) <= 15.0
> zl = 11 if farthest_proposition.distance_to(origin) <= 10.0
> zl = 12 if farthest_proposition.distance_to(origin) <= 5.0
> zl = 13 if farthest_proposition.distance_to(origin) < =2.0
> zl = 14 if farthest_proposition.distance_to(origin) <= 1.0
>
> how could I replace it the dryest way possible ?
>
> zl = [9, 10, 11, 12, 13, 14]
> distance = [1.0, 2.0, 5.0, 10.0, 15.0, 25.0]
> farthest_proposition.distance_to(origin) is never > 25 (eliminated
> before..)
> farthest_proposition.distance_to(origin) can be 0.0, never negative

FWIW, one line isn't necessarily a realistic goal; DRY doesn't always
mean a large savings in LOC, just maintainability (which an excessively
"golfed" solution can hurt) and often performance.

Assuming two arrays given above are called ZL and DISTANCE (they should
really be constants), one solution is:

farthest_distance = farthest_proposition.distance_to(origin)
zl = DISTANCE.zip(ZL.reverse).find { |distance, _|
farthest_distance <= distance
}.first

Note that eliminating the repeated calls to #distance_to will yield
a performance increase. You could also gain additional performance
by combining ZL and DISTANCE into an associative list:

# (distance, z1) sorted by distance
ZL_BY_DISTANCE = [
[ 1.0, 14 ],
[ 2.0, 13 ],
[ 5.0, 12 ],
[ 10.0, 11 ],
[ 15.0, 10 ],
[ 25.0, 9 ]
]

...at which point you could simply write:

farthest_distance = farthest_proposition.distance_to(origin)
zl = ZL_BY_DISTANCE.find { |distance, _|
farthest_distance <= distance
}.first

(Side note: you might want to consider avoiding lower-case l in
variable names if you can; it is hard to tell apart from the number 1
in many fonts.)

-mental





MenTaLguY

10/30/2007 6:54:00 PM

0

On Wed, 31 Oct 2007 03:25:03 +0900, Josselin <josselin@wanadoo.fr> wrote:
> thanks a lot.. when trying to get DRY, I just wonder if it helps in
> performance ..
> in both cases we perform 6 IF..

I'd be more concerned with the multiple calls to #distance_to in the
original.

If there could be a lot of zoom levels (~50 or more), then it might
be worthwhile to replace the linear search with a binary search (giving
you only log2(N) tests to do rather than the full N), but with the small
number of zoom levels available in Google Maps, the extra complexity
likely isn't worth it.

I also wouldn't worry too much about performance unless this particular
piece of code is a measurable hot spot in your performance profile.
Otherwise, it's easy to tie yourself into knots worrying about the
performance of things which cannot have a significant impact on execution
time.

In the beginning, just focus on clarity and maintainability (which is what
DRY really speaks to): you'll often get a little performance improvement
and shorter code as side benefits without having to worry about either
directly.

-mental


MenTaLguY

10/30/2007 6:56:00 PM

0

On Wed, 31 Oct 2007 03:41:09 +0900, MenTaLguY <mental@rydia.net> wrote:
> (Side note: you might want to consider avoiding lower-case l in
> variable names if you can; it is hard to tell apart from the number 1
> in many fonts.)

(The exception being when it is clearly part of a word, like zoom_level.)

-mental


Konrad Meyer

10/30/2007 7:09:00 PM

0

Quoth MenTaLguY:
> On Wed, 31 Oct 2007 01:50:08 +0900, Josselin <josselin@wanadoo.fr> wrote:
> > I have a group of lines (used in Googlemaps display) based on 2 arrays :
> >
> > zl = 9 if farthest_proposition.distance_to(origin) < = 25.0
> > zl = 10 if farthest_proposition.distance_to(origin) <= 15.0
> > zl = 11 if farthest_proposition.distance_to(origin) <= 10.0
> > zl = 12 if farthest_proposition.distance_to(origin) <= 5.0
> > zl = 13 if farthest_proposition.distance_to(origin) < =2.0
> > zl = 14 if farthest_proposition.distance_to(origin) <= 1.0
> >
> > how could I replace it the dryest way possible ?
> >
> > zl = [9, 10, 11, 12, 13, 14]
> > distance = [1.0, 2.0, 5.0, 10.0, 15.0, 25.0]
> > farthest_proposition.distance_to(origin) is never > 25 (eliminated
> > before..)
> > farthest_proposition.distance_to(origin) can be 0.0, never negative
>
> FWIW, one line isn't necessarily a realistic goal; DRY doesn't always
> mean a large savings in LOC, just maintainability (which an excessively
> "golfed" solution can hurt) and often performance.
>
> Assuming two arrays given above are called ZL and DISTANCE (they should
> really be constants), one solution is:
>
> farthest_distance = farthest_proposition.distance_to(origin)
> zl = DISTANCE.zip(ZL.reverse).find { |distance, _|
> farthest_distance <= distance
> }.first
>
> Note that eliminating the repeated calls to #distance_to will yield
> a performance increase. You could also gain additional performance
> by combining ZL and DISTANCE into an associative list:
>
> # (distance, z1) sorted by distance
> ZL_BY_DISTANCE = [
> [ 1.0, 14 ],
> [ 2.0, 13 ],
> [ 5.0, 12 ],
> [ 10.0, 11 ],
> [ 15.0, 10 ],
> [ 25.0, 9 ]
> ]
>
> ...at which point you could simply write:
>
> farthest_distance = farthest_proposition.distance_to(origin)
> zl = ZL_BY_DISTANCE.find { |distance, _|
> farthest_distance <= distance
> }.first
>
> (Side note: you might want to consider avoiding lower-case l in
> variable names if you can; it is hard to tell apart from the number 1
> in many fonts.)
>
> -mental

Anyone doing any sort of programming should be using a font that distinguishes
1 and l.

Sorry if that sounds a bit harsh, but using a good font is important.

Regards,
--
Konrad Meyer <konrad@tylerc.org> http://konrad.sobertil...

MenTaLguY

10/30/2007 7:17:00 PM

0

On Wed, 31 Oct 2007 04:08:38 +0900, Konrad Meyer <konrad@tylerc.org> wrote:
> Anyone doing any sort of programming should be using a font that
> distinguishes 1 and l.
>
> Sorry if that sounds a bit harsh, but using a good font is important.

This is very true, but there are plenty of situations where you can't
control the font your code will be viewed in. For example, in the case
of email and the web, you are often at the mercy of the font choices made
by your readers (and/or the makers of their software).

So, I'd suggest doing both: use good fonts when you can, and minimize
the use of ambiguous letters for the sake of those viewing your code under
less-than-ideal conditions.

-mental