<?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-7979054</id><updated>2011-11-27T15:18:38.593-08:00</updated><title type='text'>Yue Zhang - Techlog</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>88</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7979054.post-8732047845304969178</id><published>2011-07-16T04:36:00.000-07:00</published><updated>2011-07-16T04:45:45.541-07:00</updated><title type='text'>SRILM note: the use of MACHINE_TYPE for customized compilation</title><content type='html'>SRILM supports compilation for different architectures by the MACHINE_TYPE variable. By default, MACHINE_TYPE is defined automatically. However, for special purposes, such as 64 bit support, MACHINE_TYPE can be manually specified. For a particular machine type x (i.e. i686, i686-m64, i686-gcc4), the corresponding compiler options are defined in common/Makefile.machine.x. When running 'make MACHINE_TYPE=x', a separate folder x will be created under bin, lib, lm/obj, dstruct/obj and other folders. The fact can be taken advantage of when making a specific compilation of the code. For example, suppose that we want to compile a position independent version of srilm for sharing. We can do this by copying one machine specific makefile, such as Makefile.machine.i686, to Makefile.machine.foo. Then we can modify the compiler flag of foo, adding what we need. For this particular case, it is -fPIC. Then we compile srilm by 'make MACHINE_TYPE=foo'. The resulting objects, such as liboolm.a, will be placed at lib/foo. This is handy since it does not clash with existing libraries and binaries.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-8732047845304969178?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/8732047845304969178/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=8732047845304969178' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/8732047845304969178'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/8732047845304969178'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2011/07/srilm-note-use-of-machinetype-for.html' title='SRILM note: the use of MACHINE_TYPE for customized compilation'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-3273133175640684146</id><published>2011-07-08T06:48:00.000-07:00</published><updated>2011-07-08T07:03:00.660-07:00</updated><title type='text'>OpenOffice Note: selecting all footnotes</title><content type='html'>The current version of OpenOffice writer does not directly support the extracting of all footnotes, but there are ways to get around this. First, footnotes can be selected by Edit | Find &amp; Replace ..., and then choosing More Options, and ticking Search for Styles below. Choose Footnote as the style in the drop down list above, then press the button Find All. All foot notes will be highlighted, and then can be copied into clipboard. Second, when trying to paste the selected footnotes into a target file, it turns out that all new lines after footnotes are gone. This can be solved by the following trick. &lt;br /&gt;&lt;br /&gt;(1) In the original document from which footnotes are extracted, select all footnotes in the aforementioned way.&lt;br /&gt;&lt;br /&gt;(2) (Assuming that each footnote ends with a period) remove trailing space characters (if any) by using Find and Replace, ticking Current Selection Only and Regular Expression in More Options. Find all patterns: [ ]+$ (note the space between [ and ]) and replacing them with an empty string (by emptying textbox). &lt;br /&gt;&lt;br /&gt;(3) Again select all footnotes in that document, and then use the same method is the previous step to replace pattern \.$ with .ENDOFPARAGRAPH. The special word ENDOFPARAGRAPH is used as a placeholder for newline. &lt;br /&gt;&lt;br /&gt;(4) Use the method mentioned before to select all footnotes again now, and copy them and paste them into a new document.&lt;br /&gt;&lt;br /&gt;(5) from the new document, use Find and Replace to replace all ENDOFPARAGRAH with \n, ticking Find Regular Expression under MoreOptions. &lt;br /&gt;&lt;br /&gt;That will do the extraction. Use an Undo step to undo the insertion of placeholder words in the original document. Or simply replace them again with ''.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-3273133175640684146?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/3273133175640684146/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=3273133175640684146' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/3273133175640684146'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/3273133175640684146'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2011/07/openoffice-note-selecting-all-footnotes.html' title='OpenOffice Note: selecting all footnotes'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-2964937833384863690</id><published>2011-06-18T04:05:00.000-07:00</published><updated>2011-06-18T04:18:08.584-07:00</updated><title type='text'>C++ note: commas and brackets in a macro</title><content type='html'>Sometimes it's handy to use a macro to avoid repeated writing of similar code, especially when there is no direct way to modularize some apparently similar but essentially very different functions. In such uses of macros it often occurs that commas and brackets need to be included in the macro. Direct inclusion of commas and brackets may confuse the compiler. &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#define example_macros(left_code, right_code)\&lt;br /&gt;left_code a right_code\&lt;br /&gt;left_code b right_code\&lt;br /&gt;left_code c right_code\&lt;br /&gt;...&lt;br /&gt;left_code z right_code&lt;br /&gt;&lt;br /&gt;void func_1() {&lt;br /&gt;   example_macros( my_module1.call( , ); );&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void func_2() {&lt;br /&gt;   example_macros( cout&lt;&lt; , &lt;&lt;(endl); );&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;When the usage become more complex, particularly when there are more arguments to macro, commas and brackets may confuse the macro. The bets solution I have found is using extra macros. &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#define id_comma ,&lt;br /&gt;#define id_left_bracket (&lt;br /&gt;#define id_right_bracket )&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;and then replace the usage of commas and brackets in macros&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;void func_1() {&lt;br /&gt;   example_macros( my_module1.call id_left_bracket , id_right_brackt ; );&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This will avoid any confusion.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-2964937833384863690?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/2964937833384863690/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=2964937833384863690' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/2964937833384863690'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/2964937833384863690'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2011/06/c-note-commas-and-brackets-in-macro.html' title='C++ note: commas and brackets in a macro'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-7419171682795883766</id><published>2011-03-02T07:45:00.001-08:00</published><updated>2011-03-02T07:46:42.326-08:00</updated><title type='text'>Bash note: get the path for the running script</title><content type='html'>The following expression returns the path the currently running script is from (note that the script might not be from pwd):&lt;br /&gt;&lt;br /&gt;$(cd `dirname $0` &amp;&amp; pwd)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-7419171682795883766?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/7419171682795883766/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=7419171682795883766' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/7419171682795883766'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/7419171682795883766'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2011/03/bash-note-get-path-for-running-script.html' title='Bash note: get the path for the running script'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-4622575058253939337</id><published>2011-01-20T06:12:00.000-08:00</published><updated>2011-01-20T06:16:12.080-08:00</updated><title type='text'>Python note: breaking a long statement to add end of line comments</title><content type='html'>There is a very simple tip for breaking a long line in order to add end comments. Python doesn't recognize arbitrary broken lines, but it allows lines to be broken if the line is inside a bracket so it is unambiguous. The following code&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;if condition1 and # comment1&lt;br /&gt;   condition2: # comment2&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;would not work because a line is broken in the if statement, however, &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;if (condition1 and #comment1&lt;br /&gt;    condition2): # comment2&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;would fix the problem and maintain neat code.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-4622575058253939337?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/4622575058253939337/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=4622575058253939337' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/4622575058253939337'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/4622575058253939337'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2011/01/python-note-breaking-long-statement-to.html' title='Python note: breaking a long statement to add end of line comments'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-9056137440816224176</id><published>2011-01-20T04:33:00.001-08:00</published><updated>2011-01-20T04:46:55.594-08:00</updated><title type='text'>Python note: set equality test</title><content type='html'>Given a class with an __eq__ function, would a python set contain only members that are equal? The answer is not necessarily.&lt;br /&gt;&lt;br /&gt;Consider the following class:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class C(object):&lt;br /&gt;   def __init__(self, x):&lt;br /&gt;      self.a = x&lt;br /&gt;   def __eq__(self, o):&lt;br /&gt;      return self.a == o.a&lt;br /&gt;   def __str__(self):&lt;br /&gt;      return str(self.a)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;It defines a member which controls its equality. However, the following code will add four members to the set &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;s = set()&lt;br /&gt;a = C(1)&lt;br /&gt;b = C(2)&lt;br /&gt;c = C(3)&lt;br /&gt;s.add(a)&lt;br /&gt;s.add(b)&lt;br /&gt;s.add(c)&lt;br /&gt;s.add(C(1))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The main reason is that set is implemented as a hash map, and without a hash function defined in the class C, python will use the object identity itself for hashing, and members of the class will be hashed into different places. The following code will fix the problem. &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class C(object):&lt;br /&gt;   def __init__(self, x):&lt;br /&gt;      self.a = x&lt;br /&gt;   def __eq__(self, o):&lt;br /&gt;      return self.a == o.a&lt;br /&gt;   def __str__(self):&lt;br /&gt;      return str(self.a)&lt;br /&gt;   def __hash__(self):&lt;br /&gt;      return self.a&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/7979054-9056137440816224176?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/9056137440816224176/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=9056137440816224176' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/9056137440816224176'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/9056137440816224176'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2011/01/python-note-set-equality-test.html' title='Python note: set equality test'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-537196432813068245</id><published>2011-01-18T08:08:00.000-08:00</published><updated>2011-01-18T08:14:37.795-08:00</updated><title type='text'>grep note: find all words that contains a particular substring</title><content type='html'>I used:&lt;br /&gt;grep -h substring path/*.txt | tr ' ' '\n' | grep substring&lt;br /&gt;&lt;span style="font-style:italic;"&gt;&lt;br /&gt;grep substring path/*.txt&lt;/span&gt; will list the files plus the matching lines. &lt;br /&gt;&lt;span style="font-style:italic;"&gt;&lt;br /&gt;grep -h substring path/*.txt&lt;/span&gt; will remove the names of the matching files, leaving only lines. &lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;grep -h substring path/*.txt | tr ' ' '\n'&lt;/span&gt; will translate the matching lines into a word-per-line form. &lt;br /&gt;&lt;br /&gt;g&lt;span style="font-style:italic;"&gt;rep -h substring path/*.txt | tr ' ' '\n' | grep substring&lt;/span&gt; will then filter the words that do not contain the pattern from the lines. &lt;br /&gt;&lt;br /&gt;I also wanted a list of unique words that contained the substring, and therefore piped the previous command into sort and uniq.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-537196432813068245?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/537196432813068245/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=537196432813068245' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/537196432813068245'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/537196432813068245'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2011/01/grep-note-find-all-words-that-contains.html' title='grep note: find all words that contains a particular substring'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-1895412078361619567</id><published>2010-11-09T09:41:00.001-08:00</published><updated>2010-11-09T09:42:25.330-08:00</updated><title type='text'>C++ note: pure virtual method called</title><content type='html'>The first thing to check is whether virtual functions are called from constructor.&lt;br /&gt;http://www.artima.com/cppsource/pure_virtual.html&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-1895412078361619567?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/1895412078361619567/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=1895412078361619567' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/1895412078361619567'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/1895412078361619567'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2010/11/c-note-pure-virtual-method-called.html' title='C++ note: pure virtual method called'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-5126388264441332418</id><published>2010-10-30T08:57:00.000-07:00</published><updated>2010-10-30T09:01:45.166-07:00</updated><title type='text'>C++ note: static variable from inline member function</title><content type='html'>I was thinking about Meyers singleton, and wonder how compilers will handle the same static variable defined in difference modules due to inline function expansion. Here are some relevant discussions (it occurs safe not to use the kind of singleton(?)). &lt;br /&gt;&lt;br /&gt;http://objectmix.com/c/250462-static-local-variable-inline-static-member-function.html&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-5126388264441332418?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/5126388264441332418/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=5126388264441332418' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/5126388264441332418'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/5126388264441332418'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2010/10/c-note-static-variable-from-inline.html' title='C++ note: static variable from inline member function'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-5799390847881694956</id><published>2010-10-13T06:42:00.000-07:00</published><updated>2010-10-13T06:53:57.569-07:00</updated><title type='text'>Sh note: adding a line at the front of files</title><content type='html'>The example script adds a new line to the beginning of each file in the directory, recursively, except those files that contain svn.&lt;br /&gt;&lt;br /&gt;for file in `find . -type f | grep -v 'svn'`;&lt;br /&gt;do&lt;br /&gt;  sed '1i\New line' -i $file&lt;br /&gt;done&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-5799390847881694956?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/5799390847881694956/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=5799390847881694956' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/5799390847881694956'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/5799390847881694956'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2010/10/sh-note-adding-line-before-each-file.html' title='Sh note: adding a line at the front of files'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-3719074703486443904</id><published>2010-10-12T07:49:00.000-07:00</published><updated>2010-10-12T07:52:18.843-07:00</updated><title type='text'>Sh note: reversing a file or a line</title><content type='html'>rev can be used to reverse a line character by character&lt;br /&gt;tac can be used to reverse a file line by line&lt;br /&gt;these two commands are sometimes handy&lt;br /&gt;&lt;br /&gt;sh$ rev&lt;br /&gt;abc&lt;br /&gt;cba&lt;br /&gt;&lt;br /&gt;sh$ tac&lt;br /&gt;a&lt;br /&gt;b&lt;br /&gt;c^D&lt;br /&gt;c&lt;br /&gt;b&lt;br /&gt;a&lt;br /&gt;&lt;br /&gt;echo abcde | rev&lt;br /&gt;&lt;br /&gt;a particular context I used tac&lt;br /&gt;ls /corpora/extra/nivre/corpus/conll-x/data/turkish/metu_sabanci/*/*.conll | cut -d '/' -f8-11 | tac&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-3719074703486443904?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/3719074703486443904/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=3719074703486443904' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/3719074703486443904'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/3719074703486443904'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2010/10/sh-note-reversing-file-or-line.html' title='Sh note: reversing a file or a line'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-2693811756216503794</id><published>2010-03-17T08:43:00.000-07:00</published><updated>2010-03-17T08:46:30.183-07:00</updated><title type='text'>C++ note: enabling and disabling assert</title><content type='html'>In C++, assert is by default compiled. To exclude it, the macro NDEBUG must be defined when assert.h is included. This can be done by using -DNDEBUG compiler option or #define NDEBUG in code.&lt;br /&gt;&lt;br /&gt;gcc -DNDEBUG -c test.cpp -o test.o&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-2693811756216503794?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/2693811756216503794/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=2693811756216503794' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/2693811756216503794'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/2693811756216503794'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2010/03/c-note-enabling-and-disabling-assert.html' title='C++ note: enabling and disabling assert'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-7038069232307812410</id><published>2009-11-09T08:13:00.000-08:00</published><updated>2010-03-17T08:47:48.441-07:00</updated><title type='text'>LaTeX note: two columns</title><content type='html'>To make a new page with two columns:&lt;br /&gt;&lt;br /&gt;\begin{twocolumns}&lt;br /&gt;...&lt;br /&gt;\end{twocolumns}&lt;br /&gt;&lt;br /&gt;Two columnns at the same page&lt;br /&gt;&lt;br /&gt;\begin{multicols}{2}&lt;br /&gt;...&lt;br /&gt;\end{multicols}&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-7038069232307812410?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/7038069232307812410/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=7038069232307812410' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/7038069232307812410'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/7038069232307812410'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2009/11/latex-note-two-columns.html' title='LaTeX note: two columns'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-7518309474923936939</id><published>2009-08-24T14:37:00.000-07:00</published><updated>2009-08-26T07:08:34.035-07:00</updated><title type='text'>Linux note: recursive replacement</title><content type='html'>This is a script to recursively do pattern replacing with dir&lt;br /&gt;&lt;br /&gt;-----------------------------------&lt;br /&gt;if [ $# -ne 3 ]&lt;br /&gt;then&lt;br /&gt;        echo 'Usage: replace.sh dir pattern1 pattern2'&lt;br /&gt;        exit 85&lt;br /&gt;fi&lt;br /&gt;&lt;br /&gt;for f in `grep -rl $2 $1`;&lt;br /&gt;do&lt;br /&gt;        sed "s/$2/$3/g" -i $f&lt;br /&gt;done&lt;br /&gt;--------------------------------------&lt;br /&gt;&lt;br /&gt;$1 is the directory, $2 is the pattern to be replaced and $3 is the new pattern. This script iterates through all files in directory. Filtering can be done by changing the for loop into a detailed list of files.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-7518309474923936939?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/7518309474923936939/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=7518309474923936939' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/7518309474923936939'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/7518309474923936939'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2009/08/linux-note-recursive-sed.html' title='Linux note: recursive replacement'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-953464384592888167</id><published>2009-04-21T07:46:00.000-07:00</published><updated>2009-06-18T12:35:41.933-07:00</updated><title type='text'>C++ note: using a functor to help organise a vector of pointers</title><content type='html'>Suppose that some large structures need to be managed by using a heap. There is no limitation to the number of items, and therefore a vector is used to maintain the memory. Because they are organised in a heap, direct heap operation on the memory vector is slow. Therefore, another vector is used to store the indice.&lt;br /&gt;&lt;br /&gt;template&amp;lt;cnode&amp;gt; myClass{&lt;br /&gt;vector&amp;lt;cnode&amp;gt; memory;&lt;br /&gt;vector&amp;lt;unsigned&amp;gt; indice;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Now the indice vector must store indice (unsigned) rather than pointers (CNode*). This is because when the memory vector is reallocated, the original pointers to the memory are invalid. Using pointer vectors will lead to segmentation-fault.&lt;br /&gt;&lt;br /&gt;Pushing and popping heap operations can now be carried out on the indice. They should rely on node comparison. The standard node comparison function should read like:&lt;br /&gt;&lt;br /&gt;// in myClass&lt;br /&gt;bool less(const unsigned x, const unsigned y) { return memory[x] &amp;lt; memory[y]; }&lt;br /&gt;&lt;br /&gt;The above code does not compile, because push_back and pop_back in std require a function with the signature less(x, y). A member function doesn't work. A solution is the functor.&lt;br /&gt;&lt;br /&gt;struct CNodeLess {&lt;br /&gt; const vector&amp;lt;CNode&amp;gt; *memory;&lt;br /&gt; CNodeLess(const vector&amp;lt;CNode&amp;gt; &amp;amp;bm): memory(&amp;amp;bm) {}&lt;br /&gt; bool operator()(const unsigned &amp;amp;x, const unsigned &amp;amp;y) { return (memory[x] &amp;lt; memory[y]); }&lt;br /&gt;&lt;br /&gt;Now the class can have a member in CNodeLess that caches the memory, and provide the less(x,y) signature.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-953464384592888167?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/953464384592888167/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=953464384592888167' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/953464384592888167'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/953464384592888167'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2009/04/c-note-functor.html' title='C++ note: using a functor to help organise a vector of pointers'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-1647356683173477690</id><published>2008-12-11T08:33:00.000-08:00</published><updated>2008-12-11T08:35:43.273-08:00</updated><title type='text'>Linux note: grep command</title><content type='html'>To grep multiple patterns from a file&lt;br /&gt;&lt;br /&gt;grep -E "patternone|patterntwo" file&lt;br /&gt;&lt;br /&gt;The option -E is to enable extended posix regular-expression (|). The quotation marks are to prevent the shell from taking | for pipe.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-1647356683173477690?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/1647356683173477690/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=1647356683173477690' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/1647356683173477690'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/1647356683173477690'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2008/12/linux-note-grep-command.html' title='Linux note: grep command'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-6872674211384689724</id><published>2008-09-26T12:56:00.000-07:00</published><updated>2008-09-26T13:04:21.747-07:00</updated><title type='text'>Java note: toarray</title><content type='html'>Because of the implementation of containers, the contained type cannot be instantiated within them. An inconvenient consequence is toArray. There are two ways to call it&lt;br /&gt;&lt;br /&gt;1.&lt;br /&gt;Object arr[] = list.toArray();&lt;br /&gt;&lt;br /&gt;But it's not easy to change Object[] to Type[].&lt;br /&gt;&lt;br /&gt;2.&lt;br /&gt;Type arr[] = new Type[m];&lt;br /&gt;list.toArray(arr);&lt;br /&gt;&lt;br /&gt;But it would be much better not to have to allocate arr separately.&lt;br /&gt;&lt;br /&gt;The next version of Java should really reconsider the implementation of templates.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-6872674211384689724?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/6872674211384689724/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=6872674211384689724' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/6872674211384689724'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/6872674211384689724'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2008/09/java-note-toarray.html' title='Java note: toarray'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-4584183353830075499</id><published>2008-09-17T07:58:00.001-07:00</published><updated>2008-09-17T08:06:25.726-07:00</updated><title type='text'>Java note: generics</title><content type='html'>In Java 1.5 (and 1.6), generics is used by containers to avoid runtime type cast. Generics are not implemented in the same way as C++ templates, and are much less flexible. A generic class is compiled into only one class file, instead of one for each template instance. A big disadvantage is that a generic container cannot make new instances of its elements.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-4584183353830075499?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/4584183353830075499/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=4584183353830075499' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/4584183353830075499'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/4584183353830075499'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2008/09/java-note-generics.html' title='Java note: generics'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-1982002798515773183</id><published>2008-09-17T07:58:00.000-07:00</published><updated>2008-09-17T08:00:48.447-07:00</updated><title type='text'>Java note: assertion</title><content type='html'>The assert statement in Java are ignored from compile by default. To enable assert, add -ea when compiling.&lt;br /&gt;&lt;br /&gt;javac -ea example.java&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-1982002798515773183?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/1982002798515773183/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=1982002798515773183' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/1982002798515773183'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/1982002798515773183'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2008/09/java-note-assertion.html' title='Java note: assertion'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-449825446922608706</id><published>2008-07-10T14:07:00.000-07:00</published><updated>2008-07-11T02:21:51.601-07:00</updated><title type='text'>Python note: swapping objects</title><content type='html'>The best way to swap two objects is:&lt;br /&gt;&lt;br /&gt;a, b = b, a&lt;br /&gt;&lt;br /&gt;It swaps the names of two object by the use of a tuple, without altering the objects.&lt;br /&gt;&lt;br /&gt;The way to swap objects in many languages involves copying. However, this method can be tricky with Python. This is particularly because &lt;a href="http://docs.python.org/ref/assignment.html"&gt;object assignment&lt;/a&gt; in Python does not copy objects. It simply links a variable name to the existing object. Suppose&lt;br /&gt;&lt;br /&gt;class X(object):&lt;br /&gt;__init__(self, x)&lt;br /&gt;     self.x = x&lt;br /&gt;&lt;br /&gt;a = X([1, 2, 3])&lt;br /&gt;b = X([])&lt;br /&gt;&lt;br /&gt;Then we want this:&lt;br /&gt;&lt;br /&gt;b = a&lt;br /&gt;a.x = []&lt;br /&gt;&lt;br /&gt;The above will not work, because b.x will become [] too. To avoid copying, use&lt;br /&gt;&lt;br /&gt;a, b = b, a&lt;br /&gt;a.x = []&lt;br /&gt;&lt;br /&gt;In another occasion, if a will be kept while b becomes a copy of a's value, define a copying function or use the &lt;a href="http://docs.python.org/lib/module-copy.html"&gt;copy module&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;With the new-style class, everything is an object. So the rule for object assignment applies to lists, dicts etc. To make a copy of the original list, use l2 = l1[:].&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-449825446922608706?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/449825446922608706/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=449825446922608706' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/449825446922608706'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/449825446922608706'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2008/07/python-note-swapping-objects.html' title='Python note: swapping objects'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-4839299739003679165</id><published>2008-07-07T03:20:00.000-07:00</published><updated>2008-07-07T03:22:47.150-07:00</updated><title type='text'>Python note: functional programming saves code when dealing with lists</title><content type='html'>Another note on using functional programming. It makes code with lists shorter and clearer sometimes. &lt;br /&gt;&lt;br /&gt;For example, there is a list l. We want to add one to each element:&lt;br /&gt;&lt;br /&gt;l = map(lambda x: x+1, l)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-4839299739003679165?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/4839299739003679165/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=4839299739003679165' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/4839299739003679165'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/4839299739003679165'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2008/07/python-note-functional-programming.html' title='Python note: functional programming saves code when dealing with lists'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-6369234009185973949</id><published>2008-07-07T03:10:00.000-07:00</published><updated>2008-07-07T08:08:20.616-07:00</updated><title type='text'>LIBSVM note: problems</title><content type='html'>1. Why does svm-scale run forever, while keeping writing the output file (.scale)? &lt;br /&gt;&lt;br /&gt;It might be because the original training file contains [0, 1] range features, but the scale output requires [-1, 1] range. This is the default option. Add the option -l 0.&lt;br /&gt;&lt;br /&gt;2. Why does svm-train run forever?&lt;br /&gt;&lt;br /&gt;It might be because of the epsilon value. The default parameter (-e 0.001) sets this value. The smaller the value is, the more accurate will the trained model be, but the more iterations will be taken. Consider setting epsilon to 1 and try. &lt;br /&gt;&lt;br /&gt;If there are a lot of features, consider trying LIBLINEAR instead. It does not use a kernel, but runs faster than LIBSVM for a linear model. &lt;br /&gt;&lt;br /&gt;Another param, -m, sets the memory cache. Make it as large as possible within RAM.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-6369234009185973949?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/6369234009185973949/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=6369234009185973949' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/6369234009185973949'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/6369234009185973949'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2008/07/libsvm-note-problems.html' title='LIBSVM note: problems'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-6712797400319438546</id><published>2008-05-20T09:02:00.000-07:00</published><updated>2008-05-20T09:07:53.887-07:00</updated><title type='text'>Python tool: Chinese Treebank</title><content type='html'>I have put some scripts to process the Penn Chinese Treebank to &lt;br /&gt;&lt;a href="http://code.google.com/p/chinese-treebank-tools/"&gt;Google code&lt;/a&gt;. These files include a parser to turn bracketed annotations into Python objects, a converter to translate POS tags into the Stanford tagger format, and a set of head finding rules to translate CTB into dependency trees. &lt;br /&gt;&lt;br /&gt;I haven't made any releases for download, but have been updating the source code. The files are available by browsing the trunk from the SVN repository.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-6712797400319438546?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/6712797400319438546/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=6712797400319438546' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/6712797400319438546'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/6712797400319438546'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2008/05/python-tool-chinese-treebank.html' title='Python tool: Chinese Treebank'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-6694077121400419903</id><published>2008-04-01T09:04:00.000-07:00</published><updated>2008-04-29T13:49:36.685-07:00</updated><title type='text'>Python note: reversing lists</title><content type='html'>There are two ways to reverse a list. One way is to modify the original list:&lt;br /&gt;&lt;br /&gt;l = [1,2,3]&lt;br /&gt;l.reverse() # l becomes [3,2,1]&lt;br /&gt;&lt;br /&gt;The other way is not to modify the original list, but make a copy:&lt;br /&gt;&lt;br /&gt;l = [1,2,3]&lt;br /&gt;l[::-1] # l remains&lt;br /&gt;&lt;br /&gt;Notes: l[start:end:step] makes a new sequence from l by slicing. For example, l[1:2] makes a new list [2] and l[0:3] makes [1,2,3]. l[:] is often used to make a copy of the whole list l. This is useful when we want to pass the value (not rerence) of l to a new list.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-6694077121400419903?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/6694077121400419903/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=6694077121400419903' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/6694077121400419903'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/6694077121400419903'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2008/04/python-note-reverse-lists.html' title='Python note: reversing lists'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-2788730113540903345</id><published>2008-03-30T04:54:00.000-07:00</published><updated>2008-04-29T13:58:48.783-07:00</updated><title type='text'>Python note: the difference between __getattr__ and __getattribute__</title><content type='html'>I tried to overload __setattr__ today, so that when a value is assigned to item.type, I can check whether it is in the set of possible choices. However, I made a mistake by defining a __setattribute__ function instead of __setattr__.&lt;br /&gt;&lt;br /&gt;There is no special function named __setattribute__. The only functions that intercepts attribute accesses in Python are __getattr__, __getattribute__ and __setattr__. The difference between __getattr__ and __getattribute is that, __getattr__ is called when the attribute is not in the object's dictionary, while __getatttribute__ is called whenever the attribute is accessed. Therefore, __getattribute__ will make the speed slower. __setattr__ is the same as __getattribute__ in the triggering mechanism -- it intercepts the assignment operation no matter the attribute to modify already exists or not.&lt;br /&gt;&lt;br /&gt;Another note about __getattr__ is that the overloaded method must raise attribute error itself or the program may run into unexpected output. For example, there is an overloaded __getattr__ method:&lt;br /&gt;&lt;br /&gt;class Foo(object):&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;def __getattr__(self, attr):&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;         if attr == "bar":&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;               return "bar"&lt;br /&gt;&lt;br /&gt;foo = Foo()&lt;br /&gt;&lt;br /&gt;Now when we try to see foo.barrrr which doesn't exist, we get None value instead of a thrown attribute error. The code should be corrected into:&lt;br /&gt;&lt;br /&gt;class Foo(object):&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;   def __getattr__(self, attr):&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;   if attr == "bar":&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;      return "bar"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;   else:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;      raise AttributeError, attr&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-2788730113540903345?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/2788730113540903345/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=2788730113540903345' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/2788730113540903345'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/2788730113540903345'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2008/03/python-note-difference-between-getattr.html' title='Python note: the difference between __getattr__ and __getattribute__'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-5113451947371204969</id><published>2008-03-20T04:29:00.000-07:00</published><updated>2008-03-30T10:39:44.551-07:00</updated><title type='text'>Python tool: traditional to simplified Chinese converter</title><content type='html'>I just wrote this script to convert traditional Chinese text to simplified Chinese. Since the relationship between traditional and simplified characters is many to one, I haven't decided to write the revert convertion script.&lt;br /&gt;&lt;br /&gt;It has been tested with my files and can be &lt;a href="http://www.codeplex.com/simplify"&gt;downloaded here&lt;/a&gt;, and please report bugs and suggestions if you found any.&lt;br /&gt;&lt;br /&gt;The package contains two files, simplify.py and utftable.txt. The python script is the converter and utftable.txt is the character table. The two files must be put into the same directory.&lt;br /&gt;&lt;br /&gt;Usage:&lt;br /&gt;python simplify.py input.txt &gt;output.txt&lt;br /&gt;&lt;br /&gt;Both the input and the output text files must be in UTF8.&lt;br /&gt;&lt;br /&gt;Note that you can replace the character relationship table file with your own file (the new file must be in the same format as the original file), just in case there are more comprehensive tables than this one.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-5113451947371204969?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/5113451947371204969/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=5113451947371204969' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/5113451947371204969'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/5113451947371204969'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2008/03/python-tool-traditional-chinese-to.html' title='Python tool: traditional to simplified Chinese converter'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-7504675673525801905</id><published>2008-03-18T14:07:00.000-07:00</published><updated>2008-03-18T14:13:27.053-07:00</updated><title type='text'>sqlite note: using the command line tool</title><content type='html'>The command line tool sqlite3 can be used to view the content of a database. One way of using it is typing in "sqlite3 FILE" and the database contained in FILE is opened for query commands. &lt;br /&gt;&lt;br /&gt;The command line tool sqlite3 can also be used to perform a query directly. For example, typing "sqlite3 FILE 'select * from Table1'" will print out all contents in table Table1. This is handy for showing large tables, because we can pipe the output into a reader tool. "sqlite3 FILE 'select * from Table1' | more".&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-7504675673525801905?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/7504675673525801905/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=7504675673525801905' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/7504675673525801905'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/7504675673525801905'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2008/03/sqlite-note-using-command-line-tool.html' title='sqlite note: using the command line tool'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-7010286537839015476</id><published>2008-03-10T11:17:00.001-07:00</published><updated>2008-04-29T13:48:02.722-07:00</updated><title type='text'>C++ note: static_cast from a reference to a value</title><content type='html'>By default, the  result of a static_cast is a r-value.  It can't be used as a l-value, and thus can't be given a new value.&lt;br /&gt;&lt;br /&gt;Such misuse will lead to compile errors. But the report from the compiler can be misleading or quite hard to understand. For example, suppose we have a base class Base and a derived class Derived from Base. We want to overload the istream &amp;gt;&amp;gt; operator for Derived. The following way to overloading the operator does not work:&lt;br /&gt;&lt;br /&gt;istream &amp;amp; operator &amp;gt;&amp;gt; (istream &amp;amp;is, Derived &amp;amp;derived) {&lt;br /&gt;   // special processing&lt;br /&gt;   is &amp;gt;&amp;gt; static_cast&amp;lt;Base&amp;gt;(derived);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;This is because the result for casting will be passed as a reference function parameter. The reported error from the compiler has nothing to do with cast, however, and it simply sais that there is no match for operator &amp;gt;&amp;gt; from ...&lt;br /&gt;&lt;br /&gt;It should be noticed that even if the cast is done for pointers, the results are still r-values.&lt;br /&gt;&lt;br /&gt;To avoid the above problem, use static_cast&amp;lt;Base&amp;amp;&amp;gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-7010286537839015476?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/7010286537839015476/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=7010286537839015476' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/7010286537839015476'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/7010286537839015476'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2008/03/c-note-staticcast-from-reference-to.html' title='C++ note: static_cast from a reference to a value'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-3358889579303495350</id><published>2008-01-28T02:52:00.000-08:00</published><updated>2008-01-28T03:12:22.908-08:00</updated><title type='text'>Python note: the main entry of a python file</title><content type='html'>In a python module we could write&lt;br /&gt;&lt;br /&gt;if __name__ == "__main__":&lt;br /&gt;   # the main program entry&lt;br /&gt;   ... &lt;br /&gt;&lt;br /&gt;and this is often taken as the main entry of the module. The fact may be misleading for C++ programmers, because python doesn't actually need a main entry when running a module. &lt;br /&gt;&lt;br /&gt;Unlike C++, each python module is treated as a sequence of executable commands. No matter when it is imported or run as a program, python always executes the python file from the first line to the end. This is also the reason why python is called a script language. Generally, there are three types of commands in python&lt;br /&gt;&lt;br /&gt;1. import commands: when python meets these commands, it checks sys.modules to see if the imported module is already in the list. If it is, python bypasses this command. Otherwise, python goes into the imported module and runs every command in it. &lt;br /&gt;&lt;br /&gt;2. definition commands: these commands include "class" and "def"; when python meets them it doesn not do anything, but remembers the definitions in the corresponding place (normally in the __dir__ of the current module). &lt;br /&gt;&lt;br /&gt;3. execution commands: all the other commands, including assignments, conditions and branching statements, function calls etc; python runs them according to their semantics. &lt;br /&gt;&lt;br /&gt;When a module is loaded into python as the main program, python gives the module name __name__ the special value "__main__". The condition check for __name__ == "__main__" is used to make sure that the commands below are executed only when the module is run as the main program, but not as an inmported module. There can be as many such conditions as possible, and they can occur anywhere in a python module. There is not a particular function or statement that python takes as the main entry of modules.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-3358889579303495350?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/3358889579303495350/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=3358889579303495350' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/3358889579303495350'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/3358889579303495350'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2008/01/python-note-main-entry-of-python-file.html' title='Python note: the main entry of a python file'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-8087190850172767302</id><published>2008-01-25T07:53:00.000-08:00</published><updated>2008-01-26T06:16:49.425-08:00</updated><title type='text'>C++ Makefile case study: incorrect dependencies cause unexpected errors</title><content type='html'>Incorrect dependencies in Makefiles can cause not only timestamp confusion, but also unexpected errors and segmentation faults after compiling. &lt;br /&gt;&lt;br /&gt;Suppose that there are three files: header.h, module1.cpp and module2.cpp. Both cpp files include the h file for the definition of common structures. module1 generates module1.o and module2 generates module2.o, which will be linked together. &lt;br /&gt;&lt;br /&gt;Now in the make file, suppose header.h was missing from the dependencies of module1.o and module2.o. An immediate problem that arises is that a "make" command won't compile the program if only header.h is modified after the last build. But this is not the worst problem. Suppose both header.h and module1.cpp are modified, and the common structure is touched. Now when "make" is executed, it's possible that nothing happens at compile time, but various strange bugs or unexpected results come out later at runtime. The reason is that module2 is still using the out dated version of data structure. Such a case can be confirmed by running "make clean" and then compile again to see if the unexpected errors go away.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-8087190850172767302?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/8087190850172767302/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=8087190850172767302' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/8087190850172767302'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/8087190850172767302'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2008/01/c-make-file-case-study-correct.html' title='C++ Makefile case study: incorrect dependencies cause unexpected errors'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-2867327387112005220</id><published>2008-01-14T03:00:00.000-08:00</published><updated>2008-01-14T03:05:40.125-08:00</updated><title type='text'>C++ question - linker failed</title><content type='html'>I defined a constant boolean in an external header file: &lt;br /&gt;const bool CONDITION = false ;&lt;br /&gt;&lt;br /&gt;Then I wrote in a function the following line:&lt;br /&gt;void func(...) {&lt;br /&gt;...&lt;br /&gt;if (cond) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;if (CONDITION) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;...&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;...&lt;br /&gt;...&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Then g++ couldn't compile the code, reporting that the linker couldn't find the function. &lt;br /&gt;&lt;br /&gt;I haven't figured out why it happended, but a solution is changing the if statement and constant bool value into a #ifdef directive and a macro.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-2867327387112005220?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/2867327387112005220/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=2867327387112005220' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/2867327387112005220'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/2867327387112005220'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2008/01/c-question-linker-failed.html' title='C++ question - linker failed'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-7426927213404147329</id><published>2007-11-22T10:38:00.000-08:00</published><updated>2008-03-28T06:39:18.777-07:00</updated><title type='text'>latex note: minipage with borders</title><content type='html'>One way to add borders to a minipage is embedding it into an fbox. For example:&lt;br /&gt;&lt;br /&gt;\fbox{&lt;br /&gt;\begin{minipage}[t]{0.5\textwidth}  &lt;br /&gt;...&lt;br /&gt;\end{minipage}&lt;br /&gt;}&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-7426927213404147329?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/7426927213404147329/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=7426927213404147329' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/7426927213404147329'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/7426927213404147329'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2007/11/latex-note-minipage-with-borders.html' title='latex note: minipage with borders'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-4252268247468793144</id><published>2007-11-09T04:26:00.000-08:00</published><updated>2007-11-22T12:12:58.603-08:00</updated><title type='text'>C++ note: initializers in multiple inheritance</title><content type='html'>&lt;a href="http://www.deitel.com/articles/cplusplus_tutorials/20060225/virtualBaseClass/"&gt;Here&lt;/a&gt; is a tutorial on C++ multiple inheritance.&lt;br /&gt;&lt;br /&gt;A C++ class can inherit multiple base classes. If these base class still have base classes, they will be initialized separately by default. (For each parent class, the subclass will contain the inherited structures) For example, suppose B and C derive from A, and D derive from B and C, D will have two copies of A. One inherited from B, and the other from C.&lt;br /&gt;&lt;br /&gt;In some occasions only one copy of A is needed in D. This type of inheritance is enabled by letting B and C virtually derive from A. By virtual inheritance, B and C no longer encompass the structure of A into their structure, but include a pointer to the A structure in their vtables. When D derive from B and C, the compiler generates only one A structure that is shared by B and C.&lt;br /&gt;&lt;br /&gt;Here comes a question: in the constructor of D, what structures do we need to initialize?&lt;br /&gt;&lt;br /&gt;class A {&lt;br /&gt;public:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;int a;&lt;br /&gt;&amp;nbsp;&amp;nbsp;A ( int i ) : a (i) {}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class B : virtual public A {&lt;br /&gt;public:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;B ( int i ) : A(i) {}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class C : virtual public A {&lt;br /&gt;public:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;C ( int i ) : A(i) {}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class D : public B, public C {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;D ( int i ) : A(i), B(i), C(i) {} //  &lt;-------------&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;In the above example, D has to initilize A, B and C in its constructor. The initialization of A is mandatory even though both B and C do have the initializers in their constructor. When D is constructed, the initializers of B and C will not assign any value to A by default. This fact can be observed by removing the initialization of A in D, and printing the a field from D-object.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-4252268247468793144?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/4252268247468793144/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=4252268247468793144' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/4252268247468793144'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/4252268247468793144'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2007/11/c-note-initializers-in-multiple.html' title='C++ note: initializers in multiple inheritance'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-7131770237462003727</id><published>2007-11-08T05:38:00.000-08:00</published><updated>2007-11-09T04:23:12.295-08:00</updated><title type='text'>C++ note: avoid allocating large structures in the stack</title><content type='html'>Unexpected segmentation fault when calling a function can be caused by big memory allocation in the stack. The following piece of code will fail.&lt;br /&gt;&lt;br /&gt;class Big {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;int data[10000000000];&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;void test() {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;cout &lt;&lt; "entering test";&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Big big;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void main(int argc, char** argv) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;test();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;The reason is this: when test() is called, the variables declared in this function are put to the stack ( which is a special area of memory for function calls, commonly supported by a stack pointer in the CPU architecture ). The size of the stack is limited, and putting too much data in it can cause unexpected errors without warning. ( Note that compilers may choose to push stack before any executions, and therefore the "entering test" hint might not be printed. ) This kind of error is hard to trace during debugging. With new CPU architectures, the stack size may be improved, but this trap is still commonly seen nowadays.&lt;br /&gt;&lt;br /&gt;To void such segmentation faults, we need to put the big structures into the heap. Two methods can be used. One is allocating memory inside the class:&lt;br /&gt;&lt;br /&gt;class Big {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;int *data;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Big() { data = new int[10000000000]; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;virtual ~Big() { delete data; }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;The other is allocating memory inside the function instead:&lt;br /&gt;&lt;br /&gt;void test() {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;cout &lt;&lt; "entering test";&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Big *big = new Big;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;delete big;&lt;br /&gt;}&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-7131770237462003727?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/7131770237462003727/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=7131770237462003727' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/7131770237462003727'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/7131770237462003727'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2007/11/c-note-avoid-creating-large-structures.html' title='C++ note: avoid allocating large structures in the stack'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-4194247496845117671</id><published>2007-11-07T08:21:00.000-08:00</published><updated>2007-11-07T08:31:10.450-08:00</updated><title type='text'>C++ note: pointer and reference</title><content type='html'>The semantics of the * operator is to get the value from a pointer. When it is used as a reference, *p converts the pointer to the reference of the object it points to. This is illustrated with the following example.&lt;br /&gt;&lt;br /&gt;void reference( int &amp;amp;i ) { i = 4; }&lt;br /&gt;&lt;br /&gt;void testReference() {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;int i=5;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;int *p = &amp;i;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;reference( *p );&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;cout &amp;lt; &amp;lt; i &amp;lt;&amp;lt; endl;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;As can be seen from the output (4), the &lt;span style="font-style:italic;"&gt;i&lt;/span&gt; in the &lt;span style="font-style:italic;"&gt;testReference&lt;/span&gt; method is actually modified. This shows the semantics of the * operator, when used as a reference.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-4194247496845117671?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/4194247496845117671/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=4194247496845117671' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/4194247496845117671'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/4194247496845117671'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2007/11/c-note-pointer-and-reference.html' title='C++ note: pointer and reference'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-3777436074266812505</id><published>2007-11-02T08:26:00.000-07:00</published><updated>2007-11-09T04:25:32.836-08:00</updated><title type='text'>C++ note: predefined macros</title><content type='html'>The standard C++ compilers all support the following macros:&lt;br /&gt;&lt;br /&gt;__DATE__ - a string literal containing the date when the source file was compiled, in the form of "Mmm dd yyyy". &lt;br /&gt;&lt;br /&gt;__FILE__ - a string literal containing the name of the source file. &lt;br /&gt;&lt;br /&gt;__LINE__ - an integer representing the current source line number. &lt;br /&gt;&lt;br /&gt;__STDC__ - defined if the C compiler conforms to the ANSI standard. This macro is undefined if the language level is set to anything other than ANSI. &lt;br /&gt;&lt;br /&gt;__TIME__ - a string literal containing the time when the source file was compiled, in the form of "hh:mm:ss". &lt;br /&gt;&lt;br /&gt;__cplusplus - defined when the compiler supports c plus plus. &lt;br /&gt;&lt;br /&gt;These macros can be used anywhere in the source code, just as if they were defined by the #define directive. Their value changes according the the specific file and line in the source code. Therefore, we can use them to implement error reporting that includes file and line numbers in C++ source code.  &lt;br /&gt;&lt;br /&gt;#define REPORT(x) cerr &lt;&lt; endl &lt;&lt; "In " &lt;&lt; __FILE__ &lt;&lt; ", line " &lt;&lt; __LINE__ &lt;&lt; ": " &lt;&lt; endl &lt;&lt; x &lt;&lt; endl; cerr.flush();&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-3777436074266812505?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/3777436074266812505/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=3777436074266812505' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/3777436074266812505'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/3777436074266812505'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2007/11/c-note-predefined-macros.html' title='C++ note: predefined macros'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-4186358247778160339</id><published>2007-10-29T05:05:00.000-07:00</published><updated>2007-10-29T05:09:54.834-07:00</updated><title type='text'>C++ note: operator precedence</title><content type='html'>Another common trap is the precedence between == and &lt;span style="font-style:italic;"&gt;&amp;amp; | ^&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The expression &lt;span style="font-style: italic;"&gt;a &amp;amp; b == 0&lt;/span&gt; is interpreted as &lt;span style="font-style: italic;"&gt;a &amp;amp; (b==0)&lt;/span&gt; instead of &lt;span style="font-style: italic;"&gt;(a &amp;amp; b) == 0&lt;/span&gt;, quite different from &lt;span style="font-style: italic;"&gt;a + b == 0&lt;/span&gt;. &lt;br /&gt;&lt;br /&gt;Conclusion: always add brackets when evaluating the bitwise operators &lt;span style="font-style:italic;"&gt;&amp;amp; | ^&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-4186358247778160339?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/4186358247778160339/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=4186358247778160339' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/4186358247778160339'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/4186358247778160339'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2007/10/c-note-operator-precedence.html' title='C++ note: operator precedence'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-599264021867968012</id><published>2007-10-01T09:17:00.000-07:00</published><updated>2007-10-01T09:20:50.443-07:00</updated><title type='text'>Compile log: SRILM</title><content type='html'>SRILM is a language modelling package, used by the moses translation system. The compilation is quite straightforward, except two things:&lt;br /&gt;&lt;br /&gt;1. The current path in the Makefile needs to be changed&lt;br /&gt;2. In common/Makefile.machine.xxx, there are paths to gcc and g++. &lt;br /&gt;In the first line, GCC_FLAGS might need editing as well. For example, -mtune=pentium3.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-599264021867968012?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/599264021867968012/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=599264021867968012' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/599264021867968012'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/599264021867968012'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2007/10/compile-log-srilm.html' title='Compile log: SRILM'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-3223317172215975771</id><published>2007-09-16T07:18:00.000-07:00</published><updated>2007-09-16T07:27:02.516-07:00</updated><title type='text'>vim note: grep</title><content type='html'>The handy tool grep from Linux can also be used in VIM, by just typing ":grep PATTERN FILES" in the command mode. It finds the string according to the input pattern from all designated files. Note that FILES needs to be in the format of absolute path. Wildcard, such as "c:\\files\\*.txt" can be used. In version 7.0, "\\" is required for the path splitter under windows. "/" does not seem to work. Regular expression could be used for PATTERN. &lt;br /&gt;&lt;br /&gt;By default, only the first search result is shown. Use ":cn" to navigate to the next search result, and use ":cp" to navigate to the previous result. The navigation can jump from one file to another, of course. When multiple buffers (or files) are opened, use ":bn" and ":bp" to jump from one file to the other. Use ":bd" to remove a file from buffers.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-3223317172215975771?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/3223317172215975771/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=3223317172215975771' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/3223317172215975771'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/3223317172215975771'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2007/09/vim-note-grep.html' title='vim note: grep'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-6603789322271826871</id><published>2007-09-15T09:55:00.000-07:00</published><updated>2007-09-16T12:45:46.112-07:00</updated><title type='text'>mod_python note: sessions</title><content type='html'>mod_python has its own modules for Session and Cookies. The &lt;a href="http://www.modpython.org/live/current/doc-html/"&gt;mod_python documentation&lt;/a&gt; contains consise explanations about the usage. Cookies are used for session maintenance. An introduction can be found &lt;a href="http://en.wikipedia.org/wiki/HTTP_cookie"&gt;here&lt;/a&gt;. &lt;br /&gt;Python supports cookies by a built in module, which is probably developed for CGI programming before adopted into Python core. mod_python can use this module as well for cookies.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-6603789322271826871?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/6603789322271826871/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=6603789322271826871' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/6603789322271826871'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/6603789322271826871'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2007/09/modpython-note-cookies.html' title='mod_python note: sessions'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-679485591323304973</id><published>2007-09-15T09:35:00.000-07:00</published><updated>2007-09-18T08:02:10.467-07:00</updated><title type='text'>Python note: using the windows clipboard</title><content type='html'>The windows clipboard allows HTML content to be processed. A specification about the specific format can be found &lt;a href="http://msdn2.microsoft.com/en-us/library/ms649015.aspx"&gt;here&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;A python support for the windows clipboard is found in this &lt;a href="http://sourceforge.net/projects/pywin32/"&gt;site package&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;A recipe for using the clipboard, written by Phillip Piper, can be found from &lt;a href="http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/474121"&gt;this web page&lt;/a&gt;. I  gave a simplified version of putting something into the clipboard at &lt;a href="http://clearblogs.com/frcchang/72923/%5Bpython%5D+copy+html+content+to+windows+clipboard.html"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-679485591323304973?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/679485591323304973/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=679485591323304973' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/679485591323304973'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/679485591323304973'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2007/09/python-note-using-windows-clipboard.html' title='Python note: using the windows clipboard'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-5452618495708378219</id><published>2007-09-09T12:08:00.000-07:00</published><updated>2007-09-16T12:23:47.539-07:00</updated><title type='text'>Apach note: mod_python global objects</title><content type='html'>The term "global objects" in this article means the objects that exists from the starting of the web server until the shutdown. An example of such global objects is a database proxy, which is initialized at server start, and handles database calls during all the serving session. &lt;br /&gt;&lt;br /&gt;At the first look, it appeared to be no place for defining global objects, for mod_python runs on the per-request basis, with each request being mapped to a call.  &lt;br /&gt;&lt;br /&gt;However, mod_python has the advantage over CGI that a python interpreter is created for one virtual server to handle all requests to server. The interpreter starts when the server starts, and last until the server is shut down. Here is a &lt;a href="http://www.modpython.org/live/mod_python-3.3.1/doc-html/pyapi-interps.html"&gt;reference&lt;/a&gt; for the multiple interpreter mechanism for the mod_python module. &lt;br /&gt;&lt;br /&gt;To take this advantage, global variables can be place in the global namespace for the Python interpreter. For example, it could be intitilized from a module's namespace.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-5452618495708378219?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/5452618495708378219/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=5452618495708378219' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/5452618495708378219'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/5452618495708378219'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2007/09/apach-note-modpython-global-objects.html' title='Apach note: mod_python global objects'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-6597494452694338680</id><published>2007-09-09T11:59:00.000-07:00</published><updated>2007-09-11T07:38:36.633-07:00</updated><title type='text'>Apache note: set up a mod_python server</title><content type='html'>Though the building of mod_python can be a little daunting under UNIX, it's quite easy to start a mod_python server with apache under the windows platform. &lt;br /&gt;&lt;br /&gt;Suppose that a machine has python installed. &lt;br /&gt;&lt;br /&gt;First download the apache http server from &lt;a href="http://www.apache.org"&gt;the apache web site&lt;/a&gt;. (you need to find the download site by following the links from the main site) Current version is 2.2. &lt;br /&gt;&lt;br /&gt;Second download the mod_python binaries for windows from &lt;a href="http://www.modpython.org"&gt;the mod_python web site&lt;/a&gt;. Current version is 3.3&lt;br /&gt;&lt;br /&gt;Third install apache following the instructions. &lt;br /&gt;&lt;br /&gt;Fourth install mod_python following the instructions. The information in the last page is important. The LoadModule command must be added to the httpd.conf file for apache so that the http server recognizes mod_python. &lt;br /&gt;&lt;br /&gt;The installation test can be found &lt;a href="http://www.modpython.org/live/current/doc-html/inst-testing.html"&gt;the documentation&lt;/a&gt; Note that http://127.0.0.1/test/*.py will work. This is because the request url is handed to mptest.py as parameters.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-6597494452694338680?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/6597494452694338680/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=6597494452694338680' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/6597494452694338680'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/6597494452694338680'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2007/09/apache-note-set-up-modpython-server.html' title='Apache note: set up a mod_python server'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-7135746736753308248</id><published>2007-09-09T11:54:00.000-07:00</published><updated>2007-09-09T11:59:38.398-07:00</updated><title type='text'>Latex note: how to shrink tables</title><content type='html'>To reduce the size of a table, two general methods can be used. &lt;br /&gt;&lt;br /&gt;1. Shrink the the font size. &lt;br /&gt;For example, use &lt;span style="font-style:italic;"&gt;\small{content}&lt;/span&gt; instead of &lt;span style="font-style:italic;"&gt;content&lt;/span&gt; in the table cell. &lt;br /&gt;&lt;br /&gt;2. Squeeze space between columns. &lt;br /&gt;For example, a table could be written in the following way&lt;br /&gt;&lt;span style="font-style:italic;"&gt;\begin{tabular}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;\setlength{\tabcolsep}{1pt}&lt;/span&gt;&lt;br /&gt;...&lt;br /&gt;&lt;span style="font-style:italic;"&gt;\end{tabular}&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-7135746736753308248?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/7135746736753308248/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=7135746736753308248' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/7135746736753308248'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/7135746736753308248'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2007/09/latex-note-how-to-shrink-tables.html' title='Latex note: how to shrink tables'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-655323517494412497</id><published>2007-08-25T05:50:00.000-07:00</published><updated>2007-09-06T08:28:45.554-07:00</updated><title type='text'>C++ note: unsigned int</title><content type='html'>Suppose &lt;span style="font-style:italic;"&gt;a&lt;/span&gt; is an unsigned int, the expression &lt;span style="font-style:italic;"&gt;a&lt;/span&gt;&gt;-1 is always &lt;span style="font-weight:bold;"&gt;false&lt;/span&gt;. This is because the type of -1 is decided by the type of &lt;span style="font-style:italic;"&gt;a&lt;/span&gt;, and it becomes maxint. &lt;br /&gt;&lt;br /&gt;Hint: remember the unsigned int variables in the code and do not compare them with a minus number. The comparison itself is not necessary.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-655323517494412497?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/655323517494412497/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=655323517494412497' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/655323517494412497'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/655323517494412497'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2007/08/c-note-unsigned-int.html' title='C++ note: unsigned int'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-1105279126349756736</id><published>2007-08-01T11:31:00.000-07:00</published><updated>2007-11-08T06:04:48.044-08:00</updated><title type='text'>Linux note: how to disable output</title><content type='html'>One way is adding a redirection to the command to execute:&lt;br /&gt;&lt;br /&gt;command &gt;/dev/null&lt;br /&gt;&lt;br /&gt;In the above line, &lt;span style="font-style:italic;"&gt;command &lt;/span&gt;is executed with its output redirected to /dev/null. &lt;br /&gt;&lt;br /&gt;More notes about the above syntax. "&gt;" is the operator to direct the output of command to a file. In this case, the file is the special device /dev/null. The standard output (using "&gt;") and the error output ("2&gt;") can both be redirected. To redirect the standard output and the error output at the same time, use ("&amp;&gt;"), and to append the redirected output to a file, use ("&gt;&gt;"). &lt;br /&gt;&lt;br /&gt;Disabling output is necessary in many situations. For example, when using nohup, the system output is put into the file nohup.out. If the disk space is limited, we may want this file to be as small as possible. Therefore, we may put necessary information into the error output, and redirect the standard output to null.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-1105279126349756736?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/1105279126349756736/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=1105279126349756736' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/1105279126349756736'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/1105279126349756736'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2007/08/linux-note-how-to-disable-output.html' title='Linux note: how to disable output'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-3962315850827627352</id><published>2007-06-16T03:27:00.000-07:00</published><updated>2007-06-16T03:29:35.939-07:00</updated><title type='text'>VIM note: viewport</title><content type='html'>It's sometimes necessary to split the view of a file into many windows. Below is a cheatsheet copied from &lt;a href="http://applications.linux.com/article.pl?sid=06/05/04/1544258&amp;tid=13"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;:sp  will split the Vim window horizontally. Can be written out entirely as  :split .&lt;br /&gt;:vsp will split the Vim window vertically. Can be written out as :vsplit .&lt;br /&gt;Ctrl-w Ctrl-w moves between Vim viewports.&lt;br /&gt;Ctrl-w j moves one viewport down.&lt;br /&gt;Ctrl-w k moves one viewport up.&lt;br /&gt;Ctrl-w h moves one viewport to the left.&lt;br /&gt;Ctrl-w l moves one viewport to the right.&lt;br /&gt;Ctrl-w = tells Vim to resize viewports to be of equal size.&lt;br /&gt;Ctrl-w - reduce active viewport by one line.&lt;br /&gt;Ctrl-w + increase active viewport by one line.&lt;br /&gt;Ctrl-w q will close the active window.&lt;br /&gt;Ctrl-w r will rotate windows to the right.&lt;br /&gt;Ctrl-w R will rotate windows to the left.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-3962315850827627352?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/3962315850827627352/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=3962315850827627352' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/3962315850827627352'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/3962315850827627352'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2007/06/vim-note-viewport.html' title='VIM note: viewport'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-1378105683760790339</id><published>2007-06-12T03:31:00.000-07:00</published><updated>2007-06-12T03:40:14.673-07:00</updated><title type='text'>C++ note: mix with C code</title><content type='html'>The easiest way to make use of C modules is including the header files with &lt;br /&gt;&lt;br /&gt;extern "C" &lt;br /&gt;{&lt;br /&gt;#include &amp;lt;a_c_module.h&amp;gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Then the C++ compiler knows that the header defines the structures in the c way, and will compile references in the C++ module in a compatible way. &lt;br /&gt;&lt;br /&gt;For the standard libraries name "cblabla", extern "C" is already included in the header files. This is the reason why modules &lt;cstdlib&gt; etc can be included directly. &lt;br /&gt;&lt;br /&gt;For the linker, different vendors might have different standards to mangle the refernece names. Therefore, it needs to be confirmed that the C modules are compiled in a compatible way as the C++ module. &lt;br /&gt;&lt;br /&gt;Making use of C++ modules from C modules is harder than the other way around. For the C++ programmers, it might be possible to turn some necessary C files into the C++ format and then compile the whole project as C++. Many files can be kept as the C modules and linked explicitly.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-1378105683760790339?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/1378105683760790339/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=1378105683760790339' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/1378105683760790339'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/1378105683760790339'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2007/06/c-note-mix-with-c-code.html' title='C++ note: mix with C code'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-5614067046964617459</id><published>2007-06-04T09:42:00.000-07:00</published><updated>2007-06-05T12:32:19.931-07:00</updated><title type='text'>Javascript note: about the regular expressions</title><content type='html'>Javascript supports regular expressions as a built in language feature. Regular expressions are enclosed between two "/". &lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.javascriptkit.com/javatutors/redev.shtml"&gt;Here&lt;/a&gt; is a tutorial.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-5614067046964617459?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/5614067046964617459/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=5614067046964617459' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/5614067046964617459'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/5614067046964617459'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2007/06/javascript-note-about-regular.html' title='Javascript note: about the regular expressions'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-4912910051448492057</id><published>2007-05-29T13:41:00.000-07:00</published><updated>2007-05-29T13:43:44.750-07:00</updated><title type='text'>Python note: python eggs</title><content type='html'>"Eggs to Python are like Jars to Java..."&lt;br /&gt;&lt;br /&gt;&lt;a href="http://peak.telecommunity.com/DevCenter/PythonEggs"&gt;More information&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-4912910051448492057?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/4912910051448492057/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=4912910051448492057' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/4912910051448492057'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/4912910051448492057'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2007/05/python-note-python-eggs.html' title='Python note: python eggs'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-7768791569135203631</id><published>2007-05-24T13:06:00.000-07:00</published><updated>2007-05-24T13:21:22.053-07:00</updated><title type='text'>C++ note: static variables</title><content type='html'>C++ is different from Java and csharp in the way classes are defined. The header files in C++ are not actually compiled into the object - they are only an indicator of how the data structures are organized, i.e. the reference to a member is the base address plus how much offside. All variables and functions to appear inside objects must be defined in the cpp files. The methods in header files are treated as inline methods. &lt;br /&gt;&lt;br /&gt;Now static variables are those that occur in the heap. They exist from the beginning until the finishing of the running of program. All variables defined in a cpp file are static variables, they are by default external linked. If a variable defined in a cpp file has explicit "static" modifier, it is internal linked and can only be accessed by the module. Static variables can also be defined inside functions and methods, in which case they are still present all through the running of a program; however, they can only be accessed from the name scope in which they are defined. The accessibility is the only difference between static variables. Lastly, constants in header files are also taken as static variables. This is why values can be assigned to them in the header files.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-7768791569135203631?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/7768791569135203631/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=7768791569135203631' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/7768791569135203631'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/7768791569135203631'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2007/05/c-note-static-variables.html' title='C++ note: static variables'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-6965383723393545296</id><published>2007-05-22T04:12:00.000-07:00</published><updated>2007-05-22T04:14:32.094-07:00</updated><title type='text'>g++ note: don't forget -c option</title><content type='html'>I made a mistake when writing Makefile today, by missing to put -c for the compile-only step. It led to a lot of unresolved external references.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-6965383723393545296?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/6965383723393545296/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=6965383723393545296' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/6965383723393545296'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/6965383723393545296'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2007/05/g-note-dont-forget-c-option.html' title='g++ note: don&apos;t forget -c option'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-7002356307216606487</id><published>2007-05-14T08:13:00.001-07:00</published><updated>2008-03-28T06:44:44.923-07:00</updated><title type='text'>Latex note: generating letter size papers</title><content type='html'>latex paper&lt;br /&gt;dvips -t letterSize -Ppdf -G0 paper&lt;br /&gt;ps2pdf -sPAPERSIZE=letter paper.ps&lt;br /&gt;&lt;br /&gt;If the last step doesn't work, try the following command:&lt;br /&gt;ps2pdf paper.ps&lt;br /&gt;&lt;br /&gt;It should work because the ps file already contains size information.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-7002356307216606487?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/7002356307216606487/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=7002356307216606487' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/7002356307216606487'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/7002356307216606487'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2007/05/latex-note-generating-letter-size.html' title='Latex note: generating letter size papers'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-9168397456328378707</id><published>2007-04-12T08:30:00.000-07:00</published><updated>2008-03-17T15:22:54.408-07:00</updated><title type='text'>Latex note: more on making EPS graphs from MS Office</title><content type='html'>Please see &lt;a href="http://frcchang.blogspot.com/2007/01/latex-note-convert-excel-charts-to-eps.html"&gt;my previous article&lt;/a&gt; about how to generate an eps chart from from MS Excel. &lt;br /&gt;&lt;br /&gt;You can also insert Word pictures into eps. The mechanism is the same as Excel. First, make an empty word document or page to draw the vector graphs. Then print the page, using general eps printer. Lastly, modify the page bounding box of the eps file so that it fits the graph. &lt;br /&gt;&lt;br /&gt;There is one thing to notice though: the coordinate counts from bottom left to top right! If the four numbers represent top left and bottom right, the picture will still show in latex document, but it will be sqeezed together with text because the size is below zero!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-9168397456328378707?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/9168397456328378707/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=9168397456328378707' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/9168397456328378707'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/9168397456328378707'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2007/04/latex-note-more-on-inserting-eps-from.html' title='Latex note: more on making EPS graphs from MS Office'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-2604514281021635253</id><published>2007-04-12T08:27:00.000-07:00</published><updated>2008-03-28T06:43:11.763-07:00</updated><title type='text'>Latex note: use minipage to align a figure of text to center, while keeping text aligned to left</title><content type='html'>Sometimes we need to align text with multiple lines to the center of page.&lt;br /&gt;&lt;br /&gt;\begin{figure}[t]&lt;br /&gt;\centering&lt;br /&gt;  this is first line \\&lt;br /&gt;  \hspace*{0.5cm} this is second line \\&lt;br /&gt;  this is third line \\&lt;br /&gt;  this is fourth line&lt;br /&gt;  \caption{caption}&lt;br /&gt;  \label{l}&lt;br /&gt;\end{figure}&lt;br /&gt;&lt;br /&gt;The above may not work because all lines are aligned to center, and they look messy on the left border. The solution is using a minipage to align text inside figure.&lt;br /&gt;&lt;br /&gt;\begin{figure}[t]&lt;br /&gt;\centering&lt;br /&gt;  \begin{minipage}[t]{0.5\textwidth}&lt;br /&gt;  this is first line \\&lt;br /&gt;  \hspace*{0.5cm} this is second line \\&lt;br /&gt;  this is third line \\&lt;br /&gt;  this is fourth line&lt;br /&gt;  \end{minipage}&lt;br /&gt;  \caption{caption}&lt;br /&gt;  \label{l}&lt;br /&gt;\end{figure}&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-2604514281021635253?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/2604514281021635253/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=2604514281021635253' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/2604514281021635253'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/2604514281021635253'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2007/04/latex-note-use-minipage-to-align-figure.html' title='Latex note: use minipage to align a figure of text to center, while keeping text aligned to left'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-4219356216070775690</id><published>2007-04-11T05:19:00.000-07:00</published><updated>2007-04-11T05:20:54.859-07:00</updated><title type='text'>Latex note: protect citations in caption</title><content type='html'>\caption{xxx \cite{yyy}} won't work, it won't compile with latex sometimes. &lt;br /&gt;&lt;br /&gt;use \caption{xxx {\protect \cite{yyy}}} instead.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-4219356216070775690?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/4219356216070775690/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=4219356216070775690' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/4219356216070775690'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/4219356216070775690'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2007/04/latex-note-protect-citations-in-caption.html' title='Latex note: protect citations in caption'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-3570920802746007963</id><published>2007-03-31T07:40:00.000-07:00</published><updated>2007-09-02T06:51:27.911-07:00</updated><title type='text'>Python note: os.path.join unexpected result for paths beginning with "/" or "\"</title><content type='html'>Need to pay attention when joining paths beginning with "/" (or "\" for windows). &lt;br /&gt;&lt;br /&gt;os.path.join("c:\abc", "def", "ghi") -&gt; no problem, c:\abc\def\ghi&lt;br /&gt;&lt;br /&gt;os.path.join("c:\abc", "\def") -&gt; outputs "\def".&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-3570920802746007963?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/3570920802746007963/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=3570920802746007963' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/3570920802746007963'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/3570920802746007963'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2007/03/python-note-ospathjoin.html' title='Python note: os.path.join unexpected result for paths beginning with &quot;/&quot; or &quot;\&quot;'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-802667747519978070</id><published>2007-03-23T12:54:00.000-07:00</published><updated>2007-03-23T13:07:10.935-07:00</updated><title type='text'>C++ note: be careful with unsigned</title><content type='html'>I just made a mistake with an unsigned integer. It took me nearly an hour to debug, just to find that the subtle bug is caused by this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;if (a&amp;lt;b-2)&lt;/span&gt; ...&lt;br /&gt;&lt;br /&gt;a = 0 b = 1&lt;br /&gt;&lt;br /&gt;b is an unsigned integer.&lt;br /&gt;&lt;br /&gt;The reason is that b-2 is interpreted as unsigned integer, and therefore the predicate wrong. The conclusion is that we should avoid using many minuses for unsigned.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;if (a+2&amp;lt;b)&lt;/span&gt; is the solution for this problem&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-802667747519978070?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/802667747519978070/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=802667747519978070' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/802667747519978070'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/802667747519978070'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2007/03/c-note-be-careful-with-unsigned.html' title='C++ note: be careful with unsigned'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-116864394112019274</id><published>2007-01-12T15:13:00.000-08:00</published><updated>2008-03-17T15:26:29.114-07:00</updated><title type='text'>Latex note: convert Excel charts to eps files</title><content type='html'>This tip applies to any chart from MS Office.&lt;br /&gt;&lt;br /&gt;In short, in order to insert charts from Excel to your Latex document, you need to (1) print your chart from MS Office into an eps file; (2) modify the bounding box in the output. &lt;br /&gt;&lt;br /&gt;You need to install Generic Postscript Printer from Adobe first. Link the printer to the port FILE: . After installation, set its output option from Property -&gt; Printing preferences... -&gt; Advanced -&gt; Postscript options -&gt; Postscript output opion to encapsulated postscript format (eps). &lt;br /&gt;&lt;br /&gt;This printer can be used to print the chart to an eps file.&lt;br /&gt;&lt;br /&gt;The EPS file contains borders which defines where the chart is. Use postscript to open this EPS file, then use a text editor to open it simultaneously. Tick options -&gt; eps clip from postscript. Then edit the line %%BoundingBox: ... from the text editor. Adjust the size of the chart in eps so that the clip fits well to the chart. Then save EPS.&lt;br /&gt;&lt;br /&gt;Now you are done. Insert the chart into latex!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-116864394112019274?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/116864394112019274/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=116864394112019274' title='13 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/116864394112019274'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/116864394112019274'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2007/01/latex-note-convert-excel-charts-to-eps.html' title='Latex note: convert Excel charts to eps files'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>13</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-116353910306936458</id><published>2006-11-14T13:14:00.000-08:00</published><updated>2006-11-14T13:18:24.710-08:00</updated><title type='text'>C++ note: be careful with ifstream</title><content type='html'>The following is the correct and actually standard way of reading something&lt;br /&gt;&lt;br /&gt;while(file.good())&lt;br /&gt;{&lt;br /&gt;  file &gt;&gt; s;&lt;br /&gt;  cout &lt;&lt; s;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;However, the following is wrong:&lt;br /&gt;&lt;br /&gt;while(file.good())&lt;br /&gt;{&lt;br /&gt;  file.get(t);&lt;br /&gt;  cout &lt;&lt; t ;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;it will normally repeat the last char in the file. The reason is that file.good only changes after get() is called. This is the way&lt;br /&gt;&lt;br /&gt;while(file.get(t))&lt;br /&gt;{&lt;br /&gt;  cout &lt;&lt; t ;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;file.get(t) will return success if the process works.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-116353910306936458?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/116353910306936458/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=116353910306936458' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/116353910306936458'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/116353910306936458'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2006/11/c-note-be-careful-with-ifstream.html' title='C++ note: be careful with ifstream'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-116300524461441634</id><published>2006-11-08T08:59:00.000-08:00</published><updated>2006-11-14T13:19:52.946-08:00</updated><title type='text'>C++ note: TRACE macros</title><content type='html'>#ifdef DEBUG&lt;br /&gt;#define TRACE(x) { cout &lt;&lt; x &lt;&lt; endl; cout.flush(); }&lt;br /&gt;#else&lt;br /&gt;#define TRACE(x)&lt;br /&gt;#endif&lt;br /&gt;&lt;br /&gt;#ifdef DEBUG&lt;br /&gt;#define RUN_ON_DEBUG(x) x&lt;br /&gt;#else&lt;br /&gt;#define RUN_ON_DEBUG(x)&lt;br /&gt;#endif&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-116300524461441634?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/116300524461441634/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=116300524461441634' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/116300524461441634'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/116300524461441634'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2006/11/c-note-trace-macros.html' title='C++ note: TRACE macros'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-116230867168628206</id><published>2006-10-31T07:28:00.000-08:00</published><updated>2007-11-08T05:56:18.504-08:00</updated><title type='text'>Python note: the value and the display of a unicode string</title><content type='html'>Sometimes it is necessary to view the unicode encoding of a special character or to see the display of a certain unicode code. Here is some example code.&lt;br /&gt;&lt;br /&gt;print '\xe6\x8d\xae'.decode("utf-8")&lt;br /&gt;&amp;lt;displays the unicode character&amp;gt;&lt;br /&gt;&lt;br /&gt;print repr(&amp;lt;the unicode character here&amp;gt;)&lt;br /&gt;'\xe6\x8d\xae'&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-116230867168628206?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/116230867168628206/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=116230867168628206' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/116230867168628206'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/116230867168628206'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2006/10/python-note-value-and-display-of.html' title='Python note: the value and the display of a unicode string'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-115952903673604422</id><published>2006-09-29T04:17:00.000-07:00</published><updated>2006-09-29T04:23:57.073-07:00</updated><title type='text'>wxPython note: about callbacks</title><content type='html'>Be careful about callbacks, for they sometimes bring unexpected logics. The process is not written explicitly in the code, and therefore may cause traps, just like aspect oriented programming. For example, I just wrote a callback from notebook page change. Then I used some manual calls to change the notebook pages. I did not notice that those manual calls also brought up callbacks, and therefore messing the logic. This problem is fixed by introducing a boolean variable bManual to indicate whether a page switch is done by pressing manually or by a function call. Whenever the notebook page is switched by function calls, it is marked with the variable.&lt;br /&gt;&lt;br /&gt;Thinking of aspect oriented programming, sometimes a program is added with new functionalities and thus become larger all the time. Apart from using SVN to monitor the changes, it is also possible to use some special end of line comments to clarify. For example, some functionalities can be marked with # [-functionality-]. Then in further editing, we simply check the tags to find which code does the job. However, this approach should be used carefully so that all code and comments are consistent.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-115952903673604422?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/115952903673604422/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=115952903673604422' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/115952903673604422'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/115952903673604422'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2006/09/wxpython-note-about-callbacks.html' title='wxPython note: about callbacks'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-115943772279135581</id><published>2006-09-28T02:55:00.000-07:00</published><updated>2006-09-28T03:02:03.906-07:00</updated><title type='text'>Python note: module subprocess provides functionalities to open arbitrary file</title><content type='html'>To open an email attachment in some email client, the client needs to make new processes which opens the corresponding file. This can be done by using the subprocess module, which spawns new process and opens the file.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;&lt;span style="font-family: courier new;"&gt;import subprocess&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;subprocess.Popen(filename, shell=True)&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-115943772279135581?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/115943772279135581/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=115943772279135581' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/115943772279135581'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/115943772279135581'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2006/09/python-note-module-subprocess-provides.html' title='Python note: module subprocess provides functionalities to open arbitrary file'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-115732054143661687</id><published>2006-09-03T14:51:00.000-07:00</published><updated>2006-09-04T09:17:01.693-07:00</updated><title type='text'>C++ note: about strings</title><content type='html'>length - &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;s.length()&lt;/span&gt;&lt;/span&gt; / &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;s.size()&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;index - &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;s[1] = 'x' / s[2]&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;slice - &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;s.substr(1,4) &lt;/span&gt;&lt;/span&gt;means starting from 1, length 4.&lt;br /&gt;append - &lt;span style="font-family: courier new;font-size:85%;" &gt;s.append(t)&lt;/span&gt;&lt;br /&gt;replace - &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;s.replace(1,3, 'x')&lt;/span&gt;&lt;/span&gt; replaces slice (1,3)&lt;br /&gt;erase - &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;s.erase(1,2)&lt;/span&gt;&lt;/span&gt; same meaning&lt;br /&gt;find - &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;s.find("abc",2)&lt;/span&gt;&lt;/span&gt; find from index 2&lt;br /&gt;reverse - &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;reverse(s.begin(), s.end())&lt;/span&gt;&lt;/span&gt; modifies strs.&lt;br /&gt;&lt;br /&gt;It's alright concatenating strings with +&lt;br /&gt;The constructor can also be &lt;span style="font-family: courier new;font-size:85%;" &gt;s = string(t, start, length)&lt;/span&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-115732054143661687?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/115732054143661687/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=115732054143661687' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/115732054143661687'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/115732054143661687'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2006/09/c-note-about-strings.html' title='C++ note: about strings'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-115679843559809672</id><published>2006-08-28T13:53:00.000-07:00</published><updated>2006-09-09T13:31:02.220-07:00</updated><title type='text'>C++ note: int to string</title><content type='html'>&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;import &amp;lt;string&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;import &amp;lt;sstream&amp;gt; &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;using namespace std;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;int main() {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="color: rgb(204, 204, 204);"&gt;...&lt;/span&gt;string s;&lt;br /&gt;&lt;span style="color: rgb(204, 204, 204);"&gt;...&lt;/span&gt;int a=1;&lt;br /&gt;&lt;span style="color: rgb(204, 204, 204);"&gt;...&lt;/span&gt;stringstream ss;&lt;br /&gt;&lt;span style="color: rgb(204, 204, 204);"&gt;...&lt;/span&gt;ss &lt;&lt; a;&lt;br /&gt;&lt;span style="color: rgb(204, 204, 204);"&gt;...&lt;/span&gt;&lt;/span&gt;ss &gt;&gt; s;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-family:times new roman;"&gt;also, use atoi or strtol for string to int (cstdlib).&lt;br /&gt;use s = c to assign directly from C string to string, and use s.c_str() to get c string from string&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-115679843559809672?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/115679843559809672/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=115679843559809672' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/115679843559809672'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/115679843559809672'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2006/08/c-note-int-to-string.html' title='C++ note: int to string'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-115234776495804439</id><published>2006-07-08T01:33:00.000-07:00</published><updated>2006-07-08T01:36:05.286-07:00</updated><title type='text'>Python note: __hash__</title><content type='html'>__hash__ provides the hash code for an object. It is used under two circumstances: when the object is put in a dictionary; or when hash() built-in function is called.&lt;br /&gt;&lt;br /&gt;There is a requirement for this method - two objects should have the  same hash when their __cmp__ returns zero (they are equal). Thus when a class does not provide __cmp__ member function, it should not provide __hash__.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-115234776495804439?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/115234776495804439/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=115234776495804439' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/115234776495804439'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/115234776495804439'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2006/07/python-note-hash.html' title='Python note: __hash__'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-115228438240628512</id><published>2006-07-07T07:58:00.000-07:00</published><updated>2006-11-08T09:01:34.506-08:00</updated><title type='text'>VIM note: tabs</title><content type='html'>In VIM 7, tab view is supported.&lt;br /&gt;&lt;br /&gt;To open a new tab, use :tabnew&lt;br /&gt;To navigate among tabs, use 'gt'&lt;br /&gt;To close a tab, use ':tabclose'&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-115228438240628512?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/115228438240628512/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=115228438240628512' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/115228438240628512'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/115228438240628512'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2006/07/vim-note-tabs.html' title='VIM note: tabs'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-114959003023964555</id><published>2006-06-06T03:32:00.000-07:00</published><updated>2006-06-06T03:36:47.370-07:00</updated><title type='text'>Python note: unicode example (switch utf to gb2312)</title><content type='html'>This is a script to switch files from unicode to gb2312&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;&lt;span style="font-family:courier new;"&gt;# gb2utf - switch encoding between text&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;# Yue Zhang 2006&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;import sys&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;iFile = open(sys.argv[1])&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;oFile = open(sys.argv[2], "w")&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;sLine = iFile.readline()&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;while sLine:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="color: rgb(204, 204, 204);"&gt;...&lt;/span&gt;try:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="color: rgb(204, 204, 204);"&gt;......&lt;/span&gt;uLine = sLine.decode("gb2312")&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="color: rgb(204, 204, 204);"&gt;...&lt;/span&gt;except UnicodeDecodeError:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="color: rgb(204, 204, 204);"&gt;......&lt;/span&gt;sLine = iFile.readline()&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="color: rgb(204, 204, 204);"&gt;......&lt;/span&gt;continue&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="color: rgb(204, 204, 204);"&gt;...&lt;/span&gt;oFile.write(uLine.encode("utf8")) # note this.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="color: rgb(204, 204, 204);"&gt;...&lt;/span&gt;sLine = iFile.readline()&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;iFile.close()&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;oFile.close() &lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-114959003023964555?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/114959003023964555/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=114959003023964555' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/114959003023964555'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/114959003023964555'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2006/06/python-note-unicode-example-switch-utf.html' title='Python note: unicode example (switch utf to gb2312)'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-114889757473812917</id><published>2006-05-29T03:12:00.000-07:00</published><updated>2006-05-29T03:15:17.346-07:00</updated><title type='text'>Python note: get your ip address</title><content type='html'>Here is a small platform independent script for you to get the IP address for the current machine.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;&lt;span style="font-family:courier new;"&gt;import socket&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;print socket.gethostbyname(socket.gethostname()) &lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-114889757473812917?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/114889757473812917/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=114889757473812917' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/114889757473812917'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/114889757473812917'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2006/05/python-note-get-your-ip-address.html' title='Python note: get your ip address'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-114884974249396608</id><published>2006-05-28T13:52:00.000-07:00</published><updated>2006-05-28T13:55:42.503-07:00</updated><title type='text'>Python note: SimpleHTTPServer note</title><content type='html'>Special notice for SimpleHTTPServer:&lt;br /&gt;&lt;br /&gt;1. Read more of the source code! The SimpleHTTPRequestHandler is initialised, does the job and then dissappears. To retain it code must be edited.&lt;br /&gt;&lt;br /&gt;2. Notice that each HTTP request asks only one response. This is HTTP protocol, and more responses will cause problems.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-114884974249396608?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/114884974249396608/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=114884974249396608' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/114884974249396608'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/114884974249396608'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2006/05/python-note-simplehttpserver-note.html' title='Python note: SimpleHTTPServer note'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-114840427358731771</id><published>2006-05-23T10:03:00.000-07:00</published><updated>2006-05-24T03:01:33.970-07:00</updated><title type='text'>C++ note: references vs pointers</title><content type='html'>Use references when the target is a fixed object:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;&lt;span style="font-family:courier new;"&gt;a_class* const a_inst=&amp;a;         =&gt;         a_class &amp;a_inst=a;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;It's ideal to use references when passing a parameter to a function, because they probably won't move. However, when using references for return values we must be careful that the original value is in the &lt;span style="font-weight: bold;"&gt;heap&lt;/span&gt; and not in the stack (local varaible). It's more natural to return a pointer.&lt;br /&gt;&lt;br /&gt;Use pointers in the cases of iterating through a lot of objects. Actually, iteration is probably the best place to use pointers. Also when the address is needed explicitly pointer is the only choice.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-114840427358731771?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/114840427358731771/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=114840427358731771' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/114840427358731771'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/114840427358731771'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2006/05/c-note-references-vs-pointers.html' title='C++ note: references vs pointers'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-114751253223720535</id><published>2006-05-13T02:24:00.000-07:00</published><updated>2006-05-13T02:29:38.163-07:00</updated><title type='text'>VIM note: abbreviations</title><content type='html'>Command :abbr (:ab) sets abbreviations for strings. For example, with&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;&lt;span style="font-family:courier new;"&gt;:abbr #a hello&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;You could use #a[ENTER]&lt;enter&gt; in the INSERT mode to write "hello". This is useful for writing comment.&lt;br /&gt;&lt;br /&gt;In my python files, I usually use comment blocks like&lt;br /&gt;&lt;br /&gt;&lt;span style=";font-family:courier new;font-size:78%;"  &gt;#--------------------------------------------&lt;br /&gt;#&lt;br /&gt;# Function header&lt;br /&gt;#&lt;br /&gt;#--------------------------------------------&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This could neatly be done by putting some abbr commands to the .vimrc file&lt;br /&gt;&lt;br /&gt;Note:&lt;br /&gt;1. You must use # plus one letter for abbreviation names&lt;br /&gt;2. Under windows the vimrc file is _vimrc, and you must make an environment variable VIM.&lt;/enter&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-114751253223720535?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/114751253223720535/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=114751253223720535' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/114751253223720535'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/114751253223720535'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2006/05/vim-note-abbreviations.html' title='VIM note: abbreviations'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-114725948381393072</id><published>2006-05-10T04:07:00.000-07:00</published><updated>2006-05-17T12:29:58.366-07:00</updated><title type='text'>C++ note: virtual inheritance</title><content type='html'>The format&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;&lt;span style="font-family:courier new;"&gt;public class C: &lt;span style="font-weight: bold;"&gt;virtual&lt;/span&gt; B {...}&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The  main reason for virtual inheritance is for the diamond structure - B extends D, C extends D and A extends B, C. Without &lt;span style="font-family: courier new;"&gt;virtual&lt;/span&gt; mark, the instances of A will include data slots defined in both B and C, while the data slots defined in B and C will each include the data slots from D .&lt;br /&gt;&lt;br /&gt;Python's will always have a diamond structure, because it always uses references. Of course Java does not have such problems.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-114725948381393072?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/114725948381393072/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=114725948381393072' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/114725948381393072'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/114725948381393072'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2006/05/c-note-virtual-inheritance.html' title='C++ note: virtual inheritance'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-114725849640892072</id><published>2006-05-10T03:42:00.000-07:00</published><updated>2006-05-10T03:54:56.426-07:00</updated><title type='text'>Python note: when you get a lot of instances</title><content type='html'>Some classes has quite a lot of instances, and it's important to reduce the memory consumption by these objects. I blog two ways of doing it by Python.&lt;br /&gt;&lt;br /&gt;First is using __slots__.  Define this in the class definition, with a  sequence type (normally tuple, but never string).  For example,&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;&lt;span style="font-family: courier new;"&gt;class C(object):&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;&lt;span style="color: rgb(204, 204, 204);"&gt;...&lt;/span&gt;__slots__ = "foo", "bar"&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This will make the instances of the class only have two attributes "foo" and "bar". Methods are the same, and they just need to be defined in the normal way.&lt;br /&gt;&lt;br /&gt;The reason that __slots__ might save memory is that it saves the need of making a dictionary object in every instance to store possible attributes. This works when there are a large number of instances.&lt;br /&gt;&lt;br /&gt;The second way is the &lt;span style="font-style: italic;"&gt;flyweight&lt;/span&gt; pattern. The idea of this pattern is reusing existing objects.&lt;br /&gt;&lt;br /&gt;For example, an email client maintains many messages. Each mail could be tagged with "read", "flag" etc. One client might contain huge number of email instances viewed at a time, and it's wise to reuse certain property instances for each email.&lt;br /&gt;&lt;br /&gt;Lastly, my view regarding patterns is that they are not something to be enjoyed as programming tips. Different problems must be solved in different ways, and applying a pattern blindly is of no good. However, reading some patterns could give me hints in problem solving. And a byproduct is that I would know what people in the Java world are talking about ;-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-114725849640892072?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/114725849640892072/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=114725849640892072' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/114725849640892072'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/114725849640892072'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2006/05/python-note-when-you-get-lot-of.html' title='Python note: when you get a lot of instances'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-114669119532839705</id><published>2006-05-03T13:46:00.006-07:00</published><updated>2006-05-04T07:44:56.243-07:00</updated><title type='text'>Python note: a file merger</title><content type='html'>&lt;span style="FONT-WEIGHT: bold"&gt;Problem&lt;/span&gt;: I've got two folders, containing images from two Cannon camera. They were taken the same day. Unfortunately, these two cameras gave the same names to their pictures. I wanted to merge these two folders, with more powerful functionalities.&lt;br /&gt;&lt;br /&gt;&lt;span style="FONT-WEIGHT: bold"&gt;Script&lt;/span&gt;: This script takes in two folders, moving files from one folder to the other one. When there are duplicate file names, it compares the files. If the files are really duplicated, it only keeps one copy. If the files are different in content, they are renamed to different names by adding postfixes.&lt;br /&gt;&lt;br /&gt;&lt;span style="FONT-WEIGHT: bold"&gt;Code&lt;/span&gt;: The following python source&lt;br /&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;#&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;# merge files - merge two folders with no duplicate files&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;#&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;g_sWelcome = """&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;merge_files - merge files from two directories into one.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;The files from the "from" directory will be moved to the "to" directory, while&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;duplicated files will be removed. If two files are in the same name but are&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;different in signature (revision time, size), the new one will be renamed.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;Author: Yue Zhang, 2006&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;"""&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;import sys,os&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;import filecmp&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;import shutil&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;#&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;# Given a path, filename and extention, return a full path name without collision&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;#&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;def fileid_alloc(sPath, sPathFrom, sFileName, sExtension):&lt;br /&gt;&lt;/span&gt;&lt;span style="COLOR: rgb(192,192,192);font-family:courier new;font-size:78%;"  &gt;...&lt;/span&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;global nDuplicateName, nDuplicateContent&lt;br /&gt;&lt;/span&gt;&lt;span style="COLOR: rgb(192,192,192);font-family:courier new;font-size:78%;"  &gt;...&lt;/span&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;nIndex = 0&lt;/span&gt;&lt;br /&gt;&lt;span style="COLOR: rgb(192,192,192);font-family:courier new;font-size:78%;"  &gt;...&lt;/span&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;sNewFileName = os.path.join(sPath, sFileName + sExtension)&lt;br /&gt;&lt;/span&gt;&lt;span style="COLOR: rgb(192,192,192);font-family:courier new;font-size:78%;"  &gt;...&lt;/span&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;if os.path.exists(sNewFileName):&lt;br /&gt;&lt;/span&gt;&lt;span style="COLOR: rgb(192,192,192);font-family:courier new;font-size:78%;"  &gt;...&lt;/span&gt;&lt;span style="COLOR: rgb(192,192,192);font-family:courier new;font-size:78%;"  &gt;...&lt;/span&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;nDuplicateName += 1&lt;br /&gt;&lt;/span&gt;&lt;span style="COLOR: rgb(192,192,192);font-family:courier new;font-size:78%;"  &gt;...&lt;/span&gt;&lt;span style="COLOR: rgb(192,192,192);font-family:courier new;font-size:78%;"  &gt;...&lt;/span&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;if filecmp.cmp(sNewFileName, os.path.join(sPathFrom, sFileName + sExtension)):&lt;br /&gt;&lt;/span&gt;&lt;span style="COLOR: rgb(192,192,192);font-family:courier new;font-size:78%;"  &gt;...&lt;/span&gt;&lt;span style="COLOR: rgb(192,192,192);font-family:courier new;font-size:78%;"  &gt;...&lt;/span&gt;&lt;span style="COLOR: rgb(192,192,192);font-family:courier new;font-size:78%;"  &gt;...&lt;/span&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;nDuplicateContent += 1&lt;br /&gt;&lt;/span&gt;&lt;span style="COLOR: rgb(192,192,192);font-family:courier new;font-size:78%;"  &gt;...&lt;/span&gt;&lt;span style="COLOR: rgb(192,192,192);font-family:courier new;font-size:78%;"  &gt;...&lt;/span&gt;&lt;span style="COLOR: rgb(192,192,192);font-family:courier new;font-size:78%;"  &gt;...&lt;/span&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;return sNewFileName&lt;br /&gt;&lt;/span&gt;&lt;span style="COLOR: rgb(192,192,192);font-family:courier new;font-size:78%;"  &gt;...&lt;/span&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;while os.path.exists(sNewFileName):&lt;br /&gt;&lt;/span&gt;&lt;span style="COLOR: rgb(192,192,192);font-family:courier new;font-size:78%;"  &gt;...&lt;/span&gt;&lt;span style="COLOR: rgb(192,192,192);font-family:courier new;font-size:78%;"  &gt;...&lt;/span&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;nIndex += 1&lt;br /&gt;&lt;/span&gt;&lt;span style="COLOR: rgb(192,192,192);font-family:courier new;font-size:78%;"  &gt;...&lt;/span&gt;&lt;span style="COLOR: rgb(192,192,192);font-family:courier new;font-size:78%;"  &gt;...&lt;/span&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;sNewFileName = os.path.join(sPath, sFileName + str(nIndex) + sExtension)&lt;br /&gt;&lt;/span&gt;&lt;span style="COLOR: rgb(192,192,192);font-family:courier new;font-size:78%;"  &gt;...&lt;/span&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;return sNewFileName&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;#&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;# Main function&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;#&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;def merge_files(folder_from, folder_to):&lt;br /&gt;&lt;/span&gt;&lt;span style="COLOR: rgb(192,192,192);font-family:courier new;font-size:78%;"  &gt;...&lt;/span&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;for sFullFileName in os.listdir(folder_from):&lt;br /&gt;&lt;/span&gt;&lt;span style="COLOR: rgb(192,192,192);font-family:courier new;font-size:78%;"  &gt;...&lt;/span&gt;&lt;span style="COLOR: rgb(192,192,192);font-family:courier new;font-size:78%;"  &gt;...&lt;/span&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;sFileName, sExtension = os.path.splitext(sFullFileName)&lt;br /&gt;&lt;/span&gt;&lt;span style="COLOR: rgb(192,192,192);font-family:courier new;font-size:78%;"  &gt;...&lt;/span&gt;&lt;span style="COLOR: rgb(192,192,192);font-family:courier new;font-size:78%;"  &gt;...&lt;/span&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;sNewFileName = fileid_alloc(folder_to, folder_from, sFileName, sExtension)&lt;br /&gt;&lt;/span&gt;&lt;span style="COLOR: rgb(192,192,192);font-family:courier new;font-size:78%;"  &gt;...&lt;/span&gt;&lt;span style="COLOR: rgb(192,192,192);font-family:courier new;font-size:78%;"  &gt;...&lt;/span&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;shutil.move(os.path.join(folder_from, sFullFileName), sNewFileName)&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;#&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;# Main entry&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;#&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;if __name__ == '__main__':&lt;br /&gt;&lt;/span&gt;&lt;span style="COLOR: rgb(192,192,192);font-family:courier new;font-size:78%;"  &gt;...&lt;/span&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;global nDuplicateName, nDuplicateContent&lt;br /&gt;&lt;/span&gt;&lt;span style="COLOR: rgb(192,192,192);font-family:courier new;font-size:78%;"  &gt;...&lt;/span&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;nDuplicateName = 0&lt;br /&gt;&lt;/span&gt;&lt;span style="COLOR: rgb(192,192,192);font-family:courier new;font-size:78%;"  &gt;...&lt;/span&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;nDuplicateContent = 0&lt;br /&gt;&lt;/span&gt;&lt;span style="COLOR: rgb(192,192,192);font-family:courier new;font-size:78%;"  &gt;...&lt;/span&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;print g_sWelcome&lt;br /&gt;&lt;/span&gt;&lt;span style="COLOR: rgb(192,192,192);font-family:courier new;font-size:78%;"  &gt;...&lt;/span&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;if len(sys.argv) != 3:&lt;br /&gt;&lt;/span&gt;&lt;span style="COLOR: rgb(192,192,192);font-family:courier new;font-size:78%;"  &gt;...&lt;/span&gt;&lt;span style="COLOR: rgb(192,192,192);font-family:courier new;font-size:78%;"  &gt;...&lt;/span&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;print "Usage: merge_files.py folder_from folder_to"&lt;br /&gt;&lt;/span&gt;&lt;span style="COLOR: rgb(192,192,192);font-family:courier new;font-size:78%;"  &gt;...&lt;/span&gt;&lt;span style="COLOR: rgb(192,192,192);font-family:courier new;font-size:78%;"  &gt;...&lt;/span&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;sys.exit(0)&lt;br /&gt;&lt;/span&gt;&lt;span style="COLOR: rgb(192,192,192);font-family:courier new;font-size:78%;"  &gt;...&lt;/span&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;merge_files(sys.argv[1], sys.argv[2])&lt;br /&gt;&lt;/span&gt;&lt;span style="COLOR: rgb(192,192,192);font-family:courier new;font-size:78%;"  &gt;...&lt;/span&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;print "In all %d duplicate file names processed, among which %d &lt;/span&gt;&lt;br /&gt;&lt;span style="COLOR: rgb(192,192,192);font-family:courier new;font-size:78%;"  &gt;...&lt;/span&gt;&lt;span style="COLOR: rgb(192,192,192);font-family:courier new;font-size:78%;"  &gt;...&lt;/span&gt;&lt;span style="COLOR: rgb(192,192,192);font-family:courier new;font-size:78%;"  &gt;...&lt;/span&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;&lt;span style="COLOR: rgb(192,192,192)"&gt;...&lt;/span&gt;duplicate contents are merged and the rest are allocated new name." &lt;/span&gt;&lt;br /&gt;&lt;span style="COLOR: rgb(192,192,192);font-family:courier new;font-size:78%;"  &gt;...&lt;/span&gt;&lt;span style="COLOR: rgb(192,192,192);font-family:courier new;font-size:78%;"  &gt;...&lt;/span&gt;&lt;span style="COLOR: rgb(192,192,192);font-family:courier new;font-size:78%;"  &gt;...&lt;/span&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;&lt;span style="COLOR: rgb(192,192,192)"&gt;...&lt;/span&gt;% (nDuplicateName, nDuplicateContent) &lt;/span&gt;&lt;br /&gt;&lt;span style="FONT-WEIGHT: bold"&gt;&lt;br /&gt;Disclaimer&lt;/span&gt;: I give no warranty of responsibilities of use of the code, though I have tested this code with my own photos.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-114669119532839705?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/114669119532839705/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=114669119532839705' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/114669119532839705'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/114669119532839705'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2006/05/python-note-file-merger_114669119532839705.html' title='Python note: a file merger'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-114641217542366531</id><published>2006-04-30T08:46:00.000-07:00</published><updated>2006-04-30T08:50:07.543-07:00</updated><title type='text'>VIM note: switch dos format to unix format</title><content type='html'>Still the same problem as my last Python note, now I want to do it with vim.&lt;br /&gt;&lt;br /&gt;This could be done by global pattern replacement. The command is:&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;:%s/pattern/replacement&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The pattern needs to use literal mode: [Ctrl-v] key&lt;br /&gt;In this case it's [Ctrl-v][CR], showed as ^M. The whole command will look like &lt;span style="font-family:courier new;"&gt;:%s/^M$//&lt;/span&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-114641217542366531?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/114641217542366531/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=114641217542366531' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/114641217542366531'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/114641217542366531'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2006/04/vim-note-switch-dos-format-to-unix.html' title='VIM note: switch dos format to unix format'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-114606041555154577</id><published>2006-04-26T07:03:00.000-07:00</published><updated>2006-04-26T07:13:07.510-07:00</updated><title type='text'>Python note: SunOS file format switching</title><content type='html'>When I opened boost-jam src under SunOS, I found that each  line was tailed with ^M. This is chr(13), which means that the end-of-line character for these files are \0xd\0xa.&lt;br /&gt;&lt;br /&gt;To remove \0xd in the end-of-line character and switch files to format which SunOS reads, I wrote such a Python program.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;import os&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;for sFile in os.listdir("."):&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;&amp;nbsp;&amp;nbsp;os.system("sed 's/%s//g' %s&gt;TEMP &amp;&amp;amp; mv TEMP %s" &lt;br /&gt;&amp;nbsp;&amp;nbsp;% (chr(13), sFile, sFile))&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;'s/pattern/replace/g' is the general expression for string substitution with UNIX.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-114606041555154577?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/114606041555154577/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=114606041555154577' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/114606041555154577'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/114606041555154577'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2006/04/python-note-sunos-file-format.html' title='Python note: SunOS file format switching'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-114235155369583164</id><published>2006-03-14T07:48:00.000-08:00</published><updated>2006-05-17T12:49:25.216-07:00</updated><title type='text'>Python note: "?:" in Python</title><content type='html'>In C++ and Java there is a handy way of writing conditional expression, such as &lt;span style="font-family: courier new;"&gt;x = y&gt;1?1:0.&lt;/span&gt; However there is no ?: operator in Python.&lt;br /&gt;&lt;br /&gt;Several  ways have been suggested around this problem. Some people use "a and b or c", while others use "(a and [b] or [c])[0]". However I don't think them intuitive.&lt;br /&gt;&lt;br /&gt;I was using dict for the expression, and to express &lt;span style="font-family: courier new;"&gt;x = y&gt;1 ? 1 : 0&lt;/span&gt;, I type&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;font-family:courier new;font-size:78%;"  &gt;x = {True : 1, False : 0}[y&gt;1]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;which is also concise.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-114235155369583164?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/114235155369583164/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=114235155369583164' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/114235155369583164'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/114235155369583164'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2006/03/python-note-in-python.html' title='Python note: &quot;?:&quot; in Python'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-112607911222020276</id><published>2005-09-07T00:41:00.000-07:00</published><updated>2007-09-06T08:51:16.399-07:00</updated><title type='text'>Python note: make use of built-in space</title><content type='html'>This is about the ways to make (cross module) global variables.&lt;br /&gt;&lt;br /&gt;One way of sharing variables among runtime modules is defining a global module, and let every module import it. The global module will be loaded only once, because Python puts every loaded module into sys.modules and makes sure that it won't be executed again by import statements. Once the global module is loaded, every module could access global.xxx for variables. In this way the variables are shared as global.&lt;br /&gt;&lt;br /&gt;The above method takes use of Python module loading mechanism to achieve global sharing. There is a more straightforward way. In Python, searching for variables follows the order of function -&gt; module -&gt; built-in scope. While the variable is not found anywhere in the module, the built-in scope will be looked for. This scope is defined as a global module (or dict).&lt;br /&gt;&lt;br /&gt;Suppose we have main module:&lt;br /&gt;&lt;br /&gt;main.py&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;&lt;span style="font-family:courier new;"&gt;g_nConfig = "blabla"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;__builtins__.g_nConfig = g_nConfig&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;import first_module&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;import second_module&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size:78%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;i&gt;&lt;span style="font-size:78%;"&gt;&lt;span style="font-family:courier new;"&gt;# other things to do&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;Then in the subsequent executions within the two imported modules,  g_nConfig is accessible.&lt;br /&gt;&lt;br /&gt;Now, suppose that there are many such global things to use.  You can make a concentrated sharing for them. The easiest form could be a dict.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;&lt;span style="font-family:courier new;"&gt;g_dGlobals = {'g_nConfig' : "bla bla", 'g_oObject1' : object1}&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Of course, to make the global powerful, you can make it a class.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-112607911222020276?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/112607911222020276/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=112607911222020276' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/112607911222020276'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/112607911222020276'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2005/09/python-note-take-use-of-built-in-space.html' title='Python note: make use of built-in space'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-112504633321028399</id><published>2005-08-26T01:31:00.000-07:00</published><updated>2007-09-06T08:50:30.282-07:00</updated><title type='text'>Python note: unicode</title><content type='html'>When you get some error output like this:&lt;br /&gt;&lt;br /&gt;&lt;i&gt;'ascii' encoding can not encode ...&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;The first thing to check is python unicode object.&lt;br /&gt;&lt;br /&gt;Python chooses a separate type of object to support unicode, in order to keep string compatibility. Thus python has two kinds of strings: str and unicode. Str objects are the same as the standard C string - an array of chars. It is used in most function calls. &lt;br /&gt;&lt;br /&gt;Each char in a computer system can represent 128 different values. For languages like English, the alphabet is below 30. Therefore we can find a mapping between each letter and each char value. Such a mapping is called encoding. ASCII is the most common encoding to map char values into letters. &lt;br /&gt;&lt;br /&gt;For languages with many more than 128 letters, such as Chinese and Japanese, many chars need to be combined to represent one character. A problem arises. Because different languages have different interpretations of char values, the same string can be mapped into different letters / characters by different encodings. For example, when viewing one webpage, you can switch your browser to different encodings, and the page will be displayed differently (of course there is only one encoding that is 'correct') Unicode is proposed to solve the encoding clash, and it includes all possible characters / letters in languages. Interestingly, there are also many different UTF encoding versions, include utf-8, utf-16, etc. &lt;br /&gt;&lt;br /&gt;Unicode objects in Python are actually strings encoded in utf-8. It can be seen as the abstract representation of the real character / letters, which can be encoded into different computer strings by different encodings. In other words, if strings are viewed as the outside form, Unicode can be viewed as the inside meaning. &lt;br /&gt;&lt;br /&gt;Unicode objects can be changed to str object by the method 'encode'. It will translate the meaning to raw strings with certain encodings.&lt;br /&gt;&lt;br /&gt;On the contrary, raw strings can be changed to unicode, using method 'decode'. When you know the 'correct' encoding of a raw string, you can tell it to the system and make it an unicode object.&lt;br /&gt;&lt;br /&gt;There are methods to help you determine the os encoding. They are sys.getdefaultencoding() and sys.getfilesystemencoding(). Which are self explanatory.&lt;br /&gt;&lt;br /&gt;Some methods in python work with str while other work with Unicode. You have no difficulty with those taking both types, but you need to be careful when calling a method that take only str or Unicode params. Also, the return type of a method us often neglected. For example, file.readline() would return a string. If a file is a unicode file, it's still a string encoded in 'utf-8'.&lt;br /&gt;&lt;br /&gt;When a unicode object is passed to a method taking string params, or vice versa, the system will try to switch beween them automatically. However because we did not specify encodings beforehand, it will use ascii by default. When the real encoding can't be interpreted by the ascii char set, the exception at the beginning of this article will occur. The steps to take to fix the problem might be: first check the type of the string, using type() method, then try to convert it to the correct type by using encode() or decode, specifying the encoding.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-112504633321028399?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/112504633321028399/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=112504633321028399' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/112504633321028399'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/112504633321028399'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2005/08/python-note-unicode.html' title='Python note: unicode'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-112476620659939150</id><published>2005-08-22T19:57:00.000-07:00</published><updated>2005-08-22T20:03:26.606-07:00</updated><title type='text'>wxPython note: process tab end enter key events for TextCtrl in dialogs</title><content type='html'>When you place a TextCtrl in a dialog and catch the Key events for it, you will find that enter and tab key events are not processed. When you press tab key, the focus will be switched to the next widget.&lt;br /&gt;&lt;br /&gt;The solution is setting the style for the TextCtrl. There are two styles, wx.TE_PROCESS_ENTER and wx.TE_PROCESS_TAB, which default to unset. They will help in processing events.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-112476620659939150?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/112476620659939150/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=112476620659939150' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/112476620659939150'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/112476620659939150'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2005/08/wxpython-note-process-tab-end-enter.html' title='wxPython note: process tab end enter key events for TextCtrl in dialogs'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-112442726362753405</id><published>2005-08-18T21:50:00.000-07:00</published><updated>2006-04-30T08:52:23.393-07:00</updated><title type='text'>Haskell note: turorials</title><content type='html'>I am completely new to Haskell functional programming. I started to play with it simply because of the need in my MSc course. But it seems more and more interesting now.&lt;br /&gt;&lt;br /&gt;Functional programming is quite different from "common", i.e. imperative programming, mainly in that it's not executed from the beginning to the end. A functional program can be taken as a set of equations, when calculated together yielding output.&lt;br /&gt;&lt;br /&gt;I find this introduction succinct and helpful&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.haskell.org/tutorial/"&gt;http://www.haskell.org/tutorial/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Here are some good summary of the language.&lt;br /&gt;&lt;br /&gt;About the grammar&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.cs.uu.nl/%7Eafie/haskell/tourofsyntax.html"&gt;http://www.cs.uu.nl/~afie/haskell/tourofsyntax.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;About the operators&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.imada.sdu.dk/%7Ekornerup/DM22/Noter/haskell-operatorer.pdf"&gt;http://www.imada.sdu.dk/~kornerup/DM22/Noter/haskell-operatorer.pdf&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-112442726362753405?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/112442726362753405/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=112442726362753405' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/112442726362753405'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/112442726362753405'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2005/08/haskell-note-turorials.html' title='Haskell note: turorials'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-112442670891357419</id><published>2005-08-18T21:40:00.000-07:00</published><updated>2005-08-18T22:03:44.996-07:00</updated><title type='text'>wxPython note: how to select many rows in Grid?</title><content type='html'>This problem puzzled me some time ago, and I forgot the solution again today. Thus I feel it necessary to take it down here.&lt;br /&gt;&lt;br /&gt;There is absolutely no way of setting a style like wx.CB_MULTIPLE to specify multiple selection here. wxGrid support multiple row selection by itself, see a reference&lt;br /&gt;&lt;br /&gt;&lt;a href="http://lists.wxwidgets.org/archive/wx-dev/msg21759.html"&gt;http://lists.wxwidgets.org/archive/wx-dev/msg21759.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The only thing you need to have is specifying the second (hidden!) param of SelectRow - bAppend (I am vague about the name). When it's true you will see the row selected without cleaning other rows.&lt;br /&gt;&lt;br /&gt;Of course, this implies that selecting many rows can only be done from program. Thus in order to respond to mouse and keyboard behaviors, event catching and processing are needed. Anyway, it's not uncommon to process events for a grid.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-112442670891357419?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/112442670891357419/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=112442670891357419' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/112442670891357419'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/112442670891357419'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2005/08/wxpython-note-how-to-select-many-rows.html' title='wxPython note: how to select many rows in Grid?'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-112408899076068040</id><published>2005-08-14T23:54:00.001-07:00</published><updated>2005-08-14T23:56:30.770-07:00</updated><title type='text'>Introduction to MVC</title><content type='html'>Found a good introduction to the MVC pattern.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://csis.pace.edu/~bergin/mvc/mvcgui.html"&gt;http://csis.pace.edu/~bergin/mvc/mvcgui.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Also see a general explanation at&lt;br /&gt;&lt;br /&gt;&lt;a href="http://ootips.org/mvc-pattern.html"&gt;http://ootips.org/mvc-pattern.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-112408899076068040?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/112408899076068040/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=112408899076068040' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/112408899076068040'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/112408899076068040'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2005/08/introduction-to-mvc_14.html' title='Introduction to MVC'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-112156375421926260</id><published>2005-07-16T18:21:00.000-07:00</published><updated>2006-04-30T08:53:33.560-07:00</updated><title type='text'>PHP note: Difference between PHP and Python - scope</title><content type='html'>Scope in Python is more complex. Firstly, functions. You will encounter local, global and builtin scopes in a function. Local scope is the scope within functions, global scope is the currently running module scope, while builtin scope is the current running python program. Secondly, objects. You will encounter object, class scope.  Python searches for variables in sequence of scopes, and looks at a higer level scope when it can't find symbol in the current scope.&lt;br /&gt;&lt;br /&gt;Scope in PHP is just simple. Normally you only need a module scope, while in functions there is a local scope. PHP does not search super scopes though. This is somehow because PHP can always find symbols. When variable not defined, PHP will simply set an empty value to it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-112156375421926260?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/112156375421926260/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=112156375421926260' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/112156375421926260'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/112156375421926260'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2005/07/php-note-difference-between-php-and_16.html' title='PHP note: Difference between PHP and Python - scope'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-112090568676861178</id><published>2005-07-09T03:33:00.000-07:00</published><updated>2011-01-20T04:52:11.155-08:00</updated><title type='text'>PHP note: Difference between PHP and Python - types</title><content type='html'>PHP and Python are both interpreted languages.&lt;br /&gt;&lt;br /&gt;Python has more strict types from PHP. Python does not have implicit type casting. For example, Python will calculate 3/2 as an integer division, and the output could be 1.  The only implicit type casting that I find about Python is that Python will change integers to long integers when the value of that integer is too large.&lt;br /&gt;&lt;br /&gt;PHP, on the other hand, does implicit type casting all the time.  It does not have integer division at all. When it does 3/2 it simply yields the float result 1.5. What is more unacceptable from Python thoughts is that it turns strings to integers automatically. "15abc" + 10 = 25! The same understanding of the world applies to many other places in PHP. Such as when you meet 01081 it will be taken as 8. Because that was an octal number, which was truncated when 8 came up.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-112090568676861178?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/112090568676861178/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=112090568676861178' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/112090568676861178'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/112090568676861178'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2005/07/php-note-difference-between-php-and.html' title='PHP note: Difference between PHP and Python - types'/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7979054.post-112090416061885553</id><published>2005-07-09T03:16:00.000-07:00</published><updated>2005-07-09T03:16:00.626-07:00</updated><title type='text'></title><content type='html'>&lt;a href="http://www.haloscan.com/" title="HaloScan Commenting and Trackback"&gt;Haloscan&lt;/a&gt; commenting and trackback have been added to this blog.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7979054-112090416061885553?l=frcchang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://frcchang.blogspot.com/feeds/112090416061885553/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7979054&amp;postID=112090416061885553' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/112090416061885553'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7979054/posts/default/112090416061885553'/><link rel='alternate' type='text/html' href='http://frcchang.blogspot.com/2005/07/haloscan-commenting-and-trackback-have.html' title=''/><author><name>Yue Zhang</name><uri>http://www.blogger.com/profile/09843271076983129884</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
