Floating point calculation problem

2013-02-02 Thread Schizoid Man
I have a program that performs some calculations that runs perfectly on 
Python 2.7.3. However, when I try to execute it on Python 3.3.0 I get the 
following error:

   numer = math.log(s)
TypeError: a float is required

The quantity s is input with the following line: s = input("Enter s:   ")

To get rid of the compile error, I can cast this as a float: s = 
float(input("Enter s:   "))


However, then the result returned by the method is wrong. Why does this 
error occur in version 3.3.0 but not in 2.7.3? Why is the result incorrect 
when s is cast as a float (the casting is not required in 2.7.3)? How is 
Python dynamically typed if I need to cast (in version 3.3.0 at least) to 
get rid of the compile error?


Thanks in advance.

PS - I'm a Python newbie. 


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


Re: Floating point calculation problem

2013-02-02 Thread Schizoid Man
"Chris Angelico"  wrote in message 
news:mailman.1289.1359801291.2939.python-l...@python.org...
On Sat, Feb 2, 2013 at 9:27 PM, Schizoid Man  
wrote:

The quantity s is input with the following line: s = input("Enter s:   ")

To get rid of the compile error, I can cast this as a float: s =
float(input("Enter s:   "))

However, then the result returned by the method is wrong. Why does this
error occur in version 3.3.0 but not in 2.7.3? Why is the result 
incorrect

when s is cast as a float (the casting is not required in 2.7.3)? How is
Python dynamically typed if I need to cast (in version 3.3.0 at least) to
get rid of the compile error?


Did you use input() or raw_input() in 2.7.3? If the former, you were
actually doing this:

s = eval(input("Enter s:  "))

That's extremely dangerous and inadvisable, so it's better to go with
3.3 or the raw_input function.


Thanks for the reply. You're right - even in 2.7.3 if I toggle between 
float(input(x)) and input(x), the result of the calculation changes. What 
does the float cast do exactly?



Passing it through float() is, most likely, the right way to do this.
But what do you mean by "the result... is wrong"? That's the bit to
look into.


Scratch that, I'm not sure which result is right now, so need to look at the 
full calculations in details. What would be the difference between 
raw_input() and float(input())?


Thanks again. 


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


Re: Floating point calculation problem

2013-02-02 Thread Schizoid Man

raw_input() takes a line from the keyboard (handwave) and returns it
as a string.

input() in 2.X takes a line from the keyboard and evaluates it as a
Python expression.

float() takes a string, float, int, etc, and returns the
nearest-equivalent floating point value.

What's the input you're giving to it?


Something simple like 3.0. 

PS - I'm new to Python, hence the newbie questions. 
--

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


Re: Floating point calculation problem

2013-02-02 Thread Schizoid Man

If your input has no decimal point in it, eval (or input) will return
an integer, not a float. Other than that, I can't see any obvious
reason for there to be a difference. Can you put together a simple
script that demonstrates the problem and post it, along with the exact
input that you're giving it, and the different outputs?


Understood. I'm trying to learn Python by porting an ODE solver I wrote over 
from C#, so what I'll do is break down the routine and append a small code 
snippet highlighting the difference.


I know this is probably redundant but Python 2.7.3 is running on a Mac and 
3.3.0 on a PC, so it's not exactly an apples-v-apples comparison. 


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


Re: Floating point calculation problem

2013-02-02 Thread Schizoid Man
Highly unlikely. I'd say impossible, unless you type a different value for 
x

of course. By the time the input() function returns, the result is already
a float. Wrapping it in float() again cannot possibly change the value. If
you have found a value that does change, please tell us what it is.

The only examples I can think of that will behave that way involve NANs 
and

INFs. If you don't know what they are, don't worry about it, and forget I
mentioned them. For regular floating point values, I can't think of any
possible way that float(input(x)) and input(x) could give different
results.



No, the calculation returns in neither NaN or Inf at any point.


float(x) converts x into a float.

- if x is already a float, it leaves it unchanged;

- if x is a string, it converts it to the nearest possible float;

