Monday, May 11, 2009

Python 3.1 - get ready

Python 3.1 is in beta testing now. The changes can be found here, but I'll post a quick summary:

Ordered dictionaries: Example 29 provides us with a SortableDict class, found in the collections module. What Python 3.1 gives us is a little different, though. It just keeps the order that you passed in the items. In addition to all of the normal dict methods, this new class has a method OrderedDict.popitem(last=True) that will pop the last (or first, if last is set to False) item off of the object, much like list.pop(). Note that if you change the value of an item, the order will not change. If you remove that item and then add it back in, the item will then go to the back. Here's how to use the OrderedDict class in 3.1 (using Dr. Punch's example29.demo() example values):

And the output...








String formatting, the new way. As you probably have read in my first post, the format method on strings is the preferred way to format strings... but it seems kind of silly to number each format part if you're just going in order (like we're used to with the % operator):
"I asked my friend {0}, and I asked my friend {1}; they said it was {2}!".format("Joe", "Jake", "fhqwhgads")
Well now, with Python 3.1 (RC1 is out), you can do this:
"I asked my friend {}, and I asked my friend {}; they said it was {}!".format("Joe", "Jake", "fhqwhgads")
and you will get the same formatted output. Of course, the numbering method will still work (and is still necessary if you want to be playing with the order of the format strings).

Also format-related, check this out (the comma means to add decimal separators, everything else has been around since 2.6/3.0... "0" says the first argument to format, ":" means to do manipulation, ".2" means 2-precision, "f" means to "coerce" to float):
>>> "{0:,.2f}".format(123456789)
'123,456,789.00'

That's right, human-readable decimals with string formatting!
(Combine this new change with the previous one and you get this:)
>>> "{:,.2f}".format(123456789)
'123,456,789.00'

More to come when I get time.

Thursday, December 4, 2008

Py3k is final.

As of 11:59pm EST, Python 3.0 has been released. If you're planning on upgrading, there is a very good chance that the "2to3" tool released with it (I believe it came with Python 2.6 as well) will be able to fix your code that worked with 2.x to again work with 3.0. Of course, make sure that it works in 2.x before running 2to3, or you might have a tough time figuring out what's wrong with your program.

See the first post of this blog for a list of the major things different from the upgrade.

