Home     |     .Net Programming    |     cSharp Home    |     Sql Server Home    |     Javascript / Client Side Development     |     Ajax Programming

Ruby on Rails Development     |     Perl Programming     |     C Programming Language     |     C++ Programming     |     IT Jobs

Python Programming Language     |     Laptop Suggestions?    |     TCL Scripting     |     Fortran Programming     |     Scheme Programming Language


 
 
Cervo Technologies
The Right Source to Outsource

MS Dynamics CRM 3.0

Python Programming Language

Newbie help looping/reducing code


Hey all,

Can someone help me reduce this code?  It sure seems
like there ought to be a way to loop this or combine
things so that there is only 1 or 3 lines to this
instead of 6.  I've been scratching my head over this
for a while though I can't come up with anything.
Just as a note, I need even_odd_round left alone because
it is not always used.  I just included for clarity.

As always, thanks in advance,

Lance

T2B = even_odd_round(float(str(T2B)))  
VS  = even_odd_round(float(str(VS)))    
SS  = even_odd_round(float(str(SS)))    
sh.Cells(21,lastcol+1).Value = float(str(T2B))/100
sh.Cells(22,lastcol+1).Value = float(str(VS))/100
sh.Cells(23,lastcol+1).Value = float(str(SS))/100

def even_odd_round(num):
        if(round(num,2) + .5 == int(round(num,2)) + 1):
                if num > .5:
                     if(int(num) % 2):
                        num = round(num,2) + .1 #an odd number
                     else:
                        num = round(num,2) - .1 #an even number
                else:
                   num = 1
        rounded_num = int(round(num,0))
        return rounded_num

Lance Hoffmeyer <l@augustmail.com> writes:
> T2B = even_odd_round(float(str(T2B)))      
> VS  = even_odd_round(float(str(VS)))      
> SS  = even_odd_round(float(str(SS)))      
> sh.Cells(21,lastcol+1).Value = float(str(T2B))/100
> sh.Cells(22,lastcol+1).Value = float(str(VS))/100
> sh.Cells(23,lastcol+1).Value = float(str(SS))/100

First of all, I don't understand float(str(VS)) and so forth; if VS is
(say) an integer, you can say float(VS) directly.  Second, even_odd_round
is written in a way that it can accept either an int or a float.

So assuming you need to keep those variables around, I'd write the
first three lines of the above as:

   T2B = even_odd_round(T2B)
   VS = even_odd_round(VS)
   SS = even_odd_round(SS)

or you could get fancier and say

   T2B, VS, SS = map(even_odd_round, (T2B, VS, SS))

Then you could write the next three lines as a loop:

   for i,v in ((21, T2B), (22, VS), (23,SS)):
     sh.Cells(i, lastcol+1) = float(v) / 100.0

Lance Hoffmeyer <l@augustmail.com> writes:
> def even_odd_round(num):
>    if(round(num,2) + .5 == int(round(num,2)) + 1):
>            if num > .5:
>                 if(int(num) % 2):
>                    num = round(num,2) + .1 #an odd number
>                 else:
>                    num = round(num,2) - .1 #an even number
>            else:
>               num = 1
>    rounded_num = int(round(num,0))
>    return rounded_num

I would also rewrite this function.  It's quite hard to figure out
what it's intended to do.  At minimum it should be carefully
documented.  I have the impression it's supposed to be something like
the IEEE rounding mode, that rounds floating point numbers to the
nearest integer, rounding to the even neighbor if the fractional
part (sometimes called the mantissa) is close to 0.5.

>    if(round(num,2) + .5 == int(round(num,2)) + 1):

The above is true if the mantissa is >= 0.495.  So you're going to
round 3.495 up to 4, even though it's actually closer to 3.  Is that
really what you want?  You're rounding based on a printed
representation rather than on the actual number.

>            if num > .5:

It looks like for display purposes you're trying to avoid displaying
positive numbers as zero if they're slightly below 0.5.  However, that
doesn't prevent the round-to-even behavior if the number is slightly
above 0.5.  So you get the anomaly that even_odd_round(0.499) = 1,
but even_odd_round(0.501) = 0.  My guess is that's not what you wanted
and that it's a bug.

>                 if(int(num) % 2):
>                    num = round(num,2) + .1 #an odd number
>                 else:
>                    num = round(num,2) - .1 #an even number

If the integer part is odd, round upward, else round downward, ok.
So basically you're going to round to the even neighbor if the
mantissa is close to 0.5, otherwise round to the nearest integer.

I notice also that when num is negative, your function rounds to
the odd neighbor (at least sometimes), differing from IEEE rounding.

I think it's clearer to just separate out the integer and fractional
parts and branch on the fractional part directly.  I'll ignore the
issue with negative inputs since I'm guessing you only care about
positive ones:

def even_odd_round(num):
   assert num >= 0

   # separate the number's integer and fractional parts
   intpart, fracpart = int(num), num % 1.0

   # decide what to do based on the fractional part
   if fracpart < 0.495:
      return intpart                    # round downward
   elif fracpart > 0.505 or intpart==0:
      return intpart+1                  # round upward
   else:
      return intpart + intpart % 2      # round to even

In article <7x1wkl8xb7.@ruckus.brouhaha.com>,
Paul Rubin  <http://phr@NOSPAM.invalid> wrote:
>Lance Hoffmeyer <l@augustmail.com> writes:
>> def even_odd_round(num):
>>        if(round(num,2) + .5 == int(round(num,2)) + 1):
>>                if num > .5:
>>                     if(int(num) % 2):
>>                        num = round(num,2) + .1 #an odd number
>>                     else:
>>                        num = round(num,2) - .1 #an even number
>>                else:
>>                   num = 1
>>        rounded_num = int(round(num,0))
>>        return rounded_num

>I would also rewrite this function.  It's quite hard to figure out
>what it's intended to do.  At minimum it should be carefully

                        .
                        .
                        .

>def even_odd_round(num):
>   assert num >= 0

>   # separate the number's integer and fractional parts
>   intpart, fracpart = int(num), num % 1.0

>   # decide what to do based on the fractional part
>   if fracpart < 0.495:
>      return intpart                    # round downward
>   elif fracpart > 0.505 or intpart==0:
>      return intpart+1                  # round upward
>   else:
>      return intpart + intpart % 2      # round to even

I have even less idea than Paul what the true intent of even_odd_round()
is.  I offer, though, the general observation that it's VERY often possible
to do what people want in this sort of regard with a simple use of
formatting--something like

    "%.3f" % num

If one comes from C or Java, it can be hard to appreciate immediately how
useful this is.  It's also likely to be more robust than anything naively
written "by hand".

Add to del.icio.us | Digg this | Stumble it | Powered by Megasolutions Inc