- if x is some other numeric value (e.g. int, Decimal or Fraction,
 but not complex) it converts it to the nearest possible float.


float(input()) is a waste of time. The dangerous part happens in the call 
to

input(): a malicious user could type a Python command, and run arbitrary
code; or they could type something like "10**100**100" and lock up your
computer. Calling float *after* the call to input doesn't do anything.

In Python 3.x, raw_input is gone, but float(input()) is safe -- it is
exactly equivalent to float(raw_input()) in Python 2.x.

One other difference between Python 2.7 and 3.3 is that they sometimes
display floats slightly differently. Sometimes 3.3 will show more decimal
places:


Thanks for that, I'll post the problematic code here shortly. 


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


Re: Floating point calculation problem

2013-02-02 Thread Schizoid Man

Ah, there may well be something in that. Definitely post the code and
outputs; chances are someone'll spot the difference.


Ok, I *think* I found the source of the difference:

This is the base code that runs fine in v 3.3.0 (the output is correct):

def Numer(s, k):
   return math.log(s / k)
s = float(input("Enter s:   "))
k = float(input("Enter k:   "))
print("Result: ", Numer(s, k))

For the v2.7 version, the only difference is the input lines:
s = input("Enter s:   ")
k = input("Enter k:   ")

So for values of s=60 and k=50, the first code returns 0.1823215567939546 
(on the PC), whereas the second returns 0.0 (on the Mac). This this 
expression is evaluated in the numerator, it never returns a divide by zero 
error, and the result of 0 is treated as legitimate.


However, if I cast the v2.7 inputs as float() then it does indeed return the 
right result. But what threw me was that no cast didn't result in a runtime 
error in 2.7, but did in 3.3.


Also, if the cast is necessary, then now exactly does the dynamic typing 
work?


Thanks. 


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


Re: Floating point calculation problem

2013-02-02 Thread Schizoid Man
"Schizoid Man"  wrote in message 
news:kejcfi$s70$1...@dont-email.me...


So for values of s=60 and k=50, the first code returns 0.1823215567939546 
(on the PC), whereas the second returns 0.0 (on the Mac). This this 
expression is evaluated in the numerator, it never returns a divide by 
zero error, and the result of 0 is treated as legitimate.


D'oh! That's the error right there. My inputs are 60 and 50, not 60.0 and 
50.0. I am a dunderhead.


Apologies for wasting your time.


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


Confusing math problem

2013-02-21 Thread Schizoid Man

Hi there,

I run the following code in Python 3.3.0 (on a Windows 7 machine) and Python 
2.7.3 on a Mac and I get two different results:


result1 = []
result2 = []
for a in range(2,101):
   for b in range(2,101):
   result1.append(math.pow(a,b))
   result2.append(a**b)
result1 = list(set(result1))
result2 = list(set(result2))
print (len(result1))
print (len(result2))

On the Windows box, I get 9183 for on both lines. However, on the Mac I get 
9220 and 9183. Why this difference? Is there some sort of precision subtlety 
I'm missing between ** and math.pow()?


Thank you. 


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


Re: Confusing math problem

2013-02-21 Thread Schizoid Man



"Dave Angel"  wrote in message

On 02/21/2013 02:33 PM, Schizoid Man wrote:
However, there is an important inaccuracy in math.pow, because it uses 
floats to do the work.  If you have very large integers, that means some 
of them won't be correct.  The following are some examples for 2.7.3 on 
Linux:


 a  b  math.pow(a,b)   a**b
 3 34 1.66771816997e+16 16677181699666569
 3 35 5.0031545099e+16 50031545098999707
...
 5 23 1.19209289551e+16 11920928955078125

The built-in pow, on the other hand, seems to get identical answers for 
all these cases.  So use pow() instead of math.pow()


I see. I thought using the ** was shorthand for math.pow() and didn't think 
that one would be integer operations and the other floats. I'm performing 
some large integer arithmetic operations. I would normally do this my 
writing my own multiplication class and storing results as strings, but a 
friend suggested that I look at Python.


I ran this one example and was quite surprised at the difference, since 9183 
is the correct answer.



