integer division gives different result in CPython 2.7 and Spyder - python

I have encountered a quite weird case in Python.
In Spyder:
>>> 274/365
0.7506849315068493
>>> sys.version
'2.7.6 (default, Dec 20 2013, 14:08:04) [MSC v.1700 64 bit (AMD64)]'
>>>
However in command line it returns 0.
>>> 274/365
0
>>> 274/365 * 1.0
0.0
>>> 274/365.0
0.7506849315068493
Same version of Python.
Could anyone tell what is wrong here? Do I need to put some other options ahead of the program? This is really nauseous since my code gave weird results if I call it through command line..

Spyder executes from __future__ import division in its console.
This is discussed at https://code.google.com/p/spyderlib/issues/detail?id=1646 - it looks like this will be deactivated by default to avoid confusion.

You either use different versions of Python (in Spyder 3.* and on command line 2.*) or in your Spyder there is automatic import for your console including
from __future__ import division
On command line for Python 2.7
>>> 4/3
1
>>> from __future__ import division
>>> 4/3
1.3333333333333333

Related

Why do semicolons not suppress output in doctests?

Why do semicolons not suppress output in doctests? A workaround is to assign the result, but I am curious as to why this does not work.
"""
>>> 1+1; # Semicolons typically suppress output, but this fails
>>> x = 1+1 # Workaround: assign result to suppress output.
"""
Failed example:
1+1;
Expected nothing
Got:
2
Unlike other languages like C/C++, semicolons are optional terminators for statements in Python, as you can see in the Repl below:
Python 3.6.5 |Anaconda custom (64-bit)| (default, Mar 29 2018, 13:32:41) [MSC v
1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> 1 + 1;
2
>>> 1 + 1
2
However, you may observe a different behavior in say IPython:
In [120]: 1 + 1;
In [121]: 1 + 1
Out[121]: 2
The docs for IPython suggest using semicolons to suppress output. However, this behavior is only specific to IPython and does not in any way extend to Python or its standard libraries(like doctest).
You're thinking of MATLAB or IPython or something. Python semicolons don't normally suppress anything. doctest simulates a normal interactive Python session, not an IPython session, so the semicolon does nothing.
The semicolon has no effect at all.
Doctest reads the expected result from the line following the Python statement (i.e. the part after >>>). In your example, there is no result, so doctest expects no result. That's why it reports "Expected nothing". However, 1+1 returns 2.
The second expression, x = 1+1, has no result, so the test is successful (although nothing really is tested).
Try this for example:
"""
>>> 1+1 # without semicolon
2
>>> 1+1; # with semicolon
2
>>> x = 1+1 # not so useful test
"""

Python3 uses restype to define the return value of kernel32.GetModuleHandleA, but the value of python output is very large

I am studying the book "Python Grey Hat", this is one of my functions, I have been looking for this problem for a long time or not solved.
def func_resolve(self,dll,function):
GetModuleHandle = kernel32.GetModuleHandleA
GetModuleHandle.argtypes = [c_char_p]
GetModuleHandle.restype = c_void_p
handle = GetModuleHandle(dll)
print(handle)
GetProcAddress = kernel32.GetProcAddress
GetProcAddress.argtypes = [c_void_p,c_char_p]
GetProcAddress.restype = c_void_p
address = GetProcAddress(handle,function)
print(address)
My output handle value is 140707194077184, the address value is 140707194386736, I use OllyDbg to view the address of the wprintf function in msvcrt.dll is 0x73D178A0, but the value of address is converted to hexadecimal is also much larger than 0x73D178A0, hope Can someone help me, thank you
Nevermind the answer to my comment, I've found the cause. From OllyDbg (emphasis is mine):
OllyDbg is a 32-bit assembler level analysing debugger for Microsoft® Windows®.
That means that it can only load (work with) 32 bit processes (and / or .dlls) only. wprintf address confirms it (0x73D178A0 is 32 bit as it has (at most) 8 hex digits).
On the other hand, in Python, you get (much) larger values for pointers or addresses (e.g. handler = 140707194077184 (0x7FF8F256B930)) which don't fit in the 32 bit range, so it's 64 bit. For more details on how to get running Python architecture, check [SO]: How do I determine if my python shell is executing in 32bit or 64bit mode on OS X? (#CristiFati's answer) (even if the question is for OSX, Win is covered as well).
So, what's the catch? It's [MS.Docs]: File System Redirector that confused you regarding msvcr(t###).dll location:
Python (64 bit) loaded it from "%windir%\System32"
OllyDbg (32 bit) made you think that it loaded it from the same location (for backward compatibility reasons), when in fact it loaded it from "%windir%\SysWOW64"
Using a tool built for both 32 bit and 64 bit that you can launch in parallel (I use Dependency Walker), you can see the differences.
The return value is a Windows handle. The value is big because you are using 64-bit Python. The value doesn't matter as long as you've declared your ctypes properly. This code will work Python 2 or 3, 32- or 64-bit, and uses ctypes.wintypes for predefined Windows types:
from __future__ import print_function
import sys
from ctypes import *
from ctypes import wintypes as w
print(sys.version)
kernel32 = WinDLL('kernel32')
GetModuleHandle = kernel32.GetModuleHandleW
GetModuleHandle.argtypes = [w.LPCWSTR]
GetModuleHandle.restype = w.HMODULE
GetProcAddress = kernel32.GetProcAddress
GetProcAddress.argtypes = [w.HMODULE,w.LPCSTR]
GetProcAddress.restype = c_void_p # FARPROC isn't defined in wintypes, but a generic pointer works.
handle = GetModuleHandle(u'user32')
address = GetProcAddress(handle,b'MessageBeep')
print(hex(address))
MessageBeep = WINFUNCTYPE(w.BOOL,w.UINT)(address)
MessageBeep(0)
Output with two Pythons I have installed (beep is played each time):
C:\>py -2 test.py
2.7.14 (v2.7.14:84471935ed, Sep 16 2017, 20:19:30) [MSC v.1500 32 bit (Intel)]
0x756e56d0
C:\>py -3 test.py
3.7.0 (v3.7.0:1bf9cc5093, Jun 27 2018, 04:59:51) [MSC v.1914 64 bit (AMD64)]
0x7fff6ca29a40

why the result is different between running python interpreter and python code?

I made a simple code on python interpreter and run it.
Python 3.5.3 (v3.5.3:1880cb95a742, Jan 16 2017, 16:02:32) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy as np
>>> x=np.array([0,1])
>>> w=np.array([0.5,0.5])
>>> b=-0.7
>>> np.sum(w*x)+b
-0.19999999999999996
the result -0.19999999999999996 is weird. I think.... it is caused by IEEE 754 rule. But when I try to run almost same code by file, result is a lot different.
import numpy as np
x = np.array([0,1])
w = np.array([0.5,0.5])
b = -0.7
print(np.sum(w * x) + b)
the result is "-0.2". IEEE 754 rule does not affect the result.
what is the difference between file based running and interpreter based running?
The difference is due to how the interpreter displays output.
The print function will try to use an object's __str__ method, but the interpreter will use an object's __repr__.
If, in the interpreter you wrote:
...
z = np.sum(w*x)+b
print(z)
(which is what you're doing in your code) you'd see -0.2.
Similarly, if in your code you wrote:
print(repr(np.sum(w * x) + b))
(which is what you're doing in the interpreter) you'd see -0.19999999999999996
I think the difference lies in the fact that you use print() for your file based code, which converts the number, while in the interpreter's case, you don't use print(), but rather ask the interpreter to show the result.

Beginner of Python: <Syntaxerror: invalid syntax> when trying to import program

This is my first day learning programming. I'm following Python Programming: An introduction to computer science 2nd ed. by John Zelle, and so far things have been going smoothly.
The only trouble is that when I try and import a saved program I get a syntaxerror. I write the program and save it before executing, but then when I try to import it I get the error. I tried opening a fresh instance of the shell but no cigar. I'm using OSX Lion 10.8 and Python 2.7.3. Any help is appreciated. This is what the problem looks like:
>>> #File: chaos.py
>>> #A simple program illustrating chaotic behavior.
>>> def main():
print "This program illustrates a chaotic function"
x=input("Enter a number between 0 and 1: ")
for i in range(10):
x = 3.9 * x * (1-x)
print x
>>> main()
This program illustrates a chaotic function
Enter a number between 0 and 1: .25
0.73125
0.76644140625
0.698135010439
0.82189581879
0.570894019197
0.955398748364
0.166186721954
0.540417912062
0.9686289303
0.118509010176
>>> import chaos
Traceback (most recent call last):
File "<pyshell#47>", line 1, in <module>
import chaos
File "chaos.py", line 1
Python 2.7.3 (v2.7.3:70274d53c1dd, Apr 9 2012, 20:52:43)
^
SyntaxError: invalid syntax
My guess is that you are copying the contents of the terminal to the file, verbatim. And there are a lot of thing that should not be there, that includes the version prompt.
The file should have just something like:
#File: chaos.py
#A simple program illustrating chaotic behavior.
def main():
print "This program illustrates a chaotic function"
x=input("Enter a number between 0 and 1: ")
for i in range(10):
x = 3.9 * x * (1-x)
print x
No >>>, no ..., no tabulators and certainly do not copy the version information:
Python 2.7.3 (default, Dec 22 2012, 21:27:36)
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
File "chaos.py", line 1
Python 2.7.3 (v2.7.3:70274d53c1dd, Apr 9 2012, 20:52:43)
^
SyntaxError: invalid syntax
It looks like the first line of your chaos.py script has a line which is not python:
Python 2.7.3 (v2.7.3:70274d53c1dd, Apr 9 2012, 20:52:43)
It should be removed or commented-out by starting the line with a # sign.
Some tips to keep in mind:
In Python, whitespace is important -- they indicate indentation
level. Do not mix spaces and tabs lest Python raise IndentationErrors.
In texts or web pages, you may see transcripts of interactive
sessions which include >>> or ... indicating the Python prompt or
indentation level. If you transfer the code to a script, you must
remove those.

Using "from __future__ import division" in my program, but it isn't loaded with my program

I wrote the following program in Python 2 to do Newton's method computations for my math problem set, and while it works perfectly, for reasons unbeknownst to me, when I initially load it in ipython with %run -i NewtonsMethodMultivariate.py, the Python 3 division is not imported. I know this because after I load my Python program, entering x**(3/4) gives "1". After manually importing the new division, then x**(3/4) remains x**(3/4), as expected. Why is this?
# coding: utf-8
from __future__ import division
from sympy import symbols, Matrix, zeros
x, y = symbols('x y')
X = Matrix([[x],[y]])
tol = 1e-3
def roots(h,a):
def F(s):
return h.subs({x: s[0,0], y: s[1,0]})
def D(s):
return h.jacobian(X).subs({x: s[0,0], y: s[1,0]})
if F(a) == zeros((2,1)):
return a
else:
while (F(a)).norm() > tol:
a = a - ((D(a))**(-1))*F(a)
print a.evalf(10)
I would use Python 3 to avoid this issue, but my Linux distribution only ships SymPy for Python 2. Thanks to the help anyone can provide.
Also, in case anyone was wondering, I haven't yet generalized this script for nxn Jacobians, and only had to deal with 2x2 in my problem set. Additionally, I'm slicing the 2x2 zero matrix instead of using the command zeros(2,1) because SymPy 0.7.1, installed on my machine, complains that "zeros() takes exactly one argument", though the wiki suggests otherwise. Maybe this command is only for the git version. (Thanks eryksun for correcting my notation, which fixed the issue with the zeros function.)
Both ipython -i command and run -i in ipython interpreter ignore from __future__ import division in print05.py script.
$ cat print05.py
from __future__ import division
print(1/2)
In ipython console:
In [1]: print 1/2
0
In [2]: run -i print05.py
0.5
In [3]: division
Out[3]: _Feature((2, 2, 0, 'alpha', 2), (3, 0, 0, 'alpha', 0), 8192)
In [4]: print 1/2
0
In [5]: from __future__ import division
In [6]: print 1/2
0.5
execfile and import produce the same result:
>>> print 1/2
0
>>> execfile('print05.py')
0.5
>>> print 1/2
0
>>> from __future__ import division
>>> print 1/2
0.5
from __future__ import division should not have effect on the source code from different modules, otherwise it would break code in other modules that don't expect its presence.
Here, from __future__ import division has effect:
$ python -i print05.py
0.5
>>> print 1/2
0.5
>>> division
_Feature((2, 2, 0, 'alpha', 2), (3, 0, 0, 'alpha', 0), 8192)
The module name in this case is __main__ both inside print05.py and in the prompt.
Here, the first print 1/2 executes in print05 module, the second one in __main__ module so it also works as expected:
$ python -im print05
0.5
>>> print 1/2
0
And here's something wrong:
$ ipython -i print05.py
0.5
In [1]: division
Out[1]: _Feature((2, 2, 0, 'alpha', 2), (3, 0, 0, 'alpha', 0), 8192)
In [2]: print 1/2
0
The docs for __future__ say:
If an interpreter is started with the -i option, is passed a script
name to execute, and the script includes a future statement, it will
be in effect in the interactive session started after the script is
executed.
So It might be a bug in ipython if its -i option tries to emulate the same python option.
SymPy also provides a script -- isympy -- which is a wrapper for IPython which executes some common commands, including an import of division from future. It's quite handy, and in newer IPython versions (0.11+) it also allows automatic constructions of Symbols (which is nice as I always seem to forget); run it with the -a parameter.
As for Python 3, there is support for it in the development version and the next release will have it; when distributions are going to pack it I don't know.

Categories