a *= b not equivalent to a = a*b

2016-08-25 Thread mlz
I've been playing with the binomial function, and found that in the below code, 
rs *= x does not behave the same way as rs = rs * x. When I set FAIL to True, I 
get a different result.  Both results are below.

I had read that the two were equivalent. What am I missing?

thanks,
  -= miles =-


#!/usr/bin/python2

import sys
FAIL= True if len(sys.argv)>1 else False

def bin(n,k):
rs=1
k=min(k,n-k)

for i in range(1,k+1):
if FAIL: rs *= (n-(i-1))/i  # these should be the same, 
else: rs = rs * (n-(i-1))/i  #  but apparently are not
return rs


for n in range(10):
for k in range(n+1):
print bin(n,k),
print''
   
--- output -


$ pascal2
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
1 9 36 84 126 126 84 36 9 1

$ pascal2 fail
1
1 1
1 2 1
1 3 3 1
1 4 4 4 1
1 5 10 10 5 1
1 6 12 12 12 6 1
1 7 21 21 21 21 7 1
1 8 24 48 48 48 24 8 1
1 9 36 72 72 72 72 36 9 1




-- 
https://mail.python.org/mailman/listinfo/python-list


Re: a *= b not equivalent to a = a*b

2016-08-26 Thread mlz

Aha. That's interesting.


On Friday, August 26, 2016 at 2:11:32 AM UTC-7, Peter Otten wrote:
> mlz wrote:
> 
> > Yes, I just worked that out. It's the integer math that's the problem.
> > 
> > I guess this has been fixed in python 3, but unfortunately it seems that
> > most people are still using python 2.
> 
> Note that you can get Python 3's default behaviour in Python 2 with
> 
> from __future__ import division
> 
> at the beginning of the module.
> 
> >>> 2/3
> 0
> >>> from __future__ import division
> >>> 2/3
> 0.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: a *= b not equivalent to a = a*b

2016-08-26 Thread mlz
Partly it's the layout, but mathematically speaking the two should be equal.

(a*b)/c should equal a*(b/c)

The fact that they're not is surprising, because python 2 so seamlessly 
supports big integers in a mathematically correct way.

I consider such surprising behavior to be abstraction leak, which is probably 
why it has been fixed in python 3.

  -= m =-


On Friday, August 26, 2016 at 12:54:02 AM UTC-7, Erik wrote:
> On 26/08/16 08:14, mlz wrote:
> >
> > I was being facetious, but behind it is a serious point. Neither the APL 
> > nor the J languages use precedence even though their inventor, Ken Iverson, 
> > was a mathematician.
> >
> > That was to support functional programming dating back to the 1970's.
> 
> Precedence is not the issue here anyway. Both '*' and '/' have the same 
> precedence. The two operations in your expressions have to be evaluated 
> in SOME order - either left-to-right or right-to-left.
> 
> 
> The issue is twofold:
> 
> Firstly, the compound assignments will always evaluate their RHS before 
> performing the assignment - this is not the same as operator precedence 
> - they have to, else what does Python pass to the function that knows 
> what the compound assignment means for that type (e.g. sequences may be 
> extended for '*=')? So for compound assignments there is always 
> effectively an implicit set of parentheses around the RHS compared to 
> the expression without the assignment operator (if you think of the 
> compound assignment as being a _part_ of the overall expression).
> 
> Secondly, the way you have chosen to layout your code has fooled your 
> brain into thinking that the division is performed before the 
> multiplication. Python doesn't care that you jammed the sub-expression 
> together with no whitespace ;)
> 
> E.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: a *= b not equivalent to a = a*b

2016-08-26 Thread mlz
It's true that a*(b/c) yields fractions which would probably accrue accuracy 
errors depending on how those values are implemented. For example, it is 
possible to represent 1/3 internally as two numbers, numerator and denominator, 
thus avoiding the repeating decimal (or binimal, or whatever it's called). I 
believe there are languages that preserve exact accuracy in this way for 
rational fractions. I don't know if Python is one of them.

On the other hand, (a*b)/c is safer since in this case (for the binomial 
coefficient) it always yields an integer.

  -= m =-



On Friday, August 26, 2016 at 1:42:31 AM UTC-7, Christian Gollwitzer wrote:
> Am 26.08.16 um 09:53 schrieb Erik:
> > On 26/08/16 08:44, mlz wrote:
> >> Here's the key:
> >>
> >> $ python2
> >> Python 2.7.10 ...
> >>>>> 1/2
> >> 0
> >>>>>
> >>
> >> $ python
> >> Python 3.5.1 ...
> >>>>> 1/2
> >> 0.5
> >>>>> 1//2
> >> 0
> >>>>>
> >>
> >> I read about this awhile ago, but it's not until it bites you that you
> >> remember fully.
> >
> > How is this related to your question? The example explicitly says Python
> > 2 and doesn't use the '//' operator.
> >
> 
> It's related by the fact that a*b/c performs integer division (intended 
> by the OP) which gives a different result than a*(b/c) (unintended by 
> the OP). Floating point (as in Python 3) *also* may give a different 
> result, but the deviation from the "true", i.e. mathematical value, is 
> far less than with integer arithmetics.
> 
>   Christian

-- 
https://mail.python.org/mailman/listinfo/python-list