One other test:

diff = set(map(int, result1)).symmetric_difference(set(result2))
if diff:
print diff
print len(diff)

shows me a diff set of 15656 members.  One such member:

1355252715606880542509316001087427139282226562500L

Notice how using floats truncated lots of the digits in the value?


I'm running this test now, but the Mac's fan has kicked in (it's a slightly 
older machine) so might it let run through the night.


I appreciate the help.


--
DaveA 


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


Re: Confusing math problem

2013-02-21 Thread Schizoid Man

"Chris Angelico"  wrote in




First, are you aware that ** will return int (or sometimes long on
2.7.3), while math.pow() will return a float? That may tell you why
you're seeing differences. That said, though, I wasn't able to
replicate your result using 2.7.3 and 3.3.0 both on Windows - always
9183, indicating 618 of the powers are considered equal. But in
theory, at least, what you're seeing is that 37 of them compare
different in floating point on your Mac build. Something to consider:

print(set(result1)-set(result2))


No, I was aware to be honest. I thought ** was just short hand for 
math.pow(). Since ** is the integer operation, I suppose ^ doesn't work as 
an exponent function in Python?


I compared the difference and got a large blob of numbers. To make a proper 
comparison I'll need to compare the base and exponent for which the numbers 
are different rather than the numbers themselves. I'm following Dave's 
suggestion of determining the symmetric difference of the sets.


Thanks for the help. 


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


Re: Confusing math problem

2013-02-21 Thread Schizoid Man

"Dave Angel"  wrote


One other test:

diff = set(map(int, result1)).symmetric_difference(set(result2))
if diff:
print diff
print len(diff)

shows me a diff set of 15656 members.  One such member:

1355252715606880542509316001087427139282226562500L


These are the results I got for len(diff): Windows machines: 15656, Mac: 
15693. Someone mentioned something about processor algorithms on this thread 
and I do have a x86 Mac, so in terms of processors it's a like-for-like 
comparison.


I have a follow-up question: are ** and pow() identical? 


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


Re: Confusing math problem

2013-02-21 Thread Schizoid Man



"Oscar Benjamin"  wrote in


Then you want operator.pow:


import operator
operator.pow(3, 2)

9

math.pow is basically the (double)pow(double, double) function from
the underlying C library. operator.pow(a, b) is precisely the same as
a**b.


So how is operator.pow() different from just pow()?


There's no need to use strings if you're working with integers in
Python. The results with int (not float) will be exact and will not
overflow since Python's ints have unlimited range (unless your machine
runs out of memory but that only happens with *really* big integers).


Yes, that's the idea. I haven't really used Python before, so was just 
kicking the tyres a bit and got some odd results. This forum has been great 
though.



If you want to do computations with non-integers and high precision,
take a look at the decimal and fractions modules.
http://docs.python.org/2/library/decimal.html
http://docs.python.org/2/library/fractions.html

There is also a good third party library, sympy, for more complicated
exact algebra:
http://sympy.org/en/index.html


Thanks a lot for the references, I'll definitely check them out. 


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


Beginner's assignment question

2008-03-01 Thread Schizoid Man
As in variable assignment, not homework assignment! :)

I understand the first line but not the second of the following code:

a, b = 0, 1
a, b = b, a + b

In the first line a is assigned 0 and b is assigned 1 simultaneously.

However what is the sequence of operation in the second statement? I;m 
confused due to the inter-dependence of the variables.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Beginner's assignment question

