# RUBY DRY to replace 6 lines in 1

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

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

Something like this?

zl.reverse[distance.index(distance.select {|x| x >=
farthest_proposition.distance_to(origin)}[0])]

Juan MatÃ­as.

Quoth Josselin:

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,

On 2007-10-30 18:41:01 +0100, Sebastian Probst E.
[email protected] said:

Maybe it is not the smartest way to solve the problem, but it is a

I have a group of lines (used in Googlemaps display) based on 2 arrays :
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…

On 10/30/07, Josselin [email protected] wrote:

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

On Wed, 31 Oct 2007 01:50:08 +0900, Josselin [email protected]
wrote:

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

On 10/30/07, Martin DeMello [email protected] wrote:

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

On Wed, 31 Oct 2007 03:41:09 +0900, MenTaLguY [email protected] 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

Quoth MenTaLguY:

how could I replace it the dryest way possible ?

by combining ZL and DISTANCE into an associative list:

-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,

On Wed, 31 Oct 2007 04:08:38 +0900, Konrad M. [email protected]
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

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

On Wed, 31 Oct 2007 03:25:03 +0900, Josselin [email protected]
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

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

Ah, I just noticed a bug here in my code. This should be
.last, rather than .first, since the zoom level is the second
item in the pair.

-mental

On 2007-10-30 19:41:09 +0100, MenTaLguY [email protected] said:

how could I replace it the dryest way possible ?

by combining ZL and DISTANCE into an associative list:

-mental

thanks a lot… I wrote that in my Ruby Notebook ! I’ll keep it in
mind when coding… I learned Ruby (because of Rails…) on my personal
desk, I need to progress
what are the best books beside the basic ones I have… to improve
Ruby coding ?

joss

Quoth MenTaLguY:

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

The same goes for your email client. GUI clients will let you change the
font
to something nice. Console clients, you can change your console
emulator’s
font (unless you’re at a real console, in which case you’re SOL :D).

Regards,

On 2007-10-30 19:54:00 +0100, MenTaLguY [email protected] said:

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.
yes, wich is not the case with GoogleMaps ;-))
directly.

-mental

thanks very useful advice…it’s true that optimizing DB access
performances is my first objective,
I am trying then to look over some ‘re-du-plicated’ lines or big loops
to avoid lengthy source code (as you say clarity and maintainability…
in this particular case, maybe the 6 lines are better for clarity to
anybody looking at the code later…

joss

On 2007-10-30 19:27:46 +0100, Konrad M. [email protected] said:

zl =3D 10 if farthest_proposition.distance_to(origin) <=3D 15.0
=2E.)
13
HTH,
iD8DBQBHJ3egCHB0oCiR2cwRAtyEAKC/EPouK4xAEXIOlVIhmZLoGsyehACgu2gI
KvJhHwI/b6XDrR+iCCxh2YE=
=Ihh1
-----END PGP SIGNATURE-----

–nextPart1735617.YmkLPv5XtJ–

thanks a lot, I’ll test it in my perf bench against other ways
joss