<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-5051690563388562347</id><updated>2011-07-07T16:15:45.135-07:00</updated><category term='Python'/><category term='PSF'/><category term='py.test'/><category term='Snakebite'/><category term='nose'/><category term='VCS'/><category term='GSoC'/><category term='unittest'/><category term='Mercurial'/><title type='text'>Spartan Sniper</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://yangyan5.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5051690563388562347/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://yangyan5.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Yang Yang</name><uri>http://www.blogger.com/profile/00930453836447183866</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/_LTsGMs7zsaM/STfiDSWFaRI/AAAAAAAAABM/BVh8DUe1fu8/S220/sniper33ts.png'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>12</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5051690563388562347.post-7664857831029113886</id><published>2009-07-11T11:07:00.000-07:00</published><updated>2009-07-11T11:29:01.937-07:00</updated><title type='text'>Current Status of GSoC Project</title><content type='html'>Currently only some tests of execnet/ and test/ failed. The 2nd kind of failures in &lt;a href="http://yangyan5.blogspot.com/2009/07/current-status-of-gsoc-project.html"&gt;previous post&lt;/a&gt; can be bypassed using locals() dictionary. It seems that python3.1 intendedly suppress the variables generated by exec() can only be shown in locals() dictionary.&lt;br /&gt;&lt;br /&gt;Current Status:&lt;br /&gt;tests: 169 failed, 1283 passed.&lt;br /&gt;passed folders: builtin/, code/, cmdline/, io/, log/, misc/, path/, process/, rest/, thread/, tool/, xmlobj/.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5051690563388562347-7664857831029113886?l=yangyan5.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yangyan5.blogspot.com/feeds/7664857831029113886/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5051690563388562347&amp;postID=7664857831029113886' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5051690563388562347/posts/default/7664857831029113886'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5051690563388562347/posts/default/7664857831029113886'/><link rel='alternate' type='text/html' href='http://yangyan5.blogspot.com/2009/07/current-status-of-gsoc-project_11.html' title='Current Status of GSoC Project'/><author><name>Yang Yang</name><uri>http://www.blogger.com/profile/00930453836447183866</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/_LTsGMs7zsaM/STfiDSWFaRI/AAAAAAAAABM/BVh8DUe1fu8/S220/sniper33ts.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5051690563388562347.post-8784989573945951297</id><published>2009-07-04T10:40:00.000-07:00</published><updated>2009-07-04T12:15:12.010-07:00</updated><title type='text'>Current Status of GSoC project</title><content type='html'>Currently, for all tests of py.test, 1277 passed, 183 failed under python3.1. There are mainly 3 kinds of failures:&lt;br /&gt;1. magic/exprinfo.py relies on the compiler package which is no longer supported by python3.x. exprinfo.py is used to construct assertion exception information, and in python3.1 I just simply disable exprinfo.py feature. So, some tests failed because of assertion exception's message does not match the expected string.&lt;br /&gt;2. code/source.py provides a substitute API for compile function, but this API seems does not work well under python3.1. I think the reason is that the compile function's mechanism seems changed. For example:&lt;br /&gt;&lt;br /&gt;&lt;pre style="white-space: pre;"&gt;def foo():&lt;br /&gt;  co = compile("x=3", '', 'exec')&lt;br /&gt;  exec(co)&lt;br /&gt;  print("x:", x)&lt;br /&gt;&lt;br /&gt;foo()&lt;/pre&gt;The output is: NameError: global name 'x' is not defined. However, this program can be run successfully under python2.x.&lt;br /&gt;3. execnet/ folder aims to support distributed testing feature, and uses io stream tunnel heavily. But, in python3.1, some io streams require bytes not strings. the differences between byte and string are really annoying. So, some tests of py.test failed due to the messages cannot be transported from the sender to the receiver.&lt;br /&gt;&lt;br /&gt;Currently passed folders:&lt;br /&gt;builtin/&lt;br /&gt;cmdline/&lt;br /&gt;io/&lt;br /&gt;log/&lt;br /&gt;misc/&lt;br /&gt;path/&lt;br /&gt;process/&lt;br /&gt;rest/&lt;br /&gt;thread/&lt;br /&gt;tool/&lt;br /&gt;xmlobj/&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5051690563388562347-8784989573945951297?l=yangyan5.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yangyan5.blogspot.com/feeds/8784989573945951297/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5051690563388562347&amp;postID=8784989573945951297' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5051690563388562347/posts/default/8784989573945951297'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5051690563388562347/posts/default/8784989573945951297'/><link rel='alternate' type='text/html' href='http://yangyan5.blogspot.com/2009/07/current-status-of-gsoc-project.html' title='Current Status of GSoC project'/><author><name>Yang Yang</name><uri>http://www.blogger.com/profile/00930453836447183866</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/_LTsGMs7zsaM/STfiDSWFaRI/AAAAAAAAABM/BVh8DUe1fu8/S220/sniper33ts.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5051690563388562347.post-4969763233089130447</id><published>2009-06-19T20:22:00.000-07:00</published><updated>2009-06-27T11:10:48.010-07:00</updated><title type='text'>Porting py.test from python2.x to python3.1 (updated on Jun 27)</title><content type='html'>Due to python3.x 's intentional backwards incompatibility, it is not an easy work to migrate a project's codebase from python2.x to python3.x. Guido has given a recommended development model:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;You should have excellent unit tests with close to full coverage.&lt;/li&gt;&lt;li&gt;Port your project to Python2.6.&lt;/li&gt;&lt;li&gt;Turn on the Py3k warnings mode.&lt;/li&gt;&lt;li&gt;Test and edit until no warnings remain.&lt;/li&gt;&lt;li&gt;Use the 2to3 tool to convert this source code to 3.0 syntax.&lt;/li&gt;&lt;li&gt;Test the converted source code under 3.0.&lt;/li&gt;&lt;li&gt;If problems are found, make corrections to the 2.6 version of the source code and go back to step 4.&lt;/li&gt;&lt;li&gt;When it's time to release, release separate 2.6 and 3.0 tarballs.&lt;/li&gt;&lt;/ol&gt;Fortunately, py.test is already 2.4 and 2.6 compatible, and has sufficient unit tests. So, I can directly start from step 3. However, unfortunately, Holger requires the codebase ported to 3.1 should still be compatible with 2.4 and 2.6, i.e., maintain only one codebase which could be used through all main python versions. So, 2to3 tool can only be used to show the minimum places that need notification.&lt;br /&gt;&lt;br /&gt;Thus, to make py.test compatible with python2.4, 2.6, and 3.1, the first thing is to write some wrapper functions. The functions I wrote are:&lt;br /&gt;&lt;span style="color: rgb(51, 204, 0);"&gt;Print&lt;/span&gt;:&lt;br /&gt;--use Print function instead of each print statement in py.test, so python3.1 will not throw SyntaxError. In Print function, execute correct print code according to current python version.&lt;br /&gt;&lt;span style="color: rgb(51, 204, 0);"&gt;Raise&lt;/span&gt;:&lt;br /&gt;--the only incompatible syntax is raise cls, value, tb (2.x) and raise cls(value).with_traceback(tb) (3.x). So, just simply call corresponding statement in Raise function.&lt;br /&gt;&lt;span style="color: rgb(51, 204, 0);"&gt;isinstancemethod&lt;/span&gt;, &lt;span style="color: rgb(51, 204, 0);"&gt;isclassmethod&lt;/span&gt;, &lt;span style="color: rgb(51, 204, 0);"&gt;isfunction&lt;/span&gt;:&lt;br /&gt;--suppose we defined a class "myclass" and a method "method" inside "myclass", then create an instance of myclass, myinstance. In 2.x, myclass.method and myinstance.method have the same attribute names. But in 3.x, myclass.method's attribute names are the same with the ones of normal function. This is a very annoying difference, because in many places code objects are got by &lt;span style="font-family:courier new;"&gt;obj.im_func.func_code&lt;/span&gt;. In 2.x, &lt;span style="font-family:courier new;"&gt;obj&lt;/span&gt; could be myinstance.method or myclass.method; In 3.x, &lt;span style="font-family:courier new;"&gt;obj.im_func.func_code&lt;/span&gt; must be changed to &lt;span style="font-family:courier new;"&gt;obj.__func__.__code__&lt;/span&gt; and it only works for myinstance.method. For myclass.method or normal function, should use &lt;span style="font-family:courier new;"&gt;obj.__code__&lt;/span&gt;. So, I have to provide three functions to distinguish them respectively.&lt;br /&gt;&lt;span style="color: rgb(51, 204, 0);"&gt;updatemethodattr&lt;/span&gt;, &lt;span style="color: rgb(51, 204, 0);"&gt;updatefunctionattr&lt;/span&gt;:&lt;br /&gt;--method's attributes:&lt;br /&gt;im_self ==&gt; __self__&lt;br /&gt;im_func ==&gt; __func__&lt;br /&gt;im_class ==&gt; disappeared?&lt;br /&gt;--function's attributes:&lt;br /&gt;func_closure ==&gt; __closure__&lt;br /&gt;func_code ==&gt; __code__&lt;br /&gt;func_defaults ==&gt; __defaults__&lt;br /&gt;func_dict ==&gt; __dict__&lt;br /&gt;func_doc ==&gt; __doc__&lt;br /&gt;func_globals ==&gt; __globals__&lt;br /&gt;func_name ==&gt; __name__&lt;br /&gt;So, to keep codebase unchanged, if obj is 3.x's method or function, create 2.x's attributes.&lt;br /&gt;&lt;span style="color: rgb(51, 204, 0);"&gt;CmpToKey&lt;/span&gt;:&lt;br /&gt;--in 3.x, there is no cmp keyword in sort function. So, this wrapper will transform a cmp function to key function.&lt;br /&gt;&lt;span style="color: rgb(51, 204, 0);"&gt;bytestostr&lt;/span&gt;, &lt;span style="color: rgb(51, 204, 0);"&gt;strtobytes&lt;/span&gt;:&lt;br /&gt;--in 3.x, all strings are unicode, but lots of streams require bytes object instead of string. So, use these two functions to wrap stream arguments and when it's 3.x, transfer from bytes to str or str to bytes.&lt;br /&gt;&lt;br /&gt;Second, for some well known incompatibilities, such as "except as" and module rename. For "except Error as e:", change it to "except Error:", and in except block, create e by "e = sys.exc_info()[1]". For module rename, add a try/except block. For example:&lt;br /&gt;try: import StringIO&lt;br /&gt;except ImportError: import io as StringIO&lt;br /&gt;&lt;br /&gt;Third, 3.x has many incompatible mechanisms. For example: 3.x will not call __cmp__ when compareing two objects. So, __lt__, __gt__, __le__, __ge__, and __eq__ should be implemented. Furthermore, if you define __eq__, __hash__ must be provided.&lt;br /&gt;In 2.x, dict.items() will return a copy list of key-value pairs. But in 3.x, dict.items() will return a view object, and if the dict's size changed during iteration, a RuntimeError will be thrown. So, although "&lt;span style="font-family:courier new;"&gt;for key,value in dict.items():&lt;/span&gt;" still works in 3.x, it should be changed to "&lt;span style="font-family:courier new;"&gt;for key, value in list(dict.items()):&lt;/span&gt;" in case of RuntimeError.&lt;br /&gt;&lt;br /&gt;There are still lots of incompatibities need to be fixed. Currently the packages of py.test without test failures under 3.1 are:&lt;br /&gt;builtin/&lt;br /&gt;cmdline/&lt;br /&gt;io/&lt;br /&gt;log/&lt;br /&gt;path/&lt;br /&gt;process/&lt;br /&gt;rest/&lt;br /&gt;I will keep updating this post when porting. Hope this could be finished ASAP.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5051690563388562347-4969763233089130447?l=yangyan5.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yangyan5.blogspot.com/feeds/4969763233089130447/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5051690563388562347&amp;postID=4969763233089130447' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5051690563388562347/posts/default/4969763233089130447'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5051690563388562347/posts/default/4969763233089130447'/><link rel='alternate' type='text/html' href='http://yangyan5.blogspot.com/2009/06/porting-pytest-from-python2x-to.html' title='Porting py.test from python2.x to python3.1 (updated on Jun 27)'/><author><name>Yang Yang</name><uri>http://www.blogger.com/profile/00930453836447183866</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/_LTsGMs7zsaM/STfiDSWFaRI/AAAAAAAAABM/BVh8DUe1fu8/S220/sniper33ts.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5051690563388562347.post-120696886967113555</id><published>2009-04-23T20:17:00.000-07:00</published><updated>2009-04-26T12:01:53.405-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='unittest'/><category scheme='http://www.blogger.com/atom/ns#' term='py.test'/><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><title type='text'>Notes on Test</title><content type='html'>1. self contained&lt;br /&gt;The test case can be run either in isolation or in arbitrary combination with any number of other test cases.&lt;br /&gt;&lt;br /&gt;2. In &lt;span style="font-family:courier new;color:#33cc00;"&gt;unittest&lt;/span&gt; of Python, If &lt;span style="font-family:courier new;"&gt;setUp()&lt;/span&gt; succeeded, the &lt;span style="font-family:courier new;"&gt;tearDown()&lt;/span&gt; method will be run whether &lt;span style="font-family:courier new;"&gt;runTest()&lt;/span&gt; succeeded or not.&lt;br /&gt;&lt;br /&gt;3. In &lt;span style="font-family:courier new;"&gt;unittest&lt;/span&gt; of Python, there are some ways to create test suite.&lt;br /&gt;&lt;pre style="WHITE-SPACE: pre"&gt;--------------------&lt;br /&gt;suite = unittest.TestLoader().loadTestsFromTestCase(WidgetTestCase)&lt;br /&gt;--------------------&lt;br /&gt;def suite():&lt;br /&gt;    suite = unittest.TestSuite()&lt;br /&gt;    suite.addTest(WidgetTestCase('testDefaultSize'))&lt;br /&gt;    suite.addTest(WidgetTestCase('testResize'))&lt;br /&gt;    return suite&lt;br /&gt;--------------------&lt;br /&gt;def suite():&lt;br /&gt;    tests = ['testDefaultSize', 'testResize']&lt;br /&gt;    return unittest.TestSuite(map(WidgetTestCase, tests))&lt;/pre&gt;4. To use old test without converting every old test function to a &lt;span style="font-family:courier new;"&gt;TestCase&lt;/span&gt; subclass, unittest provides a &lt;span style="font-family:courier new;"&gt;FunctionTestCase&lt;/span&gt; class. This subclass of &lt;span style="font-family:courier new;"&gt;TestCase&lt;/span&gt; can be used to wrap an existing test function. Set-up and tear-down functions can also be provided.&lt;br /&gt;&lt;pre style="WHITE-SPACE: pre"&gt;def testSomething():&lt;br /&gt;    something = makeSomething()&lt;br /&gt;    assert something.name is not None&lt;br /&gt;    # ...&lt;br /&gt;&lt;br /&gt;testcase = unittest.FunctionTestCase(testSomething)&lt;br /&gt;or&lt;br /&gt;testcase = unittest.FunctionTestCase(testSomething,&lt;br /&gt;setUp=makeSomethingDB,&lt;br /&gt;tearDown=deleteSomethingDB)&lt;/pre&gt;5. &lt;span style="font-family:courier new;"&gt;TestCase.setUp()&lt;/span&gt;&lt;br /&gt;This is called immediately before calling the test method; any exception raised by this method will be considered an error rather than a test failure. The default implementation does nothing.&lt;br /&gt;&lt;br /&gt;6. The methods of &lt;span style="font-family:courier new;"&gt;TestCase&lt;/span&gt; used by the test implementation to check conditions and report failures can be get &lt;a href="http://docs.python.org/library/unittest.html#unittest.TestCase.assert_"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;7. ad-hoc means that there are no installation requirements whatsoever on the remote side. (from &lt;a href="http://codespeak.net/py/trunk/test/features.html#distribute-tests-across-machines"&gt;here&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;8. By default, &lt;span style="font-family:courier new;"&gt;py.test&lt;/span&gt; catches text written to stdout/stderr during the execution of each individual test. This output will only be displayed however if the test fails, each failing test that produced output during the running of the test will have its output displayed in the &lt;span style="font-family:courier new;color:#33cc00;"&gt;recorded stdout&lt;/span&gt; section.&lt;br /&gt;&lt;br /&gt;9. Disabling a test class&lt;br /&gt;If you want to disable a complete test class you can set the class-level attribute disabled. For example, in order to avoid running some tests on Win32:&lt;br /&gt;&lt;pre style="WHITE-SPACE: pre"&gt;class TestPosixOnly:&lt;br /&gt;    disabled = sys.platform == 'win32'&lt;br /&gt;    def test_xxx(self):&lt;br /&gt;        ...&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5051690563388562347-120696886967113555?l=yangyan5.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yangyan5.blogspot.com/feeds/120696886967113555/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5051690563388562347&amp;postID=120696886967113555' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5051690563388562347/posts/default/120696886967113555'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5051690563388562347/posts/default/120696886967113555'/><link rel='alternate' type='text/html' href='http://yangyan5.blogspot.com/2009/04/notes-on-test.html' title='Notes on Test'/><author><name>Yang Yang</name><uri>http://www.blogger.com/profile/00930453836447183866</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/_LTsGMs7zsaM/STfiDSWFaRI/AAAAAAAAABM/BVh8DUe1fu8/S220/sniper33ts.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5051690563388562347.post-4669886565487548672</id><published>2009-04-20T14:47:00.000-07:00</published><updated>2009-04-20T21:51:14.211-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PSF'/><category scheme='http://www.blogger.com/atom/ns#' term='py.test'/><category scheme='http://www.blogger.com/atom/ns#' term='Snakebite'/><category scheme='http://www.blogger.com/atom/ns#' term='GSoC'/><category scheme='http://www.blogger.com/atom/ns#' term='nose'/><title type='text'>GSoC Application Accepted</title><content type='html'>It is wonderful for me to know that my application was accepted by Google Summer of Code program (&lt;a href="http://socghop.appspot.com/"&gt;GSoC&lt;/a&gt;). This summer I will work for improving &lt;a href="http://codespeak.net/py/dist/test/test.html"&gt;py.test&lt;/a&gt; compatibility with several versions of Python, especially 3k. Besides, better-formatted output of regression tests and code coverage will be shown regularly on &lt;a href="http://www.snakebite.org/"&gt;Snakebite&lt;/a&gt;. This project, accepted into Python Software Foundation (&lt;a href="http://www.python.org/psf/"&gt;PSF&lt;/a&gt;), was inspired by Titus Brown, and will be mentored by Holger Krekel. Titus and Holger have given me many precious advices and suggestions, which are greatly appreciated.&lt;br /&gt;&lt;br /&gt;There is no need to keep my proposal from public view, for it is against the spirit of open source. Thus, I paste it as following, and all comments, advices, or suggestions are welcome.&lt;br /&gt;&lt;br /&gt;----&lt;span style="font-family:lucida grande;"&gt;GSoC Application Proposal&lt;/span&gt;----&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;ABOUT ME&lt;/span&gt;&lt;br /&gt;My name is Yang Yang, a Ph.D. student in Computer Science at Michigan State University. As a teaching assistant of a Python course for nearly two years, I found that Python is such an amazing programming language that freshman can learn programming concepts effectively without being trapped in lower level details, meanwhile it is very powerful and can be used in almost everywhere. I am using Python almost every day, ranging from my research work to courses projects. Compared with C++, Python could save me lots of time in programming, thanks to its fewer alternatives and elegant coding style.&lt;br /&gt;&lt;br /&gt;I still remember the time when we were developing a P2P-VoD application using C++. We have to write our own trace function and every one took charge of testing his/her own modules. Lacking of testing experience, we had to spend excessive time on debugging. Thus, knowing that py.test is aiming to provide a powerful testing framework, I am eager to improve this tool to make it usable for Core Python3k developers. So, developers can run tests without thought and more concentrate on their own modules.&lt;br /&gt;&lt;br /&gt;This project will be my main work in this summer, and I am able to be in contact with mentors and community. Furthermore, finishing this project does not mean I already reach the destination. I will still keep in contact within PSF community and keep making my contribution.&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;CONTACT INFO&lt;/span&gt;&lt;br /&gt;email: yangyan5 AT msu DOT edu&lt;br /&gt;yangyan5 AT gmail DOT com&lt;br /&gt;cell: 517-614-6078&lt;br /&gt;IRC nick: yangyang&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;TITLE &lt;/span&gt;&lt;br /&gt;Improve Unit Testing Framework for Core Python3k&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;ABSTRACT&lt;br /&gt;&lt;/span&gt;In this project, I will make py.test compatible to Core Python3k test files and introduce some features to py.test, such that Python developers can run unit testing easier. Besides, regression test suite will be run over multiple platforms regularly on Snakebite, integrated with build-bot or other facilities.&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;SUMMARY &lt;/span&gt;&lt;br /&gt;Unit testing is very important in software development and Python has already provided a unit testing framework unittest. Although unittest supports some features such as test automation and collection, tests still cannot be run without thought, which means that we still need to register the tests we want to run. Thus, some unit testing framework arises, such as py.test and nose. py.test is already used in PyPy and it has many excellent features, such as automatically collecting and executing tests, selecting/unselecting tests by keyword, and distributing tests to multiple CPUs or machines. Similarly, nose provides a number of excellent features as well. For example, nose has the ability to run tests based on specific tags, i.e. tests can be run selectively without manually generating test suite. Besides, nose can transparently wrap tests with code coverage recording. However, the prerequisite of using these features of py.test and nose is that the tests must be discoverable and executable, which cannot be guaranteed in Core Python. Besides, py.test is still not compatible with Python3k. Thus, I plan to introduce several features that make py.test and nose compatible and convenient to run the hundreds of test files in Core Python.&lt;br /&gt;&lt;br /&gt;My effort will mainly focus on Python3k and be seven-fold. The first feature I'd like to contribute is to make py.test compatible with Python3k as well as Python2.4, which will be the basis of my later work. Second, I will provide a py.test plug-in for Python3k, Python2.6, and Python2.5 that could "understand" the conditions under which regrtest.py, the current test runner, finds and runs tests. Third, as Jython is becoming more and more popular, I plan to port the plug-in to make py.test could be used in Jython. Fourth, I will set up regular test runs for Core Python3k on Snakebite such that regression test suite across multiple platforms can be recorded and posted. And, for daily run reporting on Snakebite, I will work on integrating with build-bot or other facilities. Fifth, to help developers test their code over different version of Python, I will check the latest features of unittest.py and doctest.py of Python3k and make them compatible with previous versions of Python. Sixth, aiming to increase the test coverage in Python3k, I plan to write some test cases and report current test coverage for python modules in stdlib and list achieved improvements. Although py.test has pytest_figleaf which offers coverage report, the report is raw and needs configuration to make it useful and meaningful for developers. Last but not least, to collaborate with nose, a plug-in for py.test will be provided to invoke and run nose-style tests, which means to make py.test could discover and execute nose-style tests.&lt;br /&gt;&lt;br /&gt;Through all of my work, py.test will be made compatible with multiple versions of CPython and Jython when running regression test suite, without modifying tests too much. In addition, the regression tests and code coverage result over multiple platforms will be shown on Snakebite.&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;SCHEDULE&lt;/span&gt;&lt;br /&gt;April 20 - May 22: Get to know mentors and community. Dive into the details of py.test, regrtest.py, and nose.&lt;br /&gt;May 23 - June 7: Port py.test to Python3k, keeping compatible with Python2.4 as well.. (including debugging)&lt;br /&gt;June 8 - June 21: Write a Plug-in to make py.test compatible with regrtest of Python3k, Python2.6, and Python2.5. (including debugging)&lt;br /&gt;June 22 - June 28: Port py.test and plug-in to Jython. (including debugging)&lt;br /&gt;June 29 - July 5: Port latest features of Python3k to previous versions. (including debugging)&lt;br /&gt;July 6 - July 15: Set up regular regression test runs on Snakebite. (keeping in touch with python-dev)&lt;br /&gt;July 16 - July 26: Write test cases, report current test coverage and list achieved improvements. (keeping in touch with python-dev)&lt;br /&gt;July 27 - August 2: Write a plug-in for py.test to invoke/run nose-style tests.&lt;br /&gt;August 3 - August 10: Documentation&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;DELIVERABLES&lt;/span&gt;&lt;br /&gt;1. Port py.test to Python3k, keeping compatible with Python2.4 as well.&lt;br /&gt;2. A plug-in to make py.test compatible with regrtest of Python3k, Python2.6, and Python2.5.&lt;br /&gt;3. Port py.test and plug-in to Jython.&lt;br /&gt;4. Port latest features of Python3k to previous versions.&lt;br /&gt;5. Regression test suite regular report on Snakebite, integrated with build-bot or other facilities.&lt;br /&gt;6. Report current test coverage and list achieved improvements. The report will be developer-friendly.&lt;br /&gt;7. A plug-in for py.test to invoke/run nose-style tests.&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#33cc00;"&gt;BENEFITS TO COMMUNITY&lt;/span&gt;&lt;br /&gt;1. Make unit testing on Core Python3k and other Python versions easier by allowing developers to use py.test with some convenient features.&lt;br /&gt;2. Give developers a clear view on regression test and code coverage result over multiple platforms.&lt;br /&gt;-------&lt;span style="font-family:lucida grande;"&gt;End of Proposal&lt;/span&gt;--------&lt;br /&gt;&lt;br /&gt;The exciting and busy summer is coming!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5051690563388562347-4669886565487548672?l=yangyan5.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yangyan5.blogspot.com/feeds/4669886565487548672/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5051690563388562347&amp;postID=4669886565487548672' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5051690563388562347/posts/default/4669886565487548672'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5051690563388562347/posts/default/4669886565487548672'/><link rel='alternate' type='text/html' href='http://yangyan5.blogspot.com/2009/04/gsoc-application-accepted.html' title='GSoC Application Accepted'/><author><name>Yang Yang</name><uri>http://www.blogger.com/profile/00930453836447183866</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/_LTsGMs7zsaM/STfiDSWFaRI/AAAAAAAAABM/BVh8DUe1fu8/S220/sniper33ts.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5051690563388562347.post-2765364313507455548</id><published>2009-04-19T22:25:00.000-07:00</published><updated>2009-04-22T22:13:52.062-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='VCS'/><category scheme='http://www.blogger.com/atom/ns#' term='Mercurial'/><title type='text'>Notes on Mercurial</title><content type='html'>&lt;a href="http://www.selenic.com/mercurial/wiki/"&gt;Mercurial&lt;/a&gt; is a distributed source version control system. Compared with subversion, Mercurial is much more scalable, and everyone can commit his/her own effort. It is becoming more and more popular, and Python has switched to Mercurial recently. Here is a &lt;a href="http://hgbook.red-bean.com/"&gt;tutorial&lt;/a&gt; written by Bryan &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;O'Sullivan&lt;/span&gt; and all notes below are extracted from it.&lt;br /&gt;&lt;br /&gt;1. &lt;span style="COLOR: rgb(255,204,0);font-family:courier new;" &gt;log&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;$ &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;hg&lt;/span&gt; log -r &lt;revision&gt;[-v] [-p]&lt;/revision&gt;&lt;/span&gt;&lt;br /&gt;-v: verbose mode&lt;br /&gt;-p: show content of a change&lt;br /&gt;&lt;br /&gt;2. &lt;span style="COLOR: rgb(255,204,0);font-family:courier new;" &gt;status&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;$ &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;hg&lt;/span&gt; status&lt;/span&gt;&lt;br /&gt;Show what Mercurial knows about the files in repository.&lt;br /&gt;&lt;br /&gt;3. &lt;span style="font-family:courier new;"&gt;&lt;span style="COLOR: rgb(255,204,0)"&gt;incoming&lt;/span&gt;, &lt;span style="COLOR: rgb(255,204,0)"&gt;pull&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;, &lt;/span&gt;&lt;span style="COLOR: rgb(255,204,0);font-family:courier new;" &gt;update&lt;/span&gt;&lt;br /&gt;We use &lt;span style="font-family:courier new;"&gt;pull&lt;/span&gt; to get the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;changesets&lt;/span&gt; from "remote" repository. But, to avoid blindly fetching, we should use &lt;span style="font-family:courier new;"&gt;incoming&lt;/span&gt; first to give us a clear view of what will be transferred.&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;$ hg incoming &lt;/span&gt;&lt;span style="FONT-STYLE: italic;font-family:courier new;" &gt;remote_repository&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;$ hg pull &lt;span style="FONT-STYLE: italic;font-family:courier new;" &gt;remote_repository&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Because &lt;span style="font-family:courier new;"&gt;pull&lt;/span&gt; only bring changes into repository, we should use &lt;span style="font-family:courier new;"&gt;update&lt;/span&gt; to get a working copy. So, we should run:&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;$ hg update&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;4. &lt;span style="font-family:courier new;color:#ffcc00;"&gt;outgoing&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;, &lt;span style="color:#ffcc00;"&gt;push&lt;/span&gt;, &lt;span style="color:#ffcc00;"&gt;update&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;outgoing&lt;/span&gt; command will tell us what changes would be pushed into another repository. &lt;span style="font-family:courier new;"&gt;push&lt;/span&gt; command does the actual push. Then use &lt;span style="font-family:courier new;"&gt;update&lt;/span&gt; to get a working copy.&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;$ hg outgoing &lt;em&gt;remote_repository&lt;/em&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;$ hg push remote_repository&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;$ hg update&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;5. &lt;span style="font-family:courier new;color:#ffcc00;"&gt;heads&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;, &lt;span style="color:#ffcc00;"&gt;parents&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;We can view the heads in a &lt;span style="color:#33cc00;"&gt;repository&lt;/span&gt; using the &lt;span style="font-family:courier new;"&gt;heads&lt;/span&gt; command.&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;$ hg heads&lt;/span&gt;&lt;br /&gt;Note: heads is different with &lt;span style="font-family:courier new;"&gt;parents&lt;/span&gt;. &lt;span style="font-family:courier new;"&gt;parents&lt;/span&gt; command is used to find out what revision the &lt;span style="color:#33cc00;"&gt;working directory&lt;/span&gt; is at.&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;$ hg parents&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;6. Removing a file does not affect its history. It has only two effects:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;It removes the current version of the file from the working directory.&lt;/li&gt;&lt;li&gt;It stops Mercurial from tracking changes to the file, from the time of the next commit.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;7. Mercurial considers a file that you have deleted, but not used &lt;span style="font-family:courier new;"&gt;hg remove&lt;/span&gt; to delete, to be missing. If you deleted the missing file by accident, give &lt;span style="font-family:courier new;"&gt;hg revert&lt;/span&gt; the name of the file to recover. It will reappear, in unmodified form.&lt;/p&gt;&lt;p&gt;8. Mercurial offers a combination command, &lt;span style="font-family:courier new;"&gt;hg addremove&lt;/span&gt;, that adds untracked files and marks missing files as removed.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5051690563388562347-2765364313507455548?l=yangyan5.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yangyan5.blogspot.com/feeds/2765364313507455548/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5051690563388562347&amp;postID=2765364313507455548' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5051690563388562347/posts/default/2765364313507455548'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5051690563388562347/posts/default/2765364313507455548'/><link rel='alternate' type='text/html' href='http://yangyan5.blogspot.com/2009/04/notes-on-mercurial.html' title='Notes on Mercurial'/><author><name>Yang Yang</name><uri>http://www.blogger.com/profile/00930453836447183866</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/_LTsGMs7zsaM/STfiDSWFaRI/AAAAAAAAABM/BVh8DUe1fu8/S220/sniper33ts.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5051690563388562347.post-8086212508938770221</id><published>2009-04-17T11:08:00.000-07:00</published><updated>2009-04-17T11:29:51.103-07:00</updated><title type='text'>An interesting post "Programmer Insecurity"</title><content type='html'>Holger Krekel shared with me an &lt;a href="http://blog.red-bean.com/sussman/?p=96"&gt;interesting post&lt;/a&gt; which talks about some typical prototypes of programmers. It is so true that I found those characteristics in myself and teammates very often. For example, I thought it embarrassing me to let others see my iterative work before I reach a milestone. And the result is that I have no time to refactor my code and have to continue my work based on the fragile and awkward "code bomb". Thanks to that post, I am trying to put the advices into practice.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5051690563388562347-8086212508938770221?l=yangyan5.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yangyan5.blogspot.com/feeds/8086212508938770221/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5051690563388562347&amp;postID=8086212508938770221' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5051690563388562347/posts/default/8086212508938770221'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5051690563388562347/posts/default/8086212508938770221'/><link rel='alternate' type='text/html' href='http://yangyan5.blogspot.com/2009/04/interesting-post-programmer-insecurity.html' title='An interesting post &quot;Programmer Insecurity&quot;'/><author><name>Yang Yang</name><uri>http://www.blogger.com/profile/00930453836447183866</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/_LTsGMs7zsaM/STfiDSWFaRI/AAAAAAAAABM/BVh8DUe1fu8/S220/sniper33ts.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5051690563388562347.post-1324266089599002131</id><published>2009-04-09T10:08:00.000-07:00</published><updated>2009-04-20T10:22:26.156-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><title type='text'>Notes on Python builtin functions</title><content type='html'>Recently I have been shifting from Python2.x to Python3.x. So, all notes below are only guaranteed in Python3.x.&lt;br /&gt;&lt;br /&gt;1. &lt;span style="font-family:courier new;"&gt;&lt;span style="color: rgb(255, 204, 0);"&gt;all&lt;/span&gt;(iterable)&lt;/span&gt; and &lt;span style="font-family:courier new;"&gt;&lt;span style="color: rgb(255, 204, 0);"&gt;any&lt;/span&gt;(iterable)&lt;/span&gt;&lt;br /&gt;They are equivalent to following functions respectively:&lt;br /&gt;&lt;br /&gt;&lt;pre style="white-space: pre;"&gt;def all(iterable):&lt;br /&gt;for element in iterable:&lt;br /&gt; if not element:&lt;br /&gt;     return False&lt;br /&gt;return True&lt;/pre&gt;&lt;pre style="white-space: pre;"&gt;def any(iterable):&lt;br /&gt;for element in iterable:&lt;br /&gt; if element:&lt;br /&gt;     return True&lt;br /&gt;return False&lt;/pre&gt;2. &lt;span style="font-family:courier new;"&gt;&lt;span style="color: rgb(255, 204, 0);"&gt;bin&lt;/span&gt;(number)&lt;/span&gt; and &lt;span style="font-family:courier new;"&gt;&lt;span style="color: rgb(255, 204, 0);"&gt;hex&lt;/span&gt;(number)&lt;br /&gt;&lt;/span&gt;Convert an integer number to a binary or hexadecimal string (starts with '0b' or '0x'). The result is a valid Python expression.&lt;br /&gt;&lt;br /&gt;3. &lt;span style="font-family:courier new;"&gt;&lt;span style="color: rgb(255, 204, 0);"&gt;chr&lt;/span&gt;(i)&lt;/span&gt;&lt;br /&gt;Return the string of one character whose Unicode codepoint is the integer i. For example, &lt;span style="font-family:courier new;"&gt;chr(97)&lt;/span&gt; returns the string &lt;span style="font-family:courier new;"&gt;'a'&lt;/span&gt;. This is the inverse of &lt;span style="font-family:courier new;"&gt;ord()&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;4. &lt;span style="color: rgb(255, 204, 0);font-family:courier new;" &gt;classmethod&lt;/span&gt;&lt;br /&gt;The &lt;span style="font-family:courier new;"&gt;@classmethod&lt;/span&gt; form is a function decorator. A class method receives the class as implicit first argument, just like an instance method receives the instance. To declare a class method, use this idiom:&lt;br /&gt;&lt;br /&gt;&lt;pre style="white-space: pre;"&gt;class C:&lt;br /&gt;@classmethod&lt;br /&gt;def f(cls, arg1, arg2, ...): ...&lt;/pre&gt;It can be called either on the class (such as &lt;span style="font-family:courier new;"&gt;C.f()&lt;/span&gt;) or on an instance (such as &lt;span style="font-family:courier new;"&gt;C().f()&lt;/span&gt;). The instance is ignored except for its class. If a class method is called for a derived class, the derived class object is passed as the implied first argument. Note that class methods are different than C++ or Java static methods.&lt;br /&gt;&lt;br /&gt;5. &lt;span style="color: rgb(255, 204, 0);font-family:courier new;" &gt;delattr&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;(object, name)&lt;/span&gt;&lt;br /&gt;This is a relative of &lt;span style="font-family:courier new;"&gt;setattr()&lt;/span&gt;. The arguments are an object and a string. The string must be the name of one of the object’s attributes. The function deletes the named attribute, provided the object allows it.&lt;br /&gt;&lt;br /&gt;6. &lt;span style="font-family:courier new;"&gt;&lt;span style="color: rgb(255, 204, 0);"&gt;dir&lt;/span&gt;([object])&lt;/span&gt;&lt;br /&gt;Without arguments, return the list of names in the current local scope. With an argument, attempt to return a list of valid attributes for that object.&lt;br /&gt;&lt;br /&gt;7. &lt;span style="font-family:courier new;"&gt;&lt;span style="color: rgb(255, 204, 0);"&gt;divmod&lt;/span&gt;(a, b)&lt;/span&gt;&lt;br /&gt;Take two (non complex) numbers as arguments and return a pair of numbers consisting of their quotient and remainder.&lt;br /&gt;&lt;br /&gt;8. &lt;span style="font-family:courier new;"&gt;&lt;span style="color: rgb(255, 204, 0);"&gt;enumerate&lt;/span&gt;(iterable[, start=0])&lt;/span&gt;&lt;br /&gt;Return a tuple containing a count (from start which defaults to 0) and the corresponding value obtained from iterating over iterable.&lt;br /&gt;&lt;br /&gt;9. &lt;span style="font-family:courier new;"&gt;&lt;span style="color: rgb(255, 204, 0);"&gt;eval&lt;/span&gt;(expression[, globals[, locals]])&lt;/span&gt;, &lt;span style="font-family:courier new;"&gt;&lt;span style="color: rgb(255, 204, 0);"&gt;exec&lt;/span&gt;(object[, globals[, locals]])&lt;/span&gt;, and &lt;span style="font-family:courier new;"&gt;&lt;span style="color: rgb(255, 204, 0);"&gt;compile&lt;/span&gt;(source, filename, mode[, flags[, dont_inherit]]) &lt;/span&gt;&lt;br /&gt;Here I just show some simple examples. For more details, please check &lt;a href="http://docs.python.org/3.0/library/functions.html#compile"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;pre style="white-space: pre;"&gt;&gt;&gt;&gt; glo = {'x':5, 'y':6}&lt;br /&gt;&gt;&gt;&gt; eval('x+y', glo)&lt;br /&gt;11&lt;/pre&gt;&lt;pre style="white-space: pre;"&gt;&gt;&gt;&gt; glo = {'aList':[1,2,3]}&lt;br /&gt;&gt;&gt;&gt; exec('for i in aList: print i', glo)&lt;br /&gt;1&lt;br /&gt;2&lt;br /&gt;3&lt;/pre&gt;&lt;pre style="white-space: pre;"&gt;&gt;&gt;&gt; aString = 'for i in range(3): print i'&lt;br /&gt;&gt;&gt;&gt; aStatement = compile(aString, '', 'exec')&lt;br /&gt;&gt;&gt;&gt; exec(aStatement)&lt;br /&gt;0&lt;br /&gt;1&lt;br /&gt;2&lt;/pre&gt;Note:&lt;br /&gt;a) The built-in functions &lt;span style="font-family:courier new;"&gt;globals()&lt;/span&gt; and &lt;span style="font-family:courier new;"&gt;locals()&lt;/span&gt; return the current global and local dictionary, respectively, which may be useful to pass around for use as the second and third argument to &lt;span style="font-family:courier new;"&gt;exec()&lt;/span&gt;.&lt;br /&gt;b) &lt;span style="color: rgb(255, 204, 0);font-family:courier new;" &gt;execfile&lt;/span&gt; function is no longer used in Python3.x. Instead of &lt;span style="font-family:courier new;"&gt;&lt;span style="color: rgb(255, 204, 0);"&gt;execfile&lt;/span&gt;(fn)&lt;/span&gt; use &lt;span style="font-family:courier new;"&gt;exec(open(fn).read())&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;10. &lt;span style="font-family:courier new;"&gt;&lt;span style="color: rgb(255, 204, 0);"&gt;frozenset&lt;/span&gt;([iterable])&lt;/span&gt;&lt;br /&gt;To represent sets of sets, the inner sets must be &lt;span style="font-family:courier new;"&gt;frozenset&lt;/span&gt; objects.&lt;br /&gt;&lt;br /&gt;11. &lt;span style="font-family:courier new;"&gt;&lt;span style="color: rgb(255, 204, 0);"&gt;getattr&lt;/span&gt;(object, name[, default])&lt;/span&gt;&lt;br /&gt;Return the value of the named attributed of object. &lt;span style="font-family:courier new;"&gt;name&lt;/span&gt; must be a string. If the string is the name of one of the object’s attributes, the result is the value of that attribute. For example, &lt;span style="font-family:courier new;"&gt;getattr(x, 'foobar')&lt;/span&gt; is equivalent to &lt;span style="font-family:courier new;"&gt;x.foobar&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;12. &lt;span style="font-family:courier new;"&gt;&lt;span style="color: rgb(255, 204, 0);"&gt;hasattr&lt;/span&gt;(object, name)&lt;/span&gt;&lt;br /&gt;The arguments are an object and a string. The result is &lt;span style="font-family:courier new;"&gt;True&lt;/span&gt; if the string is the name of one of the object’s attributes, &lt;span style="font-family:courier new;"&gt;False&lt;/span&gt; if not. (This is implemented by calling &lt;span style="font-family:courier new;"&gt;getattr(object, name)&lt;/span&gt; and seeing whether it raises an exception or not.)&lt;br /&gt;&lt;br /&gt;13. &lt;span style="font-family:courier new;"&gt;&lt;span style="color: rgb(255, 204, 0);"&gt;hash&lt;/span&gt;(object)&lt;/span&gt;&lt;br /&gt;Return the hash value of the object (if it has one). Hash values are integers. They are used to quickly compare dictionary keys during a dictionary lookup. Numeric values that compare equal have the same hash value (even if they are of different types, as is the case for 1 and 1.0).&lt;br /&gt;&lt;br /&gt;14. &lt;span style="font-family:courier new;"&gt;&lt;span style="color: rgb(255, 204, 0);"&gt;id&lt;/span&gt;(object)&lt;/span&gt;&lt;br /&gt;Return the “identity” of an object. This is an integer which is guaranteed to be unique and constant for this object during its lifetime. Two objects with non-overlapping lifetimes may have the same id value. (Implementation note: this is the address of the object.)&lt;br /&gt;&lt;br /&gt;15. &lt;span style="font-family:courier new;"&gt;&lt;span style="color: rgb(255, 204, 0);"&gt;memoryview&lt;/span&gt;(obj)&lt;/span&gt;&lt;br /&gt;Return a “memory view” object created from the given argument. For example:&lt;br /&gt;&lt;pre style="white-space: pre;"&gt;&gt;&gt;&gt; data = bytearray(b'abcefg')&lt;br /&gt;&gt;&gt;&gt; v = memoryview(data)&lt;br /&gt;&gt;&gt;&gt; v.readonly&lt;br /&gt;False&lt;br /&gt;&gt;&gt;&gt; v[0] = 'z'&lt;br /&gt;&gt;&gt;&gt; data&lt;br /&gt;bytearray(b'zbcefg')&lt;br /&gt;&gt;&gt;&gt; v[1:4] = b'123'&lt;br /&gt;&gt;&gt;&gt; data&lt;br /&gt;bytearray(b'a123fg')&lt;br /&gt;&gt;&gt;&gt; v[2] = b'spam'&lt;br /&gt;Traceback (most recent call last):&lt;br /&gt;File "&lt;stdin&gt;", line 1, in &lt;module&gt;&lt;br /&gt;ValueError: cannot modify size of memoryview object&lt;/module&gt;&lt;/stdin&gt;&lt;/pre&gt;There is a tolist() method which returns the data in the buffer as a list of integers:&lt;br /&gt;&lt;pre style="white-space: pre;"&gt;&gt;&gt;&gt; memoryview(b'abc').tolist()&lt;br /&gt;[97, 98, 99]&lt;/pre&gt;16. &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span" style="color: rgb(255, 204, 0);"&gt;setattr&lt;/span&gt;(object, name, value)&lt;/span&gt; &lt;div&gt;This is the counterpart of &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;getattr()&lt;/span&gt;. The arguments are an object, a string and an arbitrary value. The string may name an existing attribute or a new attribute. The function assigns the value to the attribute, provided the object allows it.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;17. &lt;span class="Apple-style-span" style="color: rgb(255, 204, 0);"&gt;staticmethod&lt;/span&gt;&lt;/div&gt;&lt;div&gt;A static method does not receive an implicit first argument. To declare a static method, use this idiom:&lt;/div&gt;&lt;pre style="white-space: pre;"&gt;class C:&lt;br /&gt; @staticmethod&lt;br /&gt; def f(arg1, arg2, ...): ...&lt;/pre&gt;It can be called either on the class (such as &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;C.f()&lt;/span&gt;) or on an instance (such as &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;C().f()&lt;/span&gt;). The instance is ignored except for its class.&lt;br /&gt;&lt;br /&gt;18. &lt;span style="font-family:courier new;"&gt;&lt;span style="color: rgb(255, 204, 0);"&gt;vars&lt;/span&gt;([object])&lt;/span&gt;&lt;br /&gt;Without arguments, return a dictionary corresponding to the current local symbol table. With a module, class or class instance object as argument (or anything else that has a &lt;span style="font-family:courier new;"&gt;__dict__&lt;/span&gt; attribute), returns a dictionary corresponding to the object’s symbol table.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5051690563388562347-1324266089599002131?l=yangyan5.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yangyan5.blogspot.com/feeds/1324266089599002131/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5051690563388562347&amp;postID=1324266089599002131' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5051690563388562347/posts/default/1324266089599002131'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5051690563388562347/posts/default/1324266089599002131'/><link rel='alternate' type='text/html' href='http://yangyan5.blogspot.com/2009/04/notes-on-python-builtin-functions.html' title='Notes on Python builtin functions'/><author><name>Yang Yang</name><uri>http://www.blogger.com/profile/00930453836447183866</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/_LTsGMs7zsaM/STfiDSWFaRI/AAAAAAAAABM/BVh8DUe1fu8/S220/sniper33ts.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5051690563388562347.post-1074048296922479405</id><published>2009-03-30T14:47:00.000-07:00</published><updated>2009-04-20T10:23:17.054-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><category scheme='http://www.blogger.com/atom/ns#' term='nose'/><title type='text'>An annoying error</title><content type='html'>&lt;div&gt;Today I was trying to run &lt;a href="http://somethingaboutorange.com/mrl/projects/nose/"&gt;nose&lt;/a&gt; on some tests, but keeping getting this error:&lt;br /&gt;&lt;pre&gt;'import site' failed; use -v for traceback&lt;/pre&gt;At first I doubted that the problem was derived from two different versions of Python. A few days ago I downloaded and built python2.7 which is still in the trunk. When I built it, I forgot to specify the tag --prefix. So, python2.7 was installed into /usr/local/, and the python command was directed to python2.7. However, when I built nose, it was extracted into /usr/lib/python2.5/site-packages/. Thus, nose kept giving me the error above. So, I removed python2.7 (this step took me a long time because I was not familiar with the locations where python2.7 was installed.).  Guess what, I still could not run nose. I tried "python -V" to get the current version, and found that the current version was still python2.7. It turned out that I forgot to delete the binary file "python" under /usr/local/bin/. OK, I directly copy the binary file under /usr/bin/ to overwrite the one in /usr/local/bin/. And still, nose did not work. I got nearly crazy and came near to reinstall the operating system. Finally, I added two lines into .bashrc file:&lt;br /&gt;&lt;pre&gt;PYTHONPATH="/usr/lib/python2.5"&lt;br /&gt;PYTHONHOME="/usr/lib/python2.5"&lt;/pre&gt;and then rebooted the operating system (I tried source command but nose still could not work.). Thank God! Everything works fine now.&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5051690563388562347-1074048296922479405?l=yangyan5.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yangyan5.blogspot.com/feeds/1074048296922479405/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5051690563388562347&amp;postID=1074048296922479405' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5051690563388562347/posts/default/1074048296922479405'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5051690563388562347/posts/default/1074048296922479405'/><link rel='alternate' type='text/html' href='http://yangyan5.blogspot.com/2009/03/annoying-error.html' title='An annoying error'/><author><name>Yang Yang</name><uri>http://www.blogger.com/profile/00930453836447183866</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/_LTsGMs7zsaM/STfiDSWFaRI/AAAAAAAAABM/BVh8DUe1fu8/S220/sniper33ts.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5051690563388562347.post-4136418406925116609</id><published>2009-03-14T14:02:00.000-07:00</published><updated>2009-04-20T10:23:36.440-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><title type='text'>Notes &amp; tips in Python</title><content type='html'>If you really want to dive into a programming language, the best way is to read its docs. Thus, all notes below are fetched from Python2.6 Doc.&lt;br /&gt;1. Assignment to slices is also possible, and this can even change the size of the list or clear it entirely:&lt;br /&gt;&lt;br /&gt;&lt;pre style="white-space: pre;"&gt;&gt;&gt;&gt; # Replace some items:&lt;br /&gt;... a[0:2] = [1, 12]&lt;br /&gt;&gt;&gt;&gt; a&lt;br /&gt;[1, 12, 123, 1234]&lt;br /&gt;&gt;&gt;&gt; # Remove some:&lt;br /&gt;... a[0:2] = []&lt;br /&gt;&gt;&gt;&gt; a&lt;br /&gt;[123, 1234]&lt;br /&gt;&gt;&gt;&gt; # Insert some:&lt;br /&gt;... a[1:1] = ['bletch', 'xyzzy']&lt;br /&gt;&gt;&gt;&gt; a&lt;br /&gt;[123, 'bletch', 'xyzzy', 1234]&lt;br /&gt;&gt;&gt;&gt; # Insert (a copy of) itself at the beginning&lt;br /&gt;&gt;&gt;&gt; a[:0] = a&lt;br /&gt;&gt;&gt;&gt; a&lt;br /&gt;[123, 'bletch', 'xyzzy', 1234, 123, 'bletch', 'xyzzy', 1234]&lt;br /&gt;&gt;&gt;&gt; # Clear the list: replace all items with an empty list&lt;br /&gt;&gt;&gt;&gt; a[:] = []&lt;br /&gt;&gt;&gt;&gt; a&lt;br /&gt;[]&lt;/pre&gt;2. It is not safe to modify the sequence being iterated over in the loop (this can only happen for mutable sequence types, such as lists). If you need to modify the list you are iterating over (for example, to duplicate selected items) you must iterate over a copy. The slice notation makes this particularly convenient:&lt;br /&gt;&lt;br /&gt;&lt;pre style="white-space: pre;"&gt;&gt;&gt;&gt; a = ['cat', 'window', 'defenestrate']&lt;br /&gt;&gt;&gt;&gt; for x in a[:]: # make a slice copy of the entire list&lt;br /&gt;...    if len(x) &gt; 6: a.insert(0, x)&lt;br /&gt;...&lt;br /&gt;&gt;&gt;&gt; a&lt;br /&gt;['defenestrate', 'cat', 'window', 'defenestrate']&lt;/pre&gt;3. An example to show the slice of list:&lt;br /&gt;&lt;br /&gt;&lt;pre style="white-space: pre;"&gt;&gt;&gt;&gt; a = [1,2,3]&lt;br /&gt;&gt;&gt;&gt; a[:] = []&lt;br /&gt;&gt;&gt;&gt; a&lt;br /&gt;[]&lt;br /&gt;&gt;&gt;&gt; a = [1,2,3]&lt;br /&gt;&gt;&gt;&gt; b = a&lt;br /&gt;&gt;&gt;&gt; b.append(4)&lt;br /&gt;&gt;&gt;&gt; b&lt;br /&gt;[1,2,3,4]&lt;br /&gt;&gt;&gt;&gt; a&lt;br /&gt;[1,2,3,4]&lt;br /&gt;&gt;&gt;&gt; c = a[:]&lt;br /&gt;&gt;&gt;&gt; c.append(5)&lt;br /&gt;&gt;&gt;&gt; c&lt;br /&gt;[1,2,3,4,5]&lt;br /&gt;&gt;&gt;&gt; a&lt;br /&gt;[1,2,3,4]&lt;/pre&gt;4. Loop statements may have an else clause; it is executed when the loop terminates through exhaustion of the list (with for) or when the condition becomes false (with while), but not when the loop is terminated by a break statement.&lt;br /&gt;&lt;br /&gt;5. A function definition introduces the function name in the current symbol table. The value of the function name has a type that is recognized by the interpreter as a user-defined function. This value can be assigned to another name which can then also be used as a function.&lt;br /&gt;&lt;br /&gt;6. The default values are evaluated at the point of function definition in the defining scope, so that:&lt;br /&gt;&lt;br /&gt;&lt;pre style="white-space: pre;"&gt;i = 5&lt;br /&gt;&lt;br /&gt;def f(arg=i):&lt;br /&gt;print arg&lt;br /&gt;&lt;br /&gt;i = 6&lt;br /&gt;f()&lt;/pre&gt;will print 5. The default value is evaluated only once. This makes a difference when the default is a mutable object such as a list, dictionary, or instances of most classes. For example, the following function accumulates the arguments passed to it on subsequent calls:&lt;br /&gt;&lt;br /&gt;&lt;pre style="white-space: pre;"&gt;def f(a, L=[]):&lt;br /&gt;L.append(a)&lt;br /&gt;return L&lt;br /&gt;&lt;br /&gt;print f(1)&lt;br /&gt;print f(2)&lt;br /&gt;print f(3)&lt;/pre&gt;This will print:&lt;br /&gt;&lt;br /&gt;&lt;pre style="white-space: pre;"&gt;[1]&lt;br /&gt;[1, 2]&lt;br /&gt;[1, 2, 3]&lt;/pre&gt;If you don’t want the default to be shared between subsequent calls, you can write the function like this instead:&lt;br /&gt;&lt;br /&gt;&lt;pre style="white-space: pre;"&gt;def f(a, L=None):&lt;br /&gt;if L is None:&lt;br /&gt;    L = []&lt;br /&gt;L.append(a)&lt;br /&gt;return L&lt;/pre&gt;7. When the arguments are already in a list or tuple, it can be unpacked for a function call requiring separate positional arguments.&lt;br /&gt;&lt;br /&gt;&lt;pre style="white-space: pre;"&gt;&gt;&gt;&gt; range(3, 6)&lt;br /&gt;[3, 4, 5]&lt;br /&gt;&gt;&gt;&gt; args = [3, 6]&lt;br /&gt;&gt;&gt;&gt; range(*args)&lt;br /&gt;[3, 4, 5]&lt;/pre&gt;8. For Python, &lt;a href="http://www.python.org/dev/peps/pep-0008/"&gt;PEP 8&lt;/a&gt; has emerged as the style guide that most projects adhere to; it promotes a very readable and eye-pleasing coding style. Every Python developer should read it at some point; I just extract some points here:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;When possible, put comments on a line of their own.&lt;/li&gt;&lt;li&gt;Use docstrings.&lt;/li&gt;&lt;li&gt;Name your classes and functions consistently; the convention is to use &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;CamelCase&lt;/span&gt;&lt;/tt&gt; for classes and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;lower_case_with_underscores&lt;/span&gt;&lt;/tt&gt; for functions and methods.&lt;/li&gt;&lt;li&gt;Don’t use fancy encodings if your code is meant to be used in international environments. Plain ASCII works best in any case.&lt;/li&gt;&lt;/ul&gt;9. &lt;span style="font-family:courier new;"&gt;list.insert(i, x)&lt;/span&gt;&lt;br /&gt;Insert an item at a given position. The first argument is the index of the element before which to insert, so &lt;span style="font-family:courier new;"&gt;a.insert(0, x)&lt;/span&gt; inserts at the front of the list, and &lt;span style="font-family:courier new;"&gt;a.insert(len(a), x)&lt;/span&gt; is equivalent to &lt;span style="font-family:courier new;"&gt;a.append(x)&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;10. There are three built-in functions that are very useful when used with lists: &lt;span style="color: rgb(255, 204, 0);font-family:courier new;" &gt;filter()&lt;/span&gt;, &lt;span style="color: rgb(255, 204, 0);font-family:courier new;" &gt;map()&lt;/span&gt;, and &lt;span style="color: rgb(255, 204, 0);font-family:courier new;" &gt;reduce()&lt;/span&gt;.&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;filter(function, sequence) &lt;/span&gt;returns a sequence consisting of those items from the sequence for which &lt;span style="font-family:courier new;"&gt;function(item)&lt;/span&gt; is true. If sequence is a string or tuple, the result will be of the same type; otherwise, it is always a list. For example, to compute some primes:&lt;br /&gt;&lt;br /&gt;&lt;pre style="white-space: pre;"&gt;&gt;&gt;&gt; def f(x): return x % 2 != 0 and x % 3 != 0&lt;br /&gt;...&lt;br /&gt;&gt;&gt;&gt; filter(f, range(2, 25))&lt;br /&gt;[5, 7, 11, 13, 17, 19, 23]&lt;/pre&gt;&lt;span style="font-family:courier new;"&gt;map(function, sequence) &lt;/span&gt;calls &lt;span style="font-family:courier new;"&gt;function(item)&lt;/span&gt; for each of the sequence’s items and returns a list of the return values. For example, to compute some cubes:&lt;br /&gt;&lt;br /&gt;&lt;pre style="white-space: pre;"&gt;&gt;&gt;&gt; def cube(x): return x*x*x&lt;br /&gt;...&lt;br /&gt;&gt;&gt;&gt; map(cube, range(1, 11))&lt;br /&gt;[1, 8, 27, 64, 125, 216, 343, 512, 729, 1000]&lt;/pre&gt;More than one sequence may be passed; the function must then have as many arguments as there are sequences and is called with the corresponding item from each sequence (or &lt;span style="font-family:courier new;"&gt;None&lt;/span&gt; if some sequence is shorter than another). For example:&lt;br /&gt;&lt;br /&gt;&lt;pre style="white-space: pre;"&gt;&gt;&gt;&gt; seq = range(8)&lt;br /&gt;&gt;&gt;&gt; def add(x, y): return x+y&lt;br /&gt;...&lt;br /&gt;&gt;&gt;&gt; map(add, seq, seq)&lt;br /&gt;[0, 2, 4, 6, 8, 10, 12, 14]&lt;/pre&gt;&lt;span style="font-family:courier new;"&gt;reduce(function, sequence)&lt;/span&gt; returns a single value constructed by calling the binary function function on the first two items of the sequence, then on the result and the next item, and so on. For example, to compute the sum of the numbers 1 through 10:&lt;br /&gt;&lt;br /&gt;&lt;pre style="white-space: pre;"&gt;&gt;&gt;&gt; def add(x,y): return x+y&lt;br /&gt;...&lt;br /&gt;&gt;&gt;&gt; reduce(add, range(1, 11))&lt;br /&gt;55&lt;/pre&gt;11. Consider the following example of a 3x3 matrix held as a list containing three lists, one list per row:&lt;br /&gt;&lt;br /&gt;&lt;pre style="white-space: pre;"&gt;&gt;&gt;&gt; mat = [&lt;br /&gt;...        [1, 2, 3],&lt;br /&gt;...        [4, 5, 6],&lt;br /&gt;...        [7, 8, 9],&lt;br /&gt;...       ]&lt;/pre&gt;Now, if you wanted to swap rows and columns, you could use a list comprehension:&lt;br /&gt;&lt;br /&gt;&lt;pre style="white-space: pre;"&gt;&gt;&gt;&gt; print [[row[i] for row in mat] for i in [0, 1, 2]]&lt;br /&gt;[[1, 4, 7], [2, 5, 8], [3, 6, 9]]&lt;/pre&gt;In real world, you should prefer builtin functions to complex flow statements. The &lt;span style="color: rgb(255, 204, 0);font-family:courier new;" &gt;zip()&lt;/span&gt; function would do a great job for this use case:&lt;br /&gt;&lt;br /&gt;&lt;pre style="white-space: pre;"&gt;&gt;&gt;&gt; zip(*mat)&lt;br /&gt;[(1, 4, 7), (2, 5, 8), (3, 6, 9)]&lt;/pre&gt;12. the &lt;span style="color: rgb(255, 204, 0);font-family:courier new;" &gt;del&lt;/span&gt; statement differs from the &lt;span style="color: rgb(255, 204, 0);font-family:courier new;" &gt;pop()&lt;/span&gt; method which returns a value. The &lt;span style="font-family:courier new;"&gt;del&lt;/span&gt; statement can also be used to remove slices from a list or clear the entire list (which we did earlier by assignment of an empty list to the slice). For example:&lt;br /&gt;&lt;br /&gt;&lt;pre style="white-space: pre;"&gt;&gt;&gt;&gt; a = [-1, 1, 66.25, 333, 333, 1234.5]&lt;br /&gt;&gt;&gt;&gt; del a[0]&lt;br /&gt;&gt;&gt;&gt; a&lt;br /&gt;[1, 66.25, 333, 333, 1234.5]&lt;br /&gt;&gt;&gt;&gt; del a[2:4]&lt;br /&gt;&gt;&gt;&gt; a&lt;br /&gt;[1, 66.25, 1234.5]&lt;br /&gt;&gt;&gt;&gt; del a[:]&lt;br /&gt;&gt;&gt;&gt; a&lt;br /&gt;[]&lt;/pre&gt;&lt;span style="font-family:courier new;"&gt;del&lt;/span&gt; can also be used to delete entire variables:&lt;br /&gt;&lt;br /&gt;&lt;pre style="white-space: pre;"&gt;&gt;&gt;&gt; del a&lt;/pre&gt;Referencing the name a hereafter is an error (at least until another value is assigned to it). We’ll find other uses for &lt;span style="font-family:courier new;"&gt;del&lt;/span&gt; later.&lt;br /&gt;&lt;br /&gt;13. Here are some set operations:&lt;br /&gt;&lt;br /&gt;&lt;pre style="white-space: pre;"&gt;&gt;&gt;&gt; a = set('abracadabra')&lt;br /&gt;&gt;&gt;&gt; b = set('alacazam')&lt;br /&gt;&gt;&gt;&gt; a      # unique letters in a&lt;br /&gt;set(['a', 'r', 'b', 'c', 'd'])&lt;br /&gt;&gt;&gt;&gt; a - b  # letters in a but not in b&lt;br /&gt;set(['r', 'd', 'b'])&lt;br /&gt;&gt;&gt;&gt; a  b   # letters in either a or b&lt;br /&gt;set(['a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'])&lt;br /&gt;&gt;&gt;&gt; a &amp;amp; b  # letters in both a and b&lt;br /&gt;set(['a', 'c'])&lt;br /&gt;&gt;&gt;&gt; a ^ b  # letters in a or b but not both&lt;br /&gt;set(['r', 'd', 'b', 'm', 'z', 'l'])&lt;/pre&gt;14. &lt;span style="color: rgb(255, 204, 0);font-family:courier new;" &gt;enumerate&lt;/span&gt; function will return a list of tuples. The first element in each tuple is the index. For example:&lt;br /&gt;&lt;br /&gt;&lt;pre style="white-space: pre;"&gt;&gt;&gt;&gt; a = [1,2,3,4]&lt;br /&gt;&gt;&gt;&gt; for x in enumerate(a):&lt;br /&gt;...     print x&lt;br /&gt;(0, 1)&lt;br /&gt;(1, 2)&lt;br /&gt;(2, 3)&lt;br /&gt;(3, 4)&lt;br /&gt;&gt;&gt;&gt; for x, y in enumerate(a):&lt;br /&gt;...     print x, y&lt;br /&gt;0 1&lt;br /&gt;1 2&lt;br /&gt;2 3&lt;br /&gt;3 4&lt;/pre&gt;15. To loop over a sequence in reverse, first specify the sequence in a forward direction and then call the &lt;span style="color: rgb(255, 204, 0);font-family:courier new;" &gt;reversed()&lt;/span&gt; function. To loop over a sequence in sorted order, use the &lt;span style="color: rgb(255, 204, 0);font-family:courier new;" &gt;sorted()&lt;/span&gt; function which returns a new sorted &lt;span style="color: rgb(255, 204, 0);"&gt;list&lt;/span&gt; while leaving the source unaltered.&lt;br /&gt;&lt;br /&gt;16. in Python, unlike C, assignment cannot occur inside expressions. C programmers may grumble about this, but it avoids a common class of problems encountered in C programs: typing = in an expression when == was intended.&lt;br /&gt;&lt;br /&gt;17.&lt;br /&gt;&lt;pre style="white-space: pre;"&gt;from modulename import *&lt;/pre&gt;This imports all names except those beginning with an underscore (&lt;span style="font-family:courier new;"&gt;_&lt;/span&gt;).&lt;br /&gt;&lt;br /&gt;18. Modules are searched in current directory and the list of directories given by the variable &lt;span style="color: rgb(255, 204, 0);font-family:courier new;" &gt;sys.path&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;19. A program doesn’t run any faster when it is read from a .pyc or .pyo file than when it is read from a .py file; the only thing that’s faster about .pyc or .pyo files is the speed with which they are loaded.&lt;br /&gt;&lt;br /&gt;20. It is possible to have a file called spam.pyc (or spam.pyo when -O is used) without a file spam.py for the same module. This can be used to distribute a library of Python code in a form that is moderately hard to reverse engineer. The module &lt;span style="color: rgb(255, 204, 0);font-family:courier new;" &gt;compileall&lt;/span&gt; can create .pyc files (or .pyo files when -O is used) for all modules in a directory.&lt;br /&gt;&lt;br /&gt;21. The variables &lt;span style="color: rgb(255, 204, 0);font-family:courier new;" &gt;sys.ps1&lt;/span&gt; and &lt;span style="color: rgb(255, 204, 0);font-family:courier new;" &gt;sys.ps2&lt;/span&gt; define the strings used as primary and secondary prompts:&lt;br /&gt;&lt;br /&gt;&lt;pre style="white-space: pre;"&gt;&gt;&gt;&gt; import sys&lt;br /&gt;&gt;&gt;&gt; sys.ps1&lt;br /&gt;'&gt;&gt;&gt; '&lt;br /&gt;&gt;&gt;&gt; sys.ps2&lt;br /&gt;'... '&lt;br /&gt;&gt;&gt;&gt; sys.ps1 = 'C&gt; '&lt;br /&gt;C&gt; print 'Yuck!'&lt;br /&gt;Yuck!&lt;br /&gt;C&gt;&lt;/pre&gt;These two variables are only defined if the interpreter is in interactive mode.&lt;br /&gt;&lt;br /&gt;22. Without arguments, &lt;span style="color: rgb(255, 204, 0);font-family:courier new;" &gt;dir()&lt;/span&gt; lists the names you have defined currently:&lt;br /&gt;&lt;br /&gt;&lt;pre style="white-space: pre;"&gt;&gt;&gt;&gt; a = [1, 2, 3, 4, 5]&lt;br /&gt;&gt;&gt;&gt; import fibo&lt;br /&gt;&gt;&gt;&gt; fib = fibo.fib&lt;br /&gt;&gt;&gt;&gt; dir()&lt;br /&gt;['__builtins__', '__doc__', '__file__', '__name__', 'a', 'fib', 'fibo', 'sys']&lt;/pre&gt;Note that it lists all types of names: variables, modules, functions, etc. &lt;span style="color: rgb(255, 204, 0);font-family:courier new;" &gt;dir()&lt;/span&gt; does not list the names of built-in functions and variables. If you want a list of those, they are defined in the standard module &lt;span style="font-family:courier new;"&gt;__builtin__&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;23. Note that when using&lt;span style="font-family:courier new;"&gt; from package import item&lt;/span&gt;, the &lt;span style="font-family:courier new;"&gt;item&lt;/span&gt; can be either a submodule (or subpackage) of the package, or some other name defined in the package, like a function, class or variable. The import statement first tests whether the &lt;span style="font-family:courier new;"&gt;item&lt;/span&gt; is defined in the package; if not, it assumes it is a module and attempts to load it. If it fails to find it, an &lt;span style="color: rgb(255, 204, 0);font-family:courier new;" &gt;ImportError&lt;/span&gt; exception is raised.&lt;br /&gt;&lt;br /&gt;24. The import statement uses the following convention: if a package’s &lt;span style="font-family:courier new;"&gt;__init__.py&lt;/span&gt; code defines a list named &lt;span style="font-family:courier new;"&gt;__all__&lt;/span&gt;, it is taken to be the list of module names that should be imported when &lt;span style="font-family:courier new;"&gt;from package import *&lt;/span&gt; is encountered. It is up to the package author to keep this list up-to-date when a new version of the package is released. Package authors may also decide not to support it, if they don’t see a use for importing &lt;span style="font-family:courier new;"&gt;*&lt;/span&gt; from their package.&lt;br /&gt;&lt;br /&gt;25. There is another method, &lt;span style="color: rgb(255, 204, 0);font-family:courier new;" &gt;zfill()&lt;/span&gt;, which pads a numeric string on the left with zeros. It understands about plus and minus signs:&lt;br /&gt;&lt;br /&gt;&lt;pre style="white-space: pre;"&gt;&gt;&gt;&gt; '12'.zfill(5)&lt;br /&gt;'00012'&lt;br /&gt;&gt;&gt;&gt; '-3.14'.zfill(7)&lt;br /&gt;'-003.14'&lt;br /&gt;&gt;&gt;&gt; '3.14159265359'.zfill(5)&lt;br /&gt;'3.14159265359'&lt;/pre&gt;26. If the end of the file has been reached, &lt;span style="color: rgb(255, 204, 0);font-family:courier new;" &gt;f.read()&lt;/span&gt; will return an empty string (&lt;span style="font-family:courier new;"&gt;""&lt;/span&gt;).&lt;br /&gt;&lt;br /&gt;&lt;pre style="white-space: pre;"&gt;&gt;&gt;&gt; f.read()&lt;br /&gt;'This is the entire file.\n'&lt;br /&gt;&gt;&gt;&gt; f.read()&lt;br /&gt;''&lt;/pre&gt;27. &lt;span style="color: rgb(255, 204, 0);font-family:courier new;" &gt;f.tell()&lt;/span&gt; returns an integer giving the file object’s current position in the file, measured in bytes from the beginning of the file. To change the file object’s position, use &lt;span style="color: rgb(255, 204, 0);font-family:courier new;" &gt;f.seek(offset, from_what)&lt;/span&gt;. The position is computed from adding offset to a reference point; the reference point is selected by the from_what argument. A from_what value of &lt;span style="color: rgb(255, 204, 0);"&gt;0&lt;/span&gt; measures from the beginning of the file, &lt;span style="color: rgb(255, 204, 0);"&gt;1&lt;/span&gt; uses the current file position, and &lt;span style="color: rgb(255, 204, 0);"&gt;2&lt;/span&gt; uses the end of the file as the reference point. from_what can be omitted and defaults to 0, using the beginning of the file as the reference point.&lt;br /&gt;&lt;br /&gt;&lt;pre style="white-space: pre;"&gt;&gt;&gt;&gt; f = open('/tmp/workfile', 'r+')&lt;br /&gt;&gt;&gt;&gt; f.write('0123456789abcdef')&lt;br /&gt;&gt;&gt;&gt; f.seek(5)     # Go to the 6th byte in the file&lt;br /&gt;&gt;&gt;&gt; f.read(1)&lt;br /&gt;'5'&lt;br /&gt;&gt;&gt;&gt; f.seek(-3, 2) # Go to the 3rd byte before the end&lt;br /&gt;&gt;&gt;&gt; f.read(1)&lt;br /&gt;'d'&lt;/pre&gt;28. It is good practice to use the &lt;span style="color: rgb(255, 204, 0);font-family:courier new;" &gt;with&lt;/span&gt; keyword when dealing with file objects. This has the advantage that the file is properly closed after its suite finishes, even if an exception is raised on the way. It is also much shorter than writing equivalent &lt;span style="font-family:courier new;"&gt;try-finally&lt;/span&gt; blocks:&lt;br /&gt;&lt;br /&gt;&lt;pre style="white-space: pre;"&gt;&gt;&gt;&gt; with open('/tmp/workfile', 'r') as f:&lt;br /&gt;...     read_data = f.read()&lt;br /&gt;&gt;&gt;&gt; f.closed&lt;br /&gt;True&lt;/pre&gt;29. Python provides a standard module called &lt;span style="color: rgb(255, 204, 0);font-family:courier new;" &gt;pickle&lt;/span&gt;. This is an amazing module that can take almost any Python object (even some forms of Python code!), and convert it to a string representation; this process is called &lt;span style="color: rgb(51, 204, 0);"&gt;pickling&lt;/span&gt;. Reconstructing the object from the string representation is called &lt;span style="color: rgb(51, 204, 0);"&gt;unpickling&lt;/span&gt;. Between pickling and unpickling, the string representing the object may have been stored in a file or data, or sent over a network connection to some distant machine.&lt;br /&gt;If you have an object &lt;span style="font-family:courier new;"&gt;x&lt;/span&gt;, and a file object &lt;span style="font-family:courier new;"&gt;f&lt;/span&gt; that’s been opened for writing, the simplest way to pickle the object takes only one line of code:&lt;br /&gt;&lt;br /&gt;&lt;pre style="white-space: pre;"&gt;pickle.dump(x, f)&lt;/pre&gt;To unpickle the object again, if &lt;span style="font-family:courier new;"&gt;f&lt;/span&gt; is a file object which has been opened for reading:&lt;br /&gt;&lt;br /&gt;&lt;pre style="white-space: pre;"&gt;x = pickle.load(f)&lt;/pre&gt;30. A good example to show &lt;span style="color: rgb(255, 204, 0);font-family:courier new;" &gt;try-except&lt;/span&gt; block:&lt;br /&gt;&lt;br /&gt;&lt;pre style="white-space: pre;"&gt;import sys&lt;br /&gt;&lt;br /&gt;try:&lt;br /&gt;   f = open('myfile.txt')&lt;br /&gt;   s = f.readline()&lt;br /&gt;   i = int(s.strip())&lt;br /&gt;except IOError as (errno, strerror):&lt;br /&gt;   print "I/O error({0}): {1}".format(errno, strerror)&lt;br /&gt;except ValueError:&lt;br /&gt;   print "Could not convert data to an integer."&lt;br /&gt;except:&lt;br /&gt;   print "Unexpected error:", sys.exc_info()[0]&lt;br /&gt;   raise&lt;/pre&gt;31. In real world applications, the &lt;span style="color: rgb(255, 204, 0);font-family:courier new;" &gt;finally&lt;/span&gt; clause is useful for releasing external resources (such as files or network connections), regardless of whether the use of the resource was successful.&lt;br /&gt;&lt;br /&gt;32. Name spaces are created at different moments and have different lifetimes. The namespace containing the built-in names is created when the Python interpreter starts up, and is never deleted. The global namespace for a module is created when the module definition is read in; normally, module namespaces also last until the interpreter quits. The statements executed by the top-level invocation of the interpreter, either read from a script file or interactively, are considered part of a module called &lt;span style="color: rgb(255, 204, 0);font-family:courier new;" &gt;__main__&lt;/span&gt;, so they have their own global namespace.(The built-in names actually also live in a module; this is called &lt;span style="color: rgb(255, 204, 0);font-family:courier new;" &gt;__builtin__&lt;/span&gt;.)&lt;br /&gt;&lt;br /&gt;33. In &lt;span style="color: rgb(255, 204, 0);font-family:courier new;" &gt;class&lt;/span&gt;, Data attributes override method attributes with the same name.&lt;br /&gt;&lt;br /&gt;34. Derived classes may override methods of their base classes. Because methods have no special privileges when calling other methods of the same object, a method of a base class that calls another method defined in the same base class may end up calling a method of a derived class that overrides it. (For C++ programmers: all methods in Python are effectively virtual.)&lt;br /&gt;&lt;br /&gt;35. Python has two builtin functions that work with inheritance:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Use &lt;span style="color: rgb(255, 204, 0);font-family:courier new;" &gt;isinstance()&lt;/span&gt; to check an object’s type: &lt;span style="font-family:courier new;"&gt;&lt;span style="color: rgb(255, 204, 0);"&gt;isinstance(obj, int)&lt;/span&gt; &lt;/span&gt;will be True only if &lt;span style="font-family:courier new;"&gt;obj.__class__&lt;/span&gt; is &lt;span style="font-family:courier new;"&gt;int&lt;/span&gt; or some class derived from &lt;span style="font-family:courier new;"&gt;int&lt;/span&gt;.&lt;/li&gt;&lt;li&gt;Use &lt;span style="color: rgb(255, 204, 0);font-family:courier new;" &gt;issubclass()&lt;/span&gt; to check class inheritance: &lt;span style="color: rgb(255, 204, 0);font-family:courier new;" &gt;issubclass(bool, int)&lt;/span&gt; is True since &lt;span style="font-family:courier new;"&gt;bool&lt;/span&gt; is a subclass of &lt;span style="font-family:courier new;"&gt;int&lt;/span&gt;. However, &lt;span style="color: rgb(255, 204, 0);font-family:courier new;" &gt;issubclass(unicode, str)&lt;/span&gt; is False since unicode is not a subclass of &lt;span style="font-family:courier new;"&gt;str &lt;/span&gt;(they only share a common ancestor, &lt;span style="font-family:courier new;"&gt;basestring&lt;/span&gt;). &lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;36. Instance method objects have attributes, too: &lt;span style="font-family:courier new;"&gt;m.&lt;span style="color: rgb(255, 204, 0);"&gt;im_self&lt;/span&gt;&lt;/span&gt; is the instance object with the method &lt;span style="font-family:courier new;"&gt;m()&lt;/span&gt;, and &lt;span style="font-family:courier new;"&gt;m.&lt;span style="color: rgb(255, 204, 0);"&gt;im_func&lt;/span&gt;&lt;/span&gt; is the function object corresponding to the method.&lt;br /&gt;&lt;br /&gt;37. There are two new valid (semantic) forms for the &lt;span style="color: rgb(255, 204, 0);font-family:courier new;" &gt;raise&lt;/span&gt; statement:&lt;br /&gt;&lt;pre style="white-space: pre;"&gt;raise Class, instance&lt;br /&gt;&lt;br /&gt;raise instance&lt;/pre&gt;In the first form, &lt;span style="font-family:courier new;"&gt;instance&lt;/span&gt; must be an instance of &lt;span style="font-family:courier new;"&gt;Class&lt;/span&gt; or of a class derived from it. The second form is a shorthand for:&lt;br /&gt;&lt;pre style="white-space: pre;"&gt;raise instance.__class__, instance&lt;/pre&gt;38. To add iterator behavior to your classes, define a &lt;span style="color: rgb(255, 204, 0);font-family:courier new;" &gt;__iter__()&lt;/span&gt; method which returns an object with a &lt;span style="color: rgb(255, 204, 0);font-family:courier new;" &gt;next()&lt;/span&gt; method. If the class defines &lt;span style="font-family:courier new;"&gt;next()&lt;/span&gt;, then &lt;span style="font-family:courier new;"&gt;__iter__()&lt;/span&gt; can just return self:&lt;br /&gt;&lt;pre style="white-space: pre;"&gt;class Reverse:&lt;br /&gt;   "Iterator for looping over a sequence backwards"&lt;br /&gt;   def __init__(self, data):&lt;br /&gt;       self.data = data&lt;br /&gt;       self.index = len(data)&lt;br /&gt;   def __iter__(self):&lt;br /&gt;       return self&lt;br /&gt;   def next(self):&lt;br /&gt;       if self.index == 0:&lt;br /&gt;           raise StopIteration&lt;br /&gt;       self.index = self.index - 1&lt;br /&gt;       return self.data[self.index]&lt;br /&gt;&lt;br /&gt;&gt;&gt;&gt; for char in Reverse('spam'):&lt;br /&gt;...     print char&lt;br /&gt;...&lt;br /&gt;m&lt;br /&gt;a&lt;br /&gt;p&lt;br /&gt;s&lt;/pre&gt;Generators are a simple and powerful tool for creating iterators. They are written like regular functions but use the &lt;span style="color: rgb(255, 204, 0);font-family:courier new;" &gt;yield&lt;/span&gt; statement whenever they want to return data. Each time &lt;span style="font-family:courier new;"&gt;next()&lt;/span&gt; is called, the generator resumes where it left-off (it remembers all the data values and which statement was last executed). An example shows that generators can be trivially easy to create:&lt;br /&gt;&lt;pre style="white-space: pre;"&gt;def reverse(data):&lt;br /&gt;   for index in range(len(data)-1, -1, -1):&lt;br /&gt;       yield data[index]&lt;br /&gt;&lt;br /&gt;&gt;&gt;&gt; for char in reverse('golf'):&lt;br /&gt;...     print char&lt;br /&gt;...&lt;br /&gt;f&lt;br /&gt;l&lt;br /&gt;o&lt;br /&gt;g&lt;/pre&gt;The &lt;span style="font-family:courier new;"&gt;yield&lt;/span&gt; statement is only used when defining a generator function, and is only used in the body of the generator function. Using a &lt;span style="font-family:courier new;"&gt;yield&lt;/span&gt; statement in a function definition is sufficient to cause that definition to create a generator function instead of a normal function. When a generator function is called, it returns an iterator known as a generator iterator, or more commonly, a generator. The body of the generator function is executed by calling the generator’s &lt;span style="font-family:courier new;"&gt;next()&lt;/span&gt; method repeatedly until it raises an exception. When a &lt;span style="font-family:courier new;"&gt;yield&lt;/span&gt; statement is executed, the state of the generator is frozen and the value of expression_list is returned to &lt;span style="font-family:courier new;"&gt;next()'&lt;/span&gt;s caller. By "frozen" we mean that all local state is retained, including the current bindings of local variables, the instruction pointer, and the internal evaluation stack: enough information is saved so that the next time &lt;span style="font-family:courier new;"&gt;next()&lt;/span&gt; is invoked, the function can proceed exactly as if the &lt;span style="font-family:courier new;"&gt;yield&lt;/span&gt; statement were just another external call.&lt;br /&gt;&lt;br /&gt;39. Be sure to use the &lt;span style="color: rgb(255, 204, 0);font-family:courier new;" &gt;import os&lt;/span&gt; style instead of &lt;span style="font-family:courier new;"&gt;from os import *&lt;/span&gt;. This will keep &lt;span style="font-family:courier new;"&gt;os.open()&lt;/span&gt; from shadowing the builtin &lt;span style="font-family:courier new;"&gt;open()&lt;/span&gt; function which operates much differently.&lt;br /&gt;&lt;br /&gt;40. The &lt;span style="color: rgb(255, 204, 0);font-family:courier new;" &gt;glob&lt;/span&gt; module provides a function for making file lists from directory wildcard searches:&lt;br /&gt;&lt;pre style="white-space: pre;"&gt;&gt;&gt;&gt; import glob&lt;br /&gt;&gt;&gt;&gt; glob.glob("C:\\Users\\Yang\\Desktop\\*.py")&lt;br /&gt;['C:\\Users\\Yang\\Desktop\\file_preprocess.py', 'C:\\Users\\Yang\\Desktop\\htmlFunctions.py', 'C:\\Users\\Yang\\Desktop\\proj03.py', 'C:\\Users\\Yang\\Desktop\\template.py', 'C:\\Users\\Yang\\Desktop\\test.py']&lt;/pre&gt;41. The most direct way to terminate a script is to use &lt;span style="color: rgb(255, 204, 0);font-family:courier new;" &gt;sys.exit()&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;42. The &lt;span style="color: rgb(255, 204, 0);font-family:courier new;" &gt;datetime&lt;/span&gt; module supplies classes for manipulating dates and times in both simple and complex ways.&lt;br /&gt;&lt;pre style="white-space: pre;"&gt;# dates are easily constructed and formatted&lt;br /&gt;&gt;&gt;&gt; from datetime import date&lt;br /&gt;&gt;&gt;&gt; now = date.today()&lt;br /&gt;&gt;&gt;&gt; now&lt;br /&gt;datetime.date(2003, 12, 2)&lt;br /&gt;&gt;&gt;&gt; now.strftime("%m-%d-%y. %d %b %Y is a %A on the %d day of %B.")&lt;br /&gt;'12-02-03. 02 Dec 2003 is a Tuesday on the 02 day of December.'&lt;br /&gt;&lt;br /&gt;# dates support calendar arithmetic&lt;br /&gt;&gt;&gt;&gt; birthday = date(1964, 7, 31)&lt;br /&gt;&gt;&gt;&gt; age = now - birthday&lt;br /&gt;&gt;&gt;&gt; age.days&lt;br /&gt;14368&lt;/pre&gt;43. The &lt;span style="color: rgb(255, 204, 0);font-family:courier new;" &gt;textwrap&lt;/span&gt; module formats paragraphs of text to fit a given screen width:&lt;br /&gt;&lt;pre style="white-space: pre;"&gt;&gt;&gt;&gt; import textwrap&lt;br /&gt;&gt;&gt;&gt; doc = """The wrap() method is just like fill() except that it returns&lt;br /&gt;... a list of strings instead of one big string with newlines to separate&lt;br /&gt;... the wrapped lines."""&lt;br /&gt;...&lt;br /&gt;&gt;&gt;&gt; print textwrap.fill(doc, width=40)&lt;br /&gt;The wrap() method is just like fill()&lt;br /&gt;except that it returns a list of strings&lt;br /&gt;instead of one big string with newlines&lt;br /&gt;to separate the wrapped lines.&lt;/pre&gt;44. The &lt;span style="color: rgb(255, 204, 0);font-family:courier new;" &gt;locale&lt;/span&gt; module accesses a database of culture specific data formats. The grouping attribute of &lt;span style="font-family:courier new;"&gt;locale&lt;/span&gt;’s &lt;span style="color: rgb(255, 204, 0);font-family:courier new;" &gt;format&lt;/span&gt; function provides a direct way of formatting numbers with group separators:&lt;br /&gt;&lt;pre style="white-space: pre;"&gt;&gt;&gt;&gt; import locale&lt;br /&gt;&gt;&gt;&gt; locale.setlocale(locale.LC_ALL, 'English_United States.1252')&lt;br /&gt;'English_United States.1252'&lt;br /&gt;&gt;&gt;&gt; conv = locale.localeconv() # get a mapping of conventions&lt;br /&gt;&gt;&gt;&gt; x = 1234567.8&lt;br /&gt;&gt;&gt;&gt; locale.format("%d", x, grouping=True)&lt;br /&gt;'1,234,567'&lt;br /&gt;&gt;&gt;&gt; locale.format("%s%.*f", (conv['currency_symbol'],&lt;br /&gt;...        conv['frac_digits'], x), grouping=True)&lt;br /&gt;'$1,234,567.80'&lt;/pre&gt;45. The following code shows how the high level &lt;span style="color: rgb(255, 204, 0);font-family:courier new;" &gt;threading&lt;/span&gt; module can run tasks in background while the main program continues to run:&lt;br /&gt;&lt;pre style="white-space: pre;"&gt;import threading, zipfile&lt;br /&gt;&lt;br /&gt;class AsyncZip(threading.Thread):&lt;br /&gt;   def __init__(self, infile, outfile):&lt;br /&gt;       threading.Thread.__init__(self)&lt;br /&gt;       self.infile = infile&lt;br /&gt;       self.outfile = outfile&lt;br /&gt;   def run(self):&lt;br /&gt;       f = zipfile.ZipFile(self.outfile, 'w', zipfile.ZIP_DEFLATED)&lt;br /&gt;       f.write(self.infile)&lt;br /&gt;       f.close()&lt;br /&gt;       print 'Finished background zip of: ', self.infile&lt;br /&gt;&lt;br /&gt;background = AsyncZip('mydata.txt', 'myarchive.zip')&lt;br /&gt;background.start()&lt;br /&gt;print 'The main program continues to run in foreground.'&lt;br /&gt;&lt;br /&gt;background.join() # Wait for the background task to finish&lt;br /&gt;print 'Main program waited until background was done.'&lt;/pre&gt;While those tools are powerful, minor design errors can result in problems that are difficult to reproduce. So, the preferred approach to task coordination is to concentrate all access to a resource in a single thread and then use the &lt;span style="color: rgb(255, 204, 0);font-family:courier new;" &gt;Queue&lt;/span&gt; module to feed that thread with requests from other threads. Applications using &lt;span style="color: rgb(255, 204, 0);font-family:courier new;" &gt;Queue.Queue&lt;/span&gt; objects for inter-thread communication and coordination are easier to design, more readable, and more reliable.&lt;br /&gt;&lt;br /&gt;46. The &lt;span style="color: rgb(255, 204, 0);font-family:courier new;" &gt;array&lt;/span&gt; module provides an &lt;span style="color: rgb(255, 204, 0);font-family:courier new;" &gt;array()&lt;/span&gt; object that is like a list that stores only &lt;span style="color: rgb(51, 204, 0);"&gt;homogeneous&lt;/span&gt; data and stores it more compactly. The following example shows an array of numbers stored as two byte unsigned binary numbers (typecode "H") rather than the usual 16 bytes per entry for regular lists of python int objects:&lt;br /&gt;&lt;pre style="white-space: pre;"&gt;&gt;&gt;&gt; from array import array&lt;br /&gt;&gt;&gt;&gt; a = array('H', [4000, 10, 700, 22222])&lt;br /&gt;&gt;&gt;&gt; sum(a)&lt;br /&gt;26932&lt;br /&gt;&gt;&gt;&gt; a[1:3]&lt;br /&gt;array('H', [10, 700])&lt;/pre&gt;47. The &lt;span style="color: rgb(255, 204, 0);font-family:courier new;" &gt;collections&lt;/span&gt; module provides a &lt;span style="color: rgb(255, 204, 0);font-family:courier new;" &gt;deque()&lt;/span&gt; object that is like a list with faster appends and pops from the left side but slower lookups in the middle. These objects are well suited for implementing queues and breadth first tree searches:&lt;br /&gt;&lt;pre style="white-space: pre;"&gt;&gt;&gt;&gt; from collections import deque&lt;br /&gt;&gt;&gt;&gt; d = deque(["task1", "task2", "task3"])&lt;br /&gt;&gt;&gt;&gt; d.append("task4")&lt;br /&gt;&gt;&gt;&gt; print "Handling", d.popleft()&lt;br /&gt;Handling task1&lt;br /&gt;&lt;br /&gt;unsearched = deque([starting_node])&lt;br /&gt;def breadth_first_search(unsearched):&lt;br /&gt;   node = unsearched.popleft()&lt;br /&gt;   for m in gen_moves(node):&lt;br /&gt;       if is_goal(m):&lt;br /&gt;           return m&lt;br /&gt;       unsearched.append(m)&lt;/pre&gt;48. The &lt;span style="color: rgb(255, 204, 0);font-family:courier new;" &gt;heapq&lt;/span&gt; module provides functions for implementing heaps based on regular lists. The lowest valued entry is always kept at position zero. This is useful for applications which repeatedly access the smallest element but do not want to run a full list sort:&lt;br /&gt;&lt;pre style="white-space: pre;"&gt;&gt;&gt;&gt; from heapq import heapify, heappop, heappush&lt;br /&gt;&gt;&gt;&gt; data = [1, 3, 5, 7, 9, 2, 4, 6, 8, 0]&lt;br /&gt;&gt;&gt;&gt; heapify(data)                      # rearrange the list into heap order&lt;br /&gt;&gt;&gt;&gt; heappush(data, -5)                 # add a new entry&lt;br /&gt;&gt;&gt;&gt; [heappop(data) for i in range(3)]  # fetch the three smallest entries&lt;br /&gt;[-5, 0, 1]&lt;/pre&gt;49. Non-identical instances of a class normally compare as non-equal unless the class defines the &lt;span style="font-family:courier new;"&gt;&lt;span style="color: rgb(255, 204, 0);"&gt;__eq__&lt;/span&gt;()&lt;/span&gt; method.&lt;br /&gt;&lt;br /&gt;50. &lt;span style="font-family:courier new;"&gt;int.&lt;span style="color: rgb(255, 204, 0);"&gt;bit_length&lt;/span&gt;()&lt;/span&gt; returns the number of bits necessary to represent an integer in binary, excluding the sign and leading zeros:&lt;br /&gt;&lt;pre style="white-space: pre;"&gt;&gt;&gt;&gt; n = -37&lt;br /&gt;&gt;&gt;&gt; bin(n)&lt;br /&gt;'-0b100101'&lt;br /&gt;&gt;&gt;&gt; n.bit_length()&lt;br /&gt;6&lt;/pre&gt;51. &lt;span style="font-family:courier new;"&gt;str.&lt;span style="color: rgb(255, 204, 0);"&gt;partition&lt;/span&gt;(sep)&lt;/span&gt;&lt;br /&gt;Split the string at the &lt;span style="color: rgb(51, 204, 0);"&gt;first&lt;/span&gt; occurrence of &lt;span style="font-family:courier new;"&gt;sep&lt;/span&gt;, and return a 3-tuple containing the part before the separator, the separator itself, and the part after the separator. If the separator is not found, return a 3-tuple containing the string itself, followed by two empty strings.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5051690563388562347-4136418406925116609?l=yangyan5.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yangyan5.blogspot.com/feeds/4136418406925116609/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5051690563388562347&amp;postID=4136418406925116609' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5051690563388562347/posts/default/4136418406925116609'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5051690563388562347/posts/default/4136418406925116609'/><link rel='alternate' type='text/html' href='http://yangyan5.blogspot.com/2009/03/1.html' title='Notes &amp;amp; tips in Python'/><author><name>Yang Yang</name><uri>http://www.blogger.com/profile/00930453836447183866</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/_LTsGMs7zsaM/STfiDSWFaRI/AAAAAAAAABM/BVh8DUe1fu8/S220/sniper33ts.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5051690563388562347.post-6902161725926491428</id><published>2008-12-04T06:33:00.000-08:00</published><updated>2008-12-04T06:55:58.082-08:00</updated><title type='text'>Why my blog's name is Spartan Sniper?</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_LTsGMs7zsaM/STft293ogvI/AAAAAAAAABw/vVVP1aAPyp8/s1600-h/sparty.jpg"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 235px; height: 314px;" src="http://1.bp.blogspot.com/_LTsGMs7zsaM/STft293ogvI/AAAAAAAAABw/vVVP1aAPyp8/s320/sparty.jpg" alt="" id="BLOGGER_PHOTO_ID_5275947017064448754" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Sparty is the mascot of Michigan State University, and we call us spartans, which shows strong laconophilia. For sniper, I am a fan of Counter-Strike, and I am very good at using AWP. Hmmm, well I was. But I still think AWP is the most beautiful weapon. That's why I pick Spartan Sniper as my blog's name.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5051690563388562347-6902161725926491428?l=yangyan5.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yangyan5.blogspot.com/feeds/6902161725926491428/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5051690563388562347&amp;postID=6902161725926491428' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5051690563388562347/posts/default/6902161725926491428'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5051690563388562347/posts/default/6902161725926491428'/><link rel='alternate' type='text/html' href='http://yangyan5.blogspot.com/2008/12/why-my-blogs-name-is-spartan-sniper.html' title='Why my blog&apos;s name is Spartan Sniper?'/><author><name>Yang Yang</name><uri>http://www.blogger.com/profile/00930453836447183866</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/_LTsGMs7zsaM/STfiDSWFaRI/AAAAAAAAABM/BVh8DUe1fu8/S220/sniper33ts.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_LTsGMs7zsaM/STft293ogvI/AAAAAAAAABw/vVVP1aAPyp8/s72-c/sparty.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5051690563388562347.post-8463771367491582079</id><published>2008-12-04T06:00:00.000-08:00</published><updated>2008-12-04T06:29:18.600-08:00</updated><title type='text'>The first post on this blog</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_LTsGMs7zsaM/STfpHlkZYRI/AAAAAAAAABo/3x-xdGOIgH0/s1600-h/albert-einstein.jpg"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 246px; height: 320px;" src="http://1.bp.blogspot.com/_LTsGMs7zsaM/STfpHlkZYRI/AAAAAAAAABo/3x-xdGOIgH0/s320/albert-einstein.jpg" alt="" id="BLOGGER_PHOTO_ID_5275941805040951570" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Hello, This is Yang. I am a Ph.D. student in Computer Science and Engineering Department of Michigan State University. Google provides so many interesting stuff, so I think creating a blog on Google can take advantage of these stuff seamlessly. This is my first blog in English, which blocks me very much to express my train of thought effectively. So I don't plan to write a novel or poem here except some sketches of what I am interested in or what I encountered. Thank you all and Merry Christmas. God bless the world.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5051690563388562347-8463771367491582079?l=yangyan5.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yangyan5.blogspot.com/feeds/8463771367491582079/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5051690563388562347&amp;postID=8463771367491582079' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5051690563388562347/posts/default/8463771367491582079'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5051690563388562347/posts/default/8463771367491582079'/><link rel='alternate' type='text/html' href='http://yangyan5.blogspot.com/2008/12/first-post-on-this-blog.html' title='The first post on this blog'/><author><name>Yang Yang</name><uri>http://www.blogger.com/profile/00930453836447183866</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/_LTsGMs7zsaM/STfiDSWFaRI/AAAAAAAAABM/BVh8DUe1fu8/S220/sniper33ts.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_LTsGMs7zsaM/STfpHlkZYRI/AAAAAAAAABo/3x-xdGOIgH0/s72-c/albert-einstein.jpg' height='72' width='72'/><thr:total>0</thr:total></entry></feed>