2008-03-02 Thread Schizoid Man
Lorenzo Gatti wrote:
> On Mar 1, 3:39 pm, Schizoid Man <[EMAIL PROTECTED]> wrote:
>> As in variable assignment, not homework assignment! :)
>>
>> I understand the first line but not the second of the following code:
>>
>> a, b = 0, 1
>> a, b = b, a + b
>>
>> In the first line a is assigned 0 and b is assigned 1 simultaneously.
>>
>> However what is the sequence of operation in the second statement? I;m
>> confused due to the inter-dependence of the variables.
> 
> The expressions of the right of the assignment operator are evaluated
> before assigning any new values, to the destinations on the left side
> of the assignment operator.
> So substitutig the old values of a and b the second assignment means
> 
> a, b = 0, 0 + 1
> 
> Simplifying the Python Reference Manual ("6.3 Assignment Statements")
> a little :
> 
> assignment_stmt ::= target_list "="+ expression_list
> 
> An assignment statement evaluates the expression list (remember that
> this can be a single expression or a comma-separated list, the latter
> yielding a tuple) and assigns the single resulting object to each of
> the target lists, from left to right.
> 
> [...]
> 
> WARNING: Although the definition of assignment implies that overlaps
> between the left-hand side and the right-hand side are `safe' (for
> example "a, b = b, a" swaps two variables), overlaps within the
> collection of assigned-to variables are not safe! For instance, the
> following program prints "[0, 2]":
> 
> x = [0, 1]
> i = 0
> i, x[i] = 1, 2
> print x
> 
> Lorenzo Gatti

Thank you for the explanation. I guess my question can be simplified as:

First step: a, b = 0, 1
No problem here as a and b are assigned values.

Second step: a, b = b, a + b

Now my question is does b become a + b after a becomes 1 or while a 
stays at 0?

As the assignment occurs simultaneously I suppose the answer is while a 
stays at 0.

Thank you.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Beginner's assignment question

2008-03-02 Thread Schizoid Man
Gabriel Genellina wrote:
> En Sun, 02 Mar 2008 08:25:49 -0200, Schizoid Man <[EMAIL PROTECTED]> escribi�:
> 
>> Lorenzo Gatti wrote:
>>> On Mar 1, 3:39 pm, Schizoid Man <[EMAIL PROTECTED]> wrote:
>>>> As in variable assignment, not homework assignment! :)
>>>>
>>>> I understand the first line but not the second of the following code:
>>>>
>>>> a, b = 0, 1
>>>> a, b = b, a + b
>>>>
>>>> In the first line a is assigned 0 and b is assigned 1 simultaneously.
>>>>
>>>> However what is the sequence of operation in the second statement? I;m
>>>> confused due to the inter-dependence of the variables.
>>>
>>> The expressions of the right of the assignment operator are evaluated
>>> before assigning any new values, to the destinations on the left side
>>> of the assignment operator.
>>> So substitutig the old values of a and b the second assignment means
>>>
>>> a, b = 0, 0 + 1
>>>
>>> Simplifying the Python Reference Manual ("6.3 Assignment Statements")
>>> a little :
>>>
>>> assignment_stmt ::= target_list "="+ expression_list
>>>
>>> An assignment statement evaluates the expression list (remember that
>>> this can be a single expression or a comma-separated list, the latter
>>> yielding a tuple) and assigns the single resulting object to each of
>>> the target lists, from left to right.
>>>
>>> [...]
>>>
>>> WARNING: Although the definition of assignment implies that overlaps
>>> between the left-hand side and the right-hand side are `safe' (for
>>> example "a, b = b, a" swaps two variables), overlaps within the
>>> collection of assigned-to variables are not safe! For instance, the
>>> following program prints "[0, 2]":
>>>
>>> x = [0, 1]
>>> i = 0
>>> i, x[i] = 1, 2
>>> print x
>>>
>>> Lorenzo Gatti
>>
>> Thank you for the explanation. I guess my question can be simplified as:
>>
>> First step: a, b = 0, 1
>> No problem here as a and b are assigned values.
>>
>> Second step: a, b = b, a + b
>>
>> Now my question is does b become a + b after a becomes 1 or while a
>> stays at 0?
>>
>> As the assignment occurs simultaneously I suppose the answer is while a
>> stays at 0.
> 
> Read the previous response carefully and you'll answer your question. 
> The right hand side is EVALUATED in full before values are assignated to 
> the left hand side. Evaluating b, a+b results in 1, 1. The, those values 
> are assigned to a, b.

Thank you very much. It's clear now.
-- 
http://mail.python.org/mailman/listinfo/python-list