Most important things:
raw_input() is no longer raw_ anymore, and just became input()
print is now a FUNCTION, not a statement. That means parentheses. (Get your fingers used to it now!) print(x), not print x.
integer division (int / int) returns a float! (int // int does the classic thing). Also longs.

Thursday, November 20, 2008

Coercion in Py3k

In Python 3.0, as Dr. Punch has hinted at in class today, coerce() and all its friends are removed.

Thursday, November 6, 2008

NumPy in Python 3.0

Today, Dr. Punch talked about NumPy. Note that this module is not available in Python 3.0 yet. My hopes are that this is available by the time Py3k is released, but it is rather possible that we will have to go without it.

Also, note that I have finished testing all the class examples with the 2to3 script. Go ahead and read what's different now!

Thursday, October 16, 2008

Dictionary Methods

Straight from the list of changes in 3.0 regarding dictionary methods:

dict methods dict.keys(), dict.items() and dict.values() return views instead of lists. For example, this no longer works: k = d.keys(); k.sort(). Use k = sorted(d) instead.

Never fear! These methods can still give you lists, by using the list() function on them.

Example:
{'k':49,'g':500}.values() => [49,500] in 2.x
list({'k':49,'g':500}.values()) => [49,500] in 3.0.

This refactoring is included with the 2to3 shell script included with version 2.6 and version 3.0RC1

Tuesday, October 7, 2008

Python 3.0: What affects us?

I've built Python 3.0 RC1 (First Release Candidate) to test out what it's going to do to our projects. This blog is specifically dedicated to a list of the changes that affect us. I will update it as I find more things (I'm going to literally go through all my projects and all the class code examples and say what doesn't work.)

If you have any questions about your particular projects / code snippets, you can send them to me at amentajo@msu.edu or simply post as a comment here. PLEASE don't send me the current working project or any significant portions of it. (Project 10 now...)

I'm willing to put my time into testing anything sent to me, so don't hesitate to send me things to test!

Python 3.0 RC1 incompatibilities:
--strings
----String formatting with the % operator is done away with, and replaced by a format() method for strings. 'Hello, %s' % ('world') has turned into 'Hello, {0}'.format('world'). In general, it looks like 'Sometext {n}'.format('a','b','c','d') where the {n} refers to the index of the tuple passed to format(). See the official readme for more details on this matter. It has been confirmed that the previous statement is false. In 3.0, print('Hello %s' % ('world')) works, as do all other implementations of the % formatting character we have learned in class. (See comment below about print()). My previous confusion was due to the fact that print is a function now.
--integers
----integer division returns a float... 1/2 => 0.5, 1//2 => 0
----long integers are now just integers, and there is no max length

--print:
----print no longer works 'without parentheses'. You must use print("Hello World"). print "Hello World" will no longer work. This is because print has been changed from a statement into a function: print(x) rather than print x.
--raw_input:
----raw_input() has been replaced with input(), which appears to work exactly the same.
--range:
----range() now returns an iterable instead of a list. That is to say, x = range(1,10) will return range(1,10) when x is called, but for x in range(1,10): print (x, end = '') will print 123456789. (This is the behaviour of a function that exists in 2.5 called xrange(), which no longer exists in 3.0)

Specific tests of Class Code Examples (python 3.0 and 2.6 come with a script called '2to3' that refactors certain lines of 2.x code to work with 3.0. I tested the examples after running 2to3 on them, and these are the results):

01-04:
fixed with 2to3...

05-haiku:
not fixed with 2to3... error at line 6, "NameError: name 'file' is not defined" This appears to be because in 3.0, various builtins were removed, including file(). Not sure what a workaround may be.

06-10:
fixed with 2to3...

11-password:
almost fixed with 2to3... change the variable name input to something else, as input() is now a function.

11.5-Palindromes:
not fixed with 2to3... multiple functions do not operate properly.

12-simpleLists:
fixed with 2to3...

13-forExample:
fixed with 2to3 and changing range(1-11) to range(1,11)

14-perfectNumbers:
fixed with 2to3, but be careful - the commented lines of print statements will NOT run if uncommented after 2to3. Please make all changes to original 2.x modules before running 2to3, and rerun it every time you make a change.

15-16B:
fixed with 2to3...

16C-mileagePuz:
fixed with 2to3... note that the time output for 3.0 appears to be approximately 25% faster than the same module in 2.6. (running Ubuntu Linux 8.04, Hardy Heron (linux kernel 2.6.24-21-generic), Intel Core 2 Duo (1.00GHz * 2), the averages of the two are 300ms in 3.0, 400ms in 2.6.)

17-19:
fixed with 2to3...

20-sets:
simpleSets.py is broken in 2.5 and 2.6: lists are unhashable. 2to3 keeps this error.

21-dicts:
fixed with 2to3...

21.5-funcParams:
not fixed with 2to3, but very fixable. change commas in print functions to %( and close parentheses at the end.

22-classes:
fixed with 2to3... previously reported as broken, but works as intended...

23-scope:
fixed with 2to3...

24-note:
not fixed with 2to3... must delete the s.print call, or define the method (print is now a function, not a statement)

25-27:
fixed with 2to3...

28-expansion:
almost fixed with 2to3... line 35 is malindented. Add another space there. Also, make sure example 27's Rational.py is in PYTHONPATH or you will get an ImportError.

29,30:
fixed with 2to3

31-PythonArray:
not fixed with 2to3... NumPy is not 3.x ready.

32-exceptionExamples:
not all fixed with 2to3...
fullException.py:
types that were once "file" are now class objects io.TextIOWrapper. Fix by importing the io module then changing line 23 to:
if type(fs)== io.TextIOWrapper:
exceptionFlow.py:
fixed with 2to3...
raise.py:
working, but be careful of the name conflict with 'raise'. No importing raise or anything from raise, but you can run it otherwise.

33-sort_and_search:
sort works with 2to3, but search needs one adjustment: since int division returns a float, line 26 needs to be converted to an int with the int() function after refactoring.

34-scriptExample:
fixed with 2to3...

35-_testing:
doctestExample.py: problems with long integers: long() is now named int() and L suffixes are removed in 3.0.
unittestExample.py: fixed with 2to3...

36-_PythonToC++:
irrelevant; the dateClass.py module is in example 22.

amentajo@msu.edu