View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0005252 | Scribus | Scripter | public | 2007-01-26 03:03 | 2007-02-03 22:42 |
Reporter | PatMcGee | Assigned To | subik | ||
Priority | normal | Severity | minor | Reproducibility | always |
Status | closed | Resolution | fixed | ||
Platform | Win | OS | XP | OS Version | SP2 |
Product Version | 1.3.3.7 | ||||
Fixed in Version | 1.3.3.8cvs | ||||
Summary | 0005252: Scripts run from Script -> Execute Script improperly type some arithmetic expressions | ||||
Description | A python division binary arithmetic operation between two integers should result in an integer result. When a script is executed using Script -> Execute Script, it results in a float. (When executing the same file from the Script Console, using File -> Open, then Script -> Run, the expression properly results in an integer.) | ||||
Steps To Reproduce | 1. In the file 'boilerplate.py', add the following lines in main immediately before the line containing 'pass': myVar = ( 3 / 2) f = open ('testfile', 'a') f.write('myVar=' + str(myVar) + ' type(myVar)=' + str(type(myVar)) + '\n') f.close 2. From the Scribus main window, do Script -> Execute Script ..., navigate to the new file, and click OK. 3. Find the file 'testfile' and examine the contents. My file had: myVar=1.5 type(myVar)=<type 'float'> 4. From the Scribus main window, do Script -> Show Console. 5. From the Script Console window, do File -> Open. Navigate to the new file and clike Open. 6. Still in the Script Console window, do Script -> Run. 7. Find the file 'testfile' and examine the contents. My file had: myVar=1 type(myVar)=<type 'int'> | ||||
Additional Information | This behavior is the same on Windows XP SP2 running Scribus 1.3.3.2 (I forgot to copy the build info before I reinstalled 1.3.3.7), and on Mac OS X 10.4.8, running the Aqua port of Scribus 1.3.3.2 Build C-C-T-F-A-Mac/Aqua. | ||||
Tags | No tags attached. | ||||
Patch | |||||
|
I should have said that I discovered this while debugging a python module that I had written for a different program and attempted to port to Scribus for use with a new script. The program failed in very strange ways, drawing things several inches away from where they should have been. It took me most of a day to track down the problem. I raise the issue because of the portability issues, not because of any impact on new code. For new code, people could use '//' instead of '/' and get the correct result. It's when importing old code where that may be several levels down that tracking down the problem gets really tricky. |
|
subzero@powerpuff:~/tmp> python Python 2.5 (r25:51908, Jan 9 2007, 16:59:32) [GCC 4.1.2 20061115 (prerelease) (SUSE Linux)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> myVar = ( 3 / 2) >>> f = open ('testfile', 'a') >>> f.write('myVar=' + str(myVar) + ' type(myVar)=' + str(type(myVar)) + '\n') >>> f.close <built-in method close of file object at 0xb7c41b18> >>> f.close() >>> subzero@powerpuff:~/tmp> cat testfile myVar=1 type(myVar)=<type 'int'> subzero@powerpuff:~/tmp> |
|
btw easy workaround: (3.0 / 2) gives you the right result |
|
I'd agree more with the position that it's a Python issue if Scribus didn't do it two different ways, one place correctly, one place incorrectly. What could it be in Scribus that causes Python to work wrong when called from some places but not others? And, more worringly, if Scribus has this effect on Python in arithmetic, what other strange things might lurk there? |
|
wooha! got it. There is missing a future's import division in one piece of the code. So 3/2 will return 1.5 in scripts *and* in scribus console after this fix too. Quick workaround: use "from __future__ import division" in your scripts until the new release/cvs build conquers your desktop. |
|
Subik, I don't think I understand. From your session on the console in note 15004, it looks like the correct answer should be 1, not 1.5. It looks to me like the Python language reference manual agrees also. So, if you change both Script and Console to return 1.5, I think they'll both be giving the same wrong answer. |
|
http://www.python.org/dev/peps/pep-0238/ heh, it's easy to patch too. Lets summarize how it will be: 3/2 = 1 (int) 3.0/2 = 1.5 (float) float(3)/2 = 1.5 (float) so it'll be like in standard Python 2.x. (which means all scripts will behave strange in Python 3000 (if it will be released some day ;))) btw I wonder why is the "true division" switch statement in script-file runtime environment. Ok, 3/2 = 1.5 *is* more logical than 1, but Python handles it this way. |
|
Reminder sent to: Craig, do you have any clue why is the "from __future__ import division" statement in void ScripterCore::slotRunScriptFile(QString fileName, bool inMainInterpreter)? Maybe it has any meaning. But I cannot see what one. |
|
Yep - it makes integer division return a real if the result isn't evenly divisible - ie: 3/2 == 1.5 instead of 3/2 = 1 As Python 2.5 or 2.6 will make this the default (see the PEP on division) that helps make sure scripts behave consistently into the future with this rather crucial change in behavior. Use // if you want floor division. [Edit: Actually, it appears that the division change will now not be going into 2.x . I think this has changed, since that was the plan for a while. Given this, removing the division import will improve compatibility, where originally it was put in to help when transitioning to newer Python versions for the same reason] |
|
Subik, Thanks for the link. Now I understand, and I also have a lot more confidence in everything else in Python under Scribus. I withdraw my question about wondering what other dragons might be lurking. On a more philosophical note, I believe they did classical division the way they did to value consistency over consistency. That is, they defined a rule that says binary arithmetic on integer operands always returned an integer, no matter what operator. So, they made classical division consistent with this rule. Some people believe that division operator should always return a float, no matter what the operands. And so, they define things consistent with that definition. In Python 3, it looks like they're changing to be consistent with the second and not with the first. Isn't consistency wonderful? |
Date Modified | Username | Field | Change |
---|---|---|---|
2007-01-26 03:03 | PatMcGee | New Issue | |
2007-01-26 03:18 | PatMcGee | Note Added: 0015002 | |
2007-01-26 06:54 | subik | Note Added: 0015004 | |
2007-01-26 06:56 | subik | Note Added: 0015005 | |
2007-01-26 14:45 | PatMcGee | Note Added: 0015012 | |
2007-01-26 15:07 | subik | Status | new => assigned |
2007-01-26 15:07 | subik | Assigned To | => subik |
2007-01-26 15:10 | subik | Note Added: 0015013 | |
2007-01-26 15:28 | PatMcGee | Note Added: 0015014 | |
2007-01-26 15:43 | subik | Note Added: 0015015 | |
2007-01-26 15:47 | subik | Note Added: 0015016 | |
2007-01-26 15:53 |
|
Note Added: 0015017 | |
2007-01-26 15:56 |
|
Note Edited: 0015017 | |
2007-01-26 15:58 | PatMcGee | Note Added: 0015018 | |
2007-01-26 18:45 | subik | Status | assigned => resolved |
2007-01-26 18:45 | subik | Fixed in Version | => 1.3.3.8cvs |
2007-01-26 18:45 | subik | Resolution | open => fixed |
2007-02-03 22:42 | cbradney | Status | resolved => closed |