While Statement

Discussion in 'Python' started by Joel Ross, May 22, 2009.

  1. Joel Ross

    Joel Ross Guest

    Hi all,

    I have this piece of code

    class progess():

    def __init__(self, number, char):

    total = number
    percentage = number
    while percentage > 0 :
    percentage = int(number/total*100)
    number-=1
    char+="*"
    print char

    progess(999, "*")

    Just wondering if anyone has any ideas on way the percentage var gets
    set to the value 0 after the first loop.

    Any feed back would be appreciated.

    Regards

    jross
     
    Joel Ross, May 22, 2009
    #1
    1. Advertising

  2. On Fri, May 22, 2009 at 2:47 PM, Joel Ross <> wrote:
    > Hi all,
    >
    > I have this piece of code
    >
    > class progess():
    >
    >    def __init__(self, number,  char):
    >
    >        total = number
    >        percentage = number
    >        while percentage > 0 :
    >            percentage = int(number/total*100)
    >            number-=1
    >            char+="*"
    >            print char
    >
    > progess(999,  "*")
    >
    > Just wondering if anyone has any ideas on way the percentage var gets set to
    > the value 0 after the first loop.
    >


    Put in a

    from __future__ import division

    statement at the start. You can experiment in the python shell if you'd like.

    >>> 2/3

    0
    >>> from __future__ import division
    >>> 2/3

    0.66666666666666663
    >>>


    This kind of division is the default in Python 3.

    --
    kushal
     
    Kushal Kumaran, May 22, 2009
    #2
    1. Advertising

  3. Joel Ross

    Andre Engels Guest

    On Fri, May 22, 2009 at 11:17 AM, Joel Ross <> wrote:
    > Hi all,
    >
    > I have this piece of code
    >
    > class progess():
    >
    >    def __init__(self, number,  char):
    >
    >        total = number
    >        percentage = number
    >        while percentage > 0 :
    >            percentage = int(number/total*100)
    >            number-=1
    >            char+="*"
    >            print char
    >
    > progess(999,  "*")
    >
    > Just wondering if anyone has any ideas on way the percentage var gets set to
    > the value 0 after the first loop.
    >
    > Any feed back would be appreciated.


    In Python 2.6 and lower, division of two integers gives an integer,
    being the result without rest of division with rest:

    >>> 4/3

    1
    >>> 5/3

    1
    >>> 6/3

    2
    >>>


    In your example, the second run has number = 998, total = 999. 998/999
    is evaluated to be zero.

    There are two ways to change this:
    1. Ensure that at least one of the things you are using in the
    division is a float. You could for example replace "total = number" by
    "total = float(number)" or "number/total*100" by
    "float(number)/total*100" or by "(number*100.0)/total".
    2. Use Python 3 behaviour here, which is done by putting the import
    "from __future__ import division" in your code.


    --
    André Engels,
     
    Andre Engels, May 22, 2009
    #3
  4. Joel Ross

    Joel Ross Guest

    Joel Ross wrote:
    > Hi all,
    >
    > I have this piece of code
    >
    > class progess():
    >
    > def __init__(self, number, char):
    >
    > total = number
    > percentage = number
    > while percentage > 0 :
    > percentage = int(number/total*100)
    > number-=1
    > char+="*"
    > print char
    >
    > progess(999, "*")
    >
    > Just wondering if anyone has any ideas on way the percentage var gets
    > set to the value 0 after the first loop.
    >
    > Any feed back would be appreciated.
    >
    > Regards
    >
    > jross


    Thanks for the quick response and the heads up. Makes sense

    Thank you. You guys helped me out alot:)
     
    Joel Ross, May 22, 2009
    #4
  5. Joel Ross

    Joel Ross Guest

    Andre Engels wrote:
    > On Fri, May 22, 2009 at 11:17 AM, Joel Ross <> wrote:
    >> Hi all,
    >>
    >> I have this piece of code
    >>
    >> class progess():
    >>
    >> def __init__(self, number, char):
    >>
    >> total = number
    >> percentage = number
    >> while percentage > 0 :
    >> percentage = int(number/total*100)
    >> number-=1
    >> char+="*"
    >> print char
    >>
    >> progess(999, "*")
    >>
    >> Just wondering if anyone has any ideas on way the percentage var gets set to
    >> the value 0 after the first loop.
    >>
    >> Any feed back would be appreciated.

    >
    > In Python 2.6 and lower, division of two integers gives an integer,
    > being the result without rest of division with rest:
    >
    >>>> 4/3

    > 1
    >>>> 5/3

    > 1
    >>>> 6/3

    > 2
    >
    > In your example, the second run has number = 998, total = 999. 998/999
    > is evaluated to be zero.
    >
    > There are two ways to change this:
    > 1. Ensure that at least one of the things you are using in the
    > division is a float. You could for example replace "total = number" by
    > "total = float(number)" or "number/total*100" by
    > "float(number)/total*100" or by "(number*100.0)/total".
    > 2. Use Python 3 behaviour here, which is done by putting the import
    > "from __future__ import division" in your code.
    >
    >


    Im using 2.6 python and when running this

    class progess():

    def __init__(self, number, total, char):

    percentage = float(number/total*100)
    percentage = int(round(percentage))
    char = char * percentage
    print char

    progess(100, 999, "*")

    the "percentage = float(number/total*100)" always equals 0.0
    any ideas way this would be?
     
    Joel Ross, May 22, 2009
    #5
  6. Joel Ross

    Andre Engels Guest

    On Fri, May 22, 2009 at 12:35 PM, Joel Ross <> wrote:

    > Im using 2.6 python and when running this
    >
    > class progess():
    >
    >    def __init__(self, number, total,  char):
    >
    >        percentage = float(number/total*100)
    >        percentage = int(round(percentage))
    >        char = char * percentage
    >        print char
    >
    > progess(100, 999,  "*")
    >
    > the "percentage = float(number/total*100)" always equals 0.0
    > any ideas way this would be?


    You have to make the conversion of integer to float before the
    division. What you are calculating now is (take number = 998, total =
    999)

    number/total = 998/999 = 0
    number/total*100 = 0*100 = 0
    float(number/total*100) = float(0) = 0.0

    Change "float(number/total*100)" to "float(number)/total*100" and it
    should work:

    float(number) = float(998) = 998.0
    float(number)/total = 998.0/999 = 0.99899899899899902
    float(number)/total*100 = 0.99899899899899902 * 100 = 99.899899899899902



    --
    André Engels,
     
    Andre Engels, May 22, 2009
    #6
  7. Joel Ross

    Joel Ross Guest

    Andre Engels wrote:
    > On Fri, May 22, 2009 at 12:35 PM, Joel Ross <> wrote:
    >
    >> Im using 2.6 python and when running this
    >>
    >> class progess():
    >>
    >> def __init__(self, number, total, char):
    >>
    >> percentage = float(number/total*100)
    >> percentage = int(round(percentage))
    >> char = char * percentage
    >> print char
    >>
    >> progess(100, 999, "*")
    >>
    >> the "percentage = float(number/total*100)" always equals 0.0
    >> any ideas way this would be?

    >
    > You have to make the conversion of integer to float before the
    > division. What you are calculating now is (take number = 998, total =
    > 999)
    >
    > number/total = 998/999 = 0
    > number/total*100 = 0*100 = 0
    > float(number/total*100) = float(0) = 0.0
    >
    > Change "float(number/total*100)" to "float(number)/total*100" and it
    > should work:
    >
    > float(number) = float(998) = 998.0
    > float(number)/total = 998.0/999 = 0.99899899899899902
    > float(number)/total*100 = 0.99899899899899902 * 100 = 99.899899899899902
    >
    >
    >

    changed it to "float(number)/total*100" and it worked thanks for all
    your help appreciated

    thanks again
     
    Joel Ross, May 22, 2009
    #7
  8. Joel Ross

    Tim Wintle Guest

    On Fri, 2009-05-22 at 13:19 +0200, Andre Engels wrote:
    > number/total = 998/999 = 0
    > number/total*100 = 0*100 = 0
    > float(number/total*100) = float(0) = 0.0
    >
    > Change "float(number/total*100)" to "float(number)/total*100" and it
    > should work:


    I'd use:

    (number * 100.)/total

    - works because
    <int> * <float> => <float>

    It's a minor thing, but it's much faster to cast implicitly as you miss
    the python function call overhead - it's no extra work to write, and for
    numerical things it can really speed things up.

    >>> a = timeit.Timer("float(200)/5*100")
    >>> b = timeit.Timer("(200*100.)/5")
    >>> a.timeit(10000000)

    12.282480955123901
    >>> b.timeit(10000000)

    3.6434230804443359

    Tim W
     
    Tim Wintle, May 22, 2009
    #8
  9. Joel Ross

    Dave Angel Guest

    Tim Wintle wrote:
    > On Fri, 2009-05-22 at 13:19 +0200, Andre Engels wrote:
    >
    >> number/total = 998/999 = 0
    >> number/total*100 = 0*100 = 0
    >> float(number/total*100) = float(0) = 0.0
    >>
    >> Change "float(number/total*100)" to "float(number)/total*100" and it
    >> should work:
    >>

    >
    > I'd use:
    >
    > (number * 100.)/total
    >
    > - works because
    > <int> * <float> => <float>
    >
    > It's a minor thing, but it's much faster to cast implicitly as you miss
    > the python function call overhead - it's no extra work to write, and for
    > numerical things it can really speed things up.
    >
    >
    >>>> a = timeit.Timer("float(200)/5*100")
    >>>> b = timeit.Timer("(200*100.)/5")
    >>>> a.timeit(10000000)
    >>>>

    > 12.282480955123901
    >
    >>>> b.timeit(10000000)
    >>>>

    > 3.6434230804443359
    >
    > Tim W
    >
    >
    >
    >

    It's the old-timer in me, but I'd avoid the float entirely. You start
    with ints, and you want to end with ints. So simply do the multiply
    first, then the divide.

    number * 100/total

    will get the same answer.
     
    Dave Angel, May 22, 2009
    #9
  10. Joel Ross

    Joel Ross Guest

    Dave Angel wrote:
    >
    >
    > Tim Wintle wrote:
    >> On Fri, 2009-05-22 at 13:19 +0200, Andre Engels wrote:
    >>
    >>> number/total = 998/999 = 0
    >>> number/total*100 = 0*100 = 0
    >>> float(number/total*100) = float(0) = 0.0
    >>>
    >>> Change "float(number/total*100)" to "float(number)/total*100" and it
    >>> should work:
    >>>

    >>
    >> I'd use:
    >>
    >> (number * 100.)/total
    >>
    >> - works because
    >> <int> * <float> => <float>
    >> It's a minor thing, but it's much faster to cast implicitly as you miss
    >> the python function call overhead - it's no extra work to write, and for
    >> numerical things it can really speed things up.
    >>
    >>
    >>>>> a = timeit.Timer("float(200)/5*100")
    >>>>> b = timeit.Timer("(200*100.)/5")
    >>>>> a.timeit(10000000)
    >>>>>

    >> 12.282480955123901
    >>
    >>>>> b.timeit(10000000)
    >>>>>

    >> 3.6434230804443359
    >>
    >> Tim W
    >>
    >>
    >>
    >>

    > It's the old-timer in me, but I'd avoid the float entirely. You start
    > with ints, and you want to end with ints. So simply do the multiply
    > first, then the divide.
    >
    > number * 100/total
    >
    > will get the same answer.
    >


    Cheers thanks for the support. if it works faster I'll definitely do it
     
    Joel Ross, May 22, 2009
    #10
  11. Joel Ross

    Tim Wintle Guest

    On Fri, 2009-05-22 at 09:59 -0400, Dave Angel wrote:
    >
    > Tim Wintle wrote:
    > > On Fri, 2009-05-22 at 13:19 +0200, Andre Engels wrote:


    > >> Change "float(number/total*100)" to "float(number)/total*100" and it
    > >> should work:
    > >>

    > >
    > > I'd use:
    > >
    > > (number * 100.)/total
    > >
    > > - works because
    > > <int> * <float> => <float>


    > It's the old-timer in me, but I'd avoid the float entirely. You start
    > with ints, and you want to end with ints. So simply do the multiply
    > first, then the divide.
    >
    > number * 100/total


    Agreed, to be honest I'd not fully read the original post and didn't
    realise everything was an int.




    >
    > will get the same answer.
    >
     
    Tim Wintle, May 22, 2009
    #11
  12. On Fri, 2009-05-22 at 09:59 -0400, Dave Angel wrote:
    >
    > Tim Wintle wrote:
    > > On Fri, 2009-05-22 at 13:19 +0200, Andre Engels wrote:
    > >
    > >> number/total = 998/999 = 0
    > >> number/total*100 = 0*100 = 0
    > >> float(number/total*100) = float(0) = 0.0
    > >>
    > >> Change "float(number/total*100)" to "float(number)/total*100" and it
    > >> should work:
    > >>

    > >
    > > I'd use:
    > >
    > > (number * 100.)/total
    > >
    > > - works because
    > > <int> * <float> => <float>
    > >
    > > It's a minor thing, but it's much faster to cast implicitly as you miss
    > > the python function call overhead - it's no extra work to write, and for
    > > numerical things it can really speed things up.
    > >
    > >
    > >>>> a = timeit.Timer("float(200)/5*100")
    > >>>> b = timeit.Timer("(200*100.)/5")
    > >>>> a.timeit(10000000)
    > >>>>

    > > 12.282480955123901
    > >
    > >>>> b.timeit(10000000)
    > >>>>

    > > 3.6434230804443359
    > >
    > > Tim W
    > >
    > >
    > >
    > >

    > It's the old-timer in me, but I'd avoid the float entirely. You start
    > with ints, and you want to end with ints. So simply do the multiply
    > first, then the divide.
    >
    > number * 100/total
    >
    > will get the same answer.
    >


    Also, to get the same behavior (faster integer division) in python 3 or
    when using `from __future__ import division`, use the // division
    operator instead of /.

    In fact, a little experimentation shows that you get the speedup even
    when using python 2.6 with old-style division. Probably because python
    doesn't have to check the types of its arguments before deciding to do
    integer division.

    >>> a = timeit.Timer("(200 * 100.)/5")
    >>> b = timeit.Timer("(200 * 100)/5")
    >>> c = timeit.Timer("(200 * 100)//5")
    >>> d = timeit.Timer("(200 * 100.0)//5")
    >>> for each in a, b, c, d:

    .... each.timeit(22222222)
    ....
    2.3681092262268066
    2.417525053024292
    0.81031703948974609
    0.81548619270324707


    Cheers,
    Cliff
     
    J. Cliff Dyer, May 22, 2009
    #12
  13. On Fri, 22 May 2009 21:33:05 +1000
    Joel Ross <> wrote:

    > changed it to "float(number)/total*100" and it worked thanks for all
    > your help appreciated


    I believe operator.truediv function also deserves a mention here, since
    line "op.truediv(number, total) * 100" somehow seem to make more sense
    to me than an explicit conversion.
    There's also "op.itruediv" for "number /= float(total) * 100" case.

    http://docs.python.org/dev/library/operator.html

    --
    Mike Kazantsev // fraggod.net

    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v2.0.11 (GNU/Linux)

    iEYEARECAAYFAkoXeGEACgkQASbOZpzyXnEzqgCgnVBO2PueqWqZOARjsBZaj2M0
    oT0An2q9SfJ1OF4NbBCSsBPQpTtJdYyh
    =0gkd
    -----END PGP SIGNATURE-----
     
    Mike Kazantsev, May 23, 2009
    #13
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    3
    Views:
    823
  2. Jay McGavren
    Replies:
    11
    Views:
    1,169
    Alan Krueger
    Jan 16, 2006
  3. tedsuzman
    Replies:
    2
    Views:
    7,146
    Michel Claveau, résurectionné d'outre-bombe inform
    Jul 21, 2004
  4. Ted
    Replies:
    1
    Views:
    483
    Duncan Booth
    Jul 22, 2004
  5. Replies:
    21
    Views:
    1,078
    Giannis Papadopoulos
    Aug 2, 2005
Loading...

Share This Page