<?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-1254518247533161511</id><updated>2012-02-17T02:28:17.920+08:00</updated><category term='BASH'/><category term='Python'/><category term='Make'/><category term='PBS'/><category term='SSH'/><category term='Download'/><category term='Reversi'/><category term='Torque'/><category term='Parallel computing'/><category term='Multi-core'/><category term='Java'/><category term='Board game'/><category term='RMI'/><category term='Regular expression'/><category term='C++'/><category term='Coding style'/><category term='Game tree'/><category term='Alpha beta prunning'/><category term='Quick reference'/><category term='Maui'/><category term='Linux utility'/><category term='Benchmark'/><category term='Gawk'/><category term='Sed'/><category term='Scheduler'/><category term='Distributed computing'/><category term='Latest release'/><title type='text'>Xman Blog Inside</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://cshinyee.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1254518247533161511/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://cshinyee.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>xman</name><uri>http://www.blogger.com/profile/05695636905017529897</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>21</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1254518247533161511.post-4145056677240440197</id><published>2006-09-18T01:15:00.000+08:00</published><updated>2006-09-18T01:16:17.951+08:00</updated><title type='text'>BLOG Migration</title><content type='html'>I just got my domain name recently at &lt;A HREF="http://myxman.org"&gt;http://myxman.org&lt;/A&gt;. That gives more much more control to post casual blog and technical blog. Hence, I shall start migrating everything from Xanga and Blogspot to this new site.  I can even provide emails like xman@myxman.org, joleck@myxman.org, ivan@myxman.org  Or provides space for photo postings. Currently I have only 40GB of space. I still can put in lots of stuff.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1254518247533161511-4145056677240440197?l=cshinyee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cshinyee.blogspot.com/feeds/4145056677240440197/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1254518247533161511&amp;postID=4145056677240440197&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1254518247533161511/posts/default/4145056677240440197'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1254518247533161511/posts/default/4145056677240440197'/><link rel='alternate' type='text/html' href='http://cshinyee.blogspot.com/2006/09/blog-migration.html' title='BLOG Migration'/><author><name>xman</name><uri>http://www.blogger.com/profile/05695636905017529897</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-1254518247533161511.post-2778798217671985963</id><published>2006-09-16T01:33:00.000+08:00</published><updated>2006-09-16T02:02:06.024+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Reversi'/><category scheme='http://www.blogger.com/atom/ns#' term='Benchmark'/><title type='text'>Reversi Benchmark -- Round 2</title><content type='html'>Finally we got a Woodcrest machine for benchmark. Thanks to &lt;A HREF="http://himiko.dnsalias.net/eblah/cgi-bin/blah/Blah.pl?"&gt;CopperBlue&lt;/A&gt; again for contributing the machine.&lt;br /&gt;&lt;br /&gt;&lt;A HREF="http://cshinyee.zoomshare.com/files/image/xversi-c-benchmark-result-round2.jpg"&gt;&lt;IMG SRC="http://cshinyee.zoomshare.com/files/image/xversi-c-benchmark-result-round2-small.jpg"  /&gt;&lt;/A&gt;&lt;br /&gt;The Intel Xeon Dual-Core 2.66GHz (Woodcrest) achieves much better 32bit performance than AMD64X2 4200+ (2.2GHz). Running Woodcrest in 64bit achieves even higher performance.&lt;br /&gt;&lt;br /&gt;&lt;A HREF="http://cshinyee.zoomshare.com/files/image/xversi-java-parallel-benchmark-result-round2.jpg"&gt;&lt;IMG SRC="http://cshinyee.zoomshare.com/files/image/xversi-java-parallel-benchmark-result-round2-small.jpg" /&gt;&lt;/A&gt;&lt;br /&gt;Can you believe Woodcrest is even slower than the aging AMD64 X2? I suggest CopperBlue upgrade his Java JVM to 1.5.x. There is significant performance boost in Java 1.5 over Java 1.4. Otherwise, his latest processor is just as slow as my 1+ year-old processor. Do you care?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1254518247533161511-2778798217671985963?l=cshinyee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cshinyee.blogspot.com/feeds/2778798217671985963/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1254518247533161511&amp;postID=2778798217671985963&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1254518247533161511/posts/default/2778798217671985963'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1254518247533161511/posts/default/2778798217671985963'/><link rel='alternate' type='text/html' href='http://cshinyee.blogspot.com/2006/09/reversi-benchmark-round-3.html' title='Reversi Benchmark -- Round 2'/><author><name>xman</name><uri>http://www.blogger.com/profile/05695636905017529897</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-1254518247533161511.post-4524241706854858372</id><published>2006-09-14T20:30:00.000+08:00</published><updated>2006-09-14T22:15:22.055+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Reversi'/><category scheme='http://www.blogger.com/atom/ns#' term='Benchmark'/><title type='text'>Reversi Benchmark: AMD64 X2 vs INTEL CORE DUO vs OTHERS</title><content type='html'>This round we manage to get an Intel Core Duo 2.16GHz with Shared 2MB L2, Mac Book Pro, to benchmark. Thanks &lt;A HREF="http://himiko.dnsalias.net/eblah/cgi-bin/blah/Blah.pl?"&gt;CopperBlue&lt;/A&gt; for contributing his laptop. How does it compare to AMD64 X2 4200+ (2.2GHz) with 2 x 512KB Private L2 which has almost the same clock speed? However, AMD64 X2 is able to run in both 32bit mode and 64bit mode, whereas Core Duo runs only 32bit mode. Does it matter?&lt;br /&gt;&lt;br /&gt;Let's see the first benchmark &lt;a href="http://cshinyee.zoomshare.com/files/xversi-c-benchmark-v0.1.tgz"&gt;xversi-c-benchmark-v0.1&lt;/a&gt; which utilizes only one core.&lt;br /&gt;&lt;A HREF="http://cshinyee.zoomshare.com/files/image/xversi-c-benchmark-result.jpg"&gt;&lt;IMG SRC="http://cshinyee.zoomshare.com/files/image/xversi-c-benchmark-result-small.jpg" /&gt;&lt;/A&gt;&lt;br /&gt;&lt;br /&gt;Intel Core Duo 2.16GHz has slight advantage over AMD64 X2 4200+ in 32bit mode. Interestingly, AMD64 X2 running in 64bit mode boost up the performance almost by 2x. Itanium II with much lower clock speed is clearly out of the game.&lt;br /&gt;&lt;br /&gt;What about the Parallel Reversi? Let's see the next benchmark &lt;a href="http://cshinyee.zoomshare.com/files/xversi-java-parallel-benchmark-v0.1.tgz"&gt;xversi-java-parallel-benchmark-v0.1&lt;/a&gt;.&lt;br /&gt;&lt;IMG SRC="http://cshinyee.zoomshare.com/files/image/xversi-java-parallel-benchmark-result.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;AMD64 X2 4200+ clearly has an advantage running in 64bit mode. The 64bit JVM definitely helps in boosting the performance. Hence, if you own a 64bit processor, use a 64bit OS, and 64bit components such as Sun Java for x86_64.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1254518247533161511-4524241706854858372?l=cshinyee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cshinyee.blogspot.com/feeds/4524241706854858372/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1254518247533161511&amp;postID=4524241706854858372&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1254518247533161511/posts/default/4524241706854858372'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1254518247533161511/posts/default/4524241706854858372'/><link rel='alternate' type='text/html' href='http://cshinyee.blogspot.com/2006/09/reversi-benchmark-amd64-x2-vs-intel.html' title='Reversi Benchmark: AMD64 X2 vs INTEL CORE DUO vs OTHERS'/><author><name>xman</name><uri>http://www.blogger.com/profile/05695636905017529897</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-1254518247533161511.post-8712081167304691609</id><published>2006-09-11T13:39:00.000+08:00</published><updated>2006-09-11T13:59:57.068+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><category scheme='http://www.blogger.com/atom/ns#' term='Quick reference'/><title type='text'>Python Core Language Quick Reference</title><content type='html'>If you can learn a language by example, this is a place for you to learn the core of python programming. However, some statements are mis-indented. But indentation should not be a problem to you if you are familiar with structured programming.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;# Getting started.&lt;/span&gt;&lt;br /&gt;&gt;&gt;&gt; print "hello world"&lt;br /&gt;hello world&lt;br /&gt;&lt;br /&gt;xman@sai python $ cat hello.py&lt;br /&gt;#!/usr/bin/python&lt;br /&gt;# hello world comment&lt;br /&gt;print "hello world"&lt;br /&gt;&lt;br /&gt;&gt;&gt;&gt; execfile("hello.py")&lt;br /&gt;hello world&lt;br /&gt;&lt;br /&gt;&gt;&gt;&gt; import sys&lt;br /&gt;&gt;&gt;&gt; sys.exit()&lt;br /&gt;xman@sai python $&lt;br /&gt;&lt;br /&gt;&gt;&gt;&gt; while x &lt;= y:&lt;br /&gt;...     print x,y&lt;br /&gt;...     x=x+1&lt;br /&gt;&gt;&gt;&gt; x = 0 ; y = 1 ; z = 2&lt;br /&gt;&gt;&gt;&gt; print "%4d  %0.2f" % (x,y)&lt;br /&gt;100  5.00&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;# Conditional.&lt;/span&gt;&lt;br /&gt;&gt;&gt;&gt; if x &lt; z =" x"&gt; y:&lt;br /&gt;...  z = y&lt;br /&gt;... elif x == y:&lt;br /&gt;...  pass&lt;br /&gt;... else:&lt;br /&gt;...  raise RuntimeError, "Unknown"&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;# Keywords&lt;/span&gt;: and assert break class continue def del elif else except exec finally for from global&lt;br /&gt;if import in is lambda not or pass print raise return try while&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;# Operators&lt;/span&gt;: + - * ** / % &lt;&lt; &gt;&gt; &lt; &gt; &lt;= &gt;= == != &lt;&gt; &amp; | ^ ~  not and or&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;# File.&lt;/span&gt;&lt;br /&gt;&gt;&gt;&gt; f = open("hello.py")&lt;br /&gt;&gt;&gt;&gt; line = f.readline()&lt;br /&gt;&gt;&gt;&gt; while line:&lt;br /&gt;...  print line&lt;br /&gt;...  line = f.readline()&lt;br /&gt;...&lt;br /&gt;&gt;&gt;&gt; f.close()&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;# File methods&lt;/span&gt;&lt;br /&gt;f.read([n])&lt;br /&gt;f.readline()&lt;br /&gt;f.readlines()&lt;br /&gt;f.write(s)      # Write string s.&lt;br /&gt;f.writelines(l) # Write all strings in list l.&lt;br /&gt;f.close()&lt;br /&gt;f.tell()&lt;br /&gt;f.seek(offset [,where])&lt;br /&gt;f.isatty()&lt;br /&gt;f.flush()&lt;br /&gt;f.truncate([size])&lt;br /&gt;f.fileno()&lt;br /&gt;f.readinto(buffer, nbytes)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;# String &amp; Char&lt;/span&gt;&lt;br /&gt;&gt;&gt;&gt; a = "hello world"&lt;br /&gt;&gt;&gt;&gt; print a[4]&lt;br /&gt;o&lt;br /&gt;&gt;&gt;&gt; a = 'hello world'&lt;br /&gt;&gt;&gt;&gt; b = "hello world"&lt;br /&gt;&gt;&gt;&gt; c = """hello world"""&lt;br /&gt;&gt;&gt;&gt; d = """hello&lt;br /&gt;... world&lt;br /&gt;... """&lt;br /&gt;&lt;br /&gt;&gt;&gt;&gt; print d&lt;br /&gt;hello&lt;br /&gt;world&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;# Slice&lt;/span&gt;&lt;br /&gt;&gt;&gt;&gt; x = a[0:5]&lt;br /&gt;&gt;&gt;&gt; y = a[1:]&lt;br /&gt;&gt;&gt;&gt; z = a[:4]&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;# String&lt;/span&gt;&lt;br /&gt;&gt;&gt;&gt; a = "hello" ; b = "world"&lt;br /&gt;&gt;&gt;&gt; c = a + b ; print c&lt;br /&gt;helloworld&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;# List&lt;/span&gt;&lt;br /&gt;&gt;&gt;&gt; data = ["a", "b", "c"]&lt;br /&gt;&gt;&gt;&gt; data.append("d")&lt;br /&gt;&gt;&gt;&gt; data = data + ['e','f']&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;# Reference count&lt;/span&gt;&lt;br /&gt;&gt;&gt;&gt; a = [1,3,5]&lt;br /&gt;&gt;&gt;&gt; b = a&lt;br /&gt;&gt;&gt;&gt; a, b&lt;br /&gt;([1, 3, 5], [1, 3, 5])&lt;br /&gt;&gt;&gt;&gt; b[1] = 100&lt;br /&gt;&gt;&gt;&gt; a, b&lt;br /&gt;([1, 100, 5], [1, 100, 5])&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;# Nested list.&lt;/span&gt;&lt;br /&gt;&gt;&gt;&gt; data = ['a' , ['b','c' ]]&lt;br /&gt;&gt;&gt;&gt; print data[1][1]&lt;br /&gt;c&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;# Map.&lt;/span&gt;&lt;br /&gt;&gt;&gt;&gt; import string&lt;br /&gt;&gt;&gt;&gt; import sys&lt;br /&gt;&gt;&gt;&gt; f = open("data.dat")&lt;br /&gt;&gt;&gt;&gt; svalues = f.readlines()&lt;br /&gt;&gt;&gt;&gt; f.close()&lt;br /&gt;&gt;&gt;&gt; fvalues = map(string.atof, svalues)&lt;br /&gt;&gt;&gt;&gt; print svalues&lt;br /&gt;['0.1\n', '0.4\n', '0.2\n', '0.3\n', '0.24\n']&lt;br /&gt;&gt;&gt;&gt; print fvalues&lt;br /&gt;[0.10000000000000001, 0.40000000000000002, 0.20000000000000001, 0.29999999999999999, 0.2399999999&lt;br /&gt;9999999]&lt;br /&gt;&gt;&gt;&gt; print min(fvalues)&lt;br /&gt;0.1&lt;br /&gt;&gt;&gt;&gt; print max(fvalues)&lt;br /&gt;0.4&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;# Tuple (Create once, no modifications allowed)&lt;/span&gt;&lt;br /&gt;&gt;&gt;&gt; a = (1,3)&lt;br /&gt;&gt;&gt;&gt; b = (2,4)&lt;br /&gt;&gt;&gt;&gt; c = (4,)&lt;br /&gt;&gt;&gt;&gt; print a,b,c&lt;br /&gt;(1, 3) (2, 4) (4,)&lt;br /&gt;&gt;&gt;&gt; print a[0], a[1]&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;# Range.&lt;/span&gt;&lt;br /&gt;&gt;&gt;&gt; print range(3)&lt;br /&gt;[0, 1, 2]&lt;br /&gt;&gt;&gt;&gt; print range(1,10)&lt;br /&gt;[1, 2, 3, 4, 5, 6, 7, 8, 9]&lt;br /&gt;&gt;&gt;&gt; print range(1,10,2)&lt;br /&gt;[1, 3, 5, 7, 9]&lt;br /&gt;&gt;&gt;&gt; for i in range(1,10,2):&lt;br /&gt;...  print i&lt;br /&gt;...&lt;br /&gt;1&lt;br /&gt;3&lt;br /&gt;5&lt;br /&gt;7&lt;br /&gt;9&lt;br /&gt;a = xrange(0,10000000) # Recompute to save memory.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;# Dictionary (associative array).&lt;/span&gt;&lt;br /&gt;&gt;&gt;&gt; a = {&lt;br /&gt;... "a" : "va" ,&lt;br /&gt;... "b" : "vb"&lt;br /&gt;... }&lt;br /&gt;&gt;&gt;&gt; print a["a"], a["b"]&lt;br /&gt;&gt;&gt;&gt; a.keys()&lt;br /&gt;&gt;&gt;&gt; a.has_key("a")&lt;br /&gt;&gt;&gt;&gt; del a["a"]&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;# Function. Local scope by default.&lt;/span&gt;&lt;br /&gt;&gt;&gt;&gt; def swap(a,b,c=0):&lt;br /&gt;...     "SWAP: Documentation string"&lt;br /&gt;...     global msg&lt;br /&gt;...     if c != 0 : print msg&lt;br /&gt;...     return (b,a)&lt;br /&gt;...&lt;br /&gt;&gt;&gt;&gt; a,b=swap(a,b)&lt;br /&gt;&gt;&gt;&gt; a,b=swap(a,b,1)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;# Variable-length argument, keyword argument.&lt;/span&gt;&lt;br /&gt;# args: Additional variables in a tuple.&lt;br /&gt;# kw: Additional keyword arguments in a table.&lt;br /&gt;&gt;&gt;&gt; def func(x, *args, **kw):&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;# Class.&lt;/span&gt;&lt;br /&gt;# def: Define a method.&lt;br /&gt;# First argument of a method: the object.&lt;br /&gt;&gt;&gt;&gt; class stack:&lt;br /&gt;...  "Stack data structure"&lt;br /&gt;...  name = "Stack"&lt;br /&gt;...  def __init__(self):&lt;br /&gt;...     self.stack = []&lt;br /&gt;...  def push(self,object):&lt;br /&gt;...     "Append object to the end"&lt;br /&gt;...     self.stack.append(object)&lt;br /&gt;...  def pop(self):&lt;br /&gt;...     "Remove an object from the end and return it"&lt;br /&gt;...     return self.stack.pop()&lt;br /&gt;...  def length(self):&lt;br /&gt;...     "Number of objects in stack"&lt;br /&gt;...     return len(self.stack)&lt;br /&gt;&gt;&gt;&gt; s = stack()&lt;br /&gt;&gt;&gt;&gt; s.push("data1")&lt;br /&gt;&gt;&gt;&gt; s.push("data2")&lt;br /&gt;&gt;&gt;&gt; x = s.pop()&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;# Inheritance.&lt;/span&gt;&lt;br /&gt;&gt;&gt;&gt; class C(A,B):&lt;br /&gt;# Encapsulation.&lt;br /&gt;&gt;&gt;&gt; class C:&lt;br /&gt;...   __x = 500&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;# Class relationship&lt;/span&gt;&lt;br /&gt;&gt;&gt;&gt; isinstance(c,C)&lt;br /&gt;&gt;&gt;&gt; issubclass(C,A)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;# Exception.&lt;/span&gt;&lt;br /&gt;&gt;&gt;&gt; try:&lt;br /&gt;...     f = open("data.txt")&lt;br /&gt;... except IOError, e:&lt;br /&gt;...     print "My error:" , e&lt;br /&gt;...&lt;br /&gt;My error: [Errno 2] No such file or directory: 'data.txt'&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;# Module.&lt;/span&gt;&lt;br /&gt;# Import the module hello.py.&lt;br /&gt;&gt;&gt;&gt; import hello&lt;br /&gt;&gt;&gt;&gt; import string&lt;br /&gt;&gt;&gt;&gt; dir(string) # List contents of module string.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;# Syntax.&lt;/span&gt;&lt;br /&gt;# Multi-line.&lt;br /&gt;&gt;&gt;&gt; c = a + \&lt;br /&gt;... b&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;# Consistent indentation.&lt;br /&gt;&lt;/span&gt;# Codes in the same block must uses the same indentation.&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;br /&gt;# Documentation strings.&lt;/span&gt;&lt;br /&gt;&gt;&gt;&gt; def func(n):&lt;br /&gt;...  "Documentation string"&lt;br /&gt;...  return n&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;# Type &amp; ID&lt;/span&gt;&lt;br /&gt;&gt;&gt;&gt; type(a)&lt;br /&gt;&lt;type&gt;&lt;br /&gt;&gt;&gt;&gt; id(a)&lt;br /&gt;5280552&lt;br /&gt;&gt;&gt;&gt; a is b&lt;br /&gt;&gt;&gt;&gt; a is not b&lt;br /&gt;&gt;&gt;&gt; type(a) == type(b)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;# Copy.&lt;/span&gt;&lt;br /&gt;&gt;&gt;&gt; import copy&lt;br /&gt;&gt;&gt;&gt; b = [1,2,3]&lt;br /&gt;&gt;&gt;&gt; a = copy.deepcopy(b)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;# List:&lt;/span&gt;&lt;br /&gt;list(s)&lt;br /&gt;s.append(x)&lt;br /&gt;s.extend(x)&lt;br /&gt;s.count(x)&lt;br /&gt;s.index(x)&lt;br /&gt;s.insert(i,x)&lt;br /&gt;s.pop([i])&lt;br /&gt;s.remove(x)&lt;br /&gt;s.reverse()&lt;br /&gt;s.sort([cmpfunc])&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;# Mapping types:&lt;/span&gt;&lt;br /&gt;len(m)&lt;br /&gt;m[k]&lt;br /&gt;del m[k]&lt;br /&gt;m.clear()&lt;br /&gt;m.copy()&lt;br /&gt;m.has_key(k)&lt;br /&gt;m.items()&lt;br /&gt;m.keys()&lt;br /&gt;m.update(b)&lt;br /&gt;m.values()&lt;br /&gt;m.get(k,[,f]) # Return m[k] if found; otherwise return f.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;# Unbound method object, bound method object.&lt;/span&gt;&lt;br /&gt;# C is a class, c is an instance of class C.&lt;br /&gt;&gt;&gt;&gt; c.work()&lt;br /&gt;hello world&lt;br /&gt;&gt;&gt;&gt; C.work(c)&lt;br /&gt;hello world&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;# Functional programming&lt;/span&gt;&lt;br /&gt;&gt;&gt;&gt; a = lambda x,y : x+y&lt;br /&gt;&gt;&gt;&gt; print a(2,5)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;# map(), reduce(), filter().&lt;/span&gt;&lt;br /&gt;# Apply func to elements in s.&lt;br /&gt;&gt;&gt;&gt; t = map(func,s)&lt;br /&gt;# Reduce a using sum function.&lt;br /&gt;&gt;&gt;&gt; b = reduce(sum, a)&lt;br /&gt;# Filter objects which satisfy the conditions.&lt;br /&gt;&gt;&gt;&gt; b = filter(lambda x: x &lt; style="font-weight: bold;"&gt;# Execution.&lt;br /&gt;# eval(str, [,globals [,locals]])&lt;br /&gt;&gt;&gt;&gt; c = eval('a+b')&lt;br /&gt;&gt;&gt;&gt; exec "print 4+3"&lt;br /&gt;# execfile(filename [,globals [,locals]])&lt;br /&gt;&gt;&gt;&gt; execfile("hello.py")&lt;br /&gt;# compile(str,filename,kind)&lt;br /&gt;&gt;&gt;&gt; c = compile(str, '', 'single')&lt;br /&gt;&gt;&gt;&gt; c = compile(str, '', 'exec')&lt;br /&gt;&gt;&gt;&gt; c = compile(str, '', 'eval')&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;# Input, Output&lt;/span&gt;&lt;br /&gt;&gt;&gt;&gt; s = raw_input("type something")&lt;br /&gt;&gt;&gt;&gt; c = sys.stdin.read(1)&lt;br /&gt;&gt;&gt;&gt; sys.stdout = open("output.txt", "w")&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;# Serialize&lt;/span&gt;&lt;br /&gt;&gt;&gt;&gt; f = open("save.dat", "w")&lt;br /&gt;&gt;&gt;&gt; pickle.dump(a,f)&lt;br /&gt;&gt;&gt;&gt; pickle.dump(b,f)&lt;br /&gt;&gt;&gt;&gt; f.close()&lt;br /&gt;&gt;&gt;&gt; f = open("save.dat", "r")&lt;br /&gt;&gt;&gt;&gt; obj = pickle.load(f)&lt;br /&gt;&gt;&gt;&gt; obj&lt;br /&gt;2&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;# Built-in Functions&lt;/span&gt;&lt;br /&gt;abs(x)&lt;br /&gt;apply(func [,args [,keywords]])&lt;br /&gt;buffer(object [,offset [,size]])&lt;br /&gt;callable(obj)&lt;br /&gt;chr(i)&lt;br /&gt;cmp(x,y)&lt;br /&gt;coerce(x,y)&lt;br /&gt;compile(string, filename, kind)&lt;br /&gt;complex(real [,img])&lt;br /&gt;delattr(obj, attr)&lt;br /&gt;dir([obj])&lt;br /&gt;divmod(a,b)&lt;br /&gt;eval(expr [, globals [,locals]])&lt;br /&gt;execfile(filename [,globals [,locals]])&lt;br /&gt;filter(function, list)&lt;br /&gt;float(x)&lt;br /&gt;getattr(obj,name)&lt;br /&gt;globals()&lt;br /&gt;hasattr(obj,name)&lt;br /&gt;hash(obj)&lt;br /&gt;hex(x)&lt;br /&gt;id(obj)&lt;br /&gt;input([prompt])&lt;br /&gt;intern(string)&lt;br /&gt;isinstance(obj,class)&lt;br /&gt;issubclass(subclass,class)&lt;br /&gt;len(s)&lt;br /&gt;list(s)&lt;br /&gt;locals()&lt;br /&gt;long(x)&lt;br /&gt;map(function, list, ...)&lt;br /&gt;max(s [,args, ...])&lt;br /&gt;min(s [,args, ...])&lt;br /&gt;oct(x)&lt;br /&gt;open(fname [, mode [, bufsize]])&lt;br /&gt;ord(c)&lt;br /&gt;power(x, y, [,z])&lt;br /&gt;range([start,] stop [,step])&lt;br /&gt;raw_input([prompt])&lt;br /&gt;reduce(func, seq [,initializer])&lt;br /&gt;reload(module)&lt;br /&gt;repr(obj)&lt;br /&gt;round(x [,n])&lt;br /&gt;setattr(obj, name, value)&lt;br /&gt;slice([start,] stop [,step])&lt;br /&gt;str(obj)&lt;br /&gt;tuple(s)&lt;br /&gt;type(obj)&lt;br /&gt;vars([obj])&lt;br /&gt;xrange([start,] stop [, step])&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;# Built-in Exceptions&lt;/span&gt;&lt;br /&gt;Exception&lt;br /&gt;StandardError&lt;br /&gt;ArithmeticError&lt;br /&gt;LookupError&lt;br /&gt;EnvironmentError&lt;br /&gt;AssertionError&lt;br /&gt;AttributeError&lt;br /&gt;EOFError&lt;br /&gt;FloatingPointError&lt;br /&gt;IOError&lt;br /&gt;ImportError&lt;br /&gt;IndexError&lt;br /&gt;KeyError&lt;br /&gt;KeyboardInterrupt&lt;br /&gt;MemoryError&lt;br /&gt;NameError&lt;br /&gt;NotImplementedError&lt;br /&gt;OSError&lt;br /&gt;OverflowError&lt;br /&gt;RuntimeError&lt;br /&gt;SyntaxError&lt;br /&gt;SystemError&lt;br /&gt;SystemExit&lt;br /&gt;TypeError&lt;br /&gt;ValueError&lt;br /&gt;ZeroDivisionError&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;# Internal.&lt;/span&gt;&lt;br /&gt;&gt;&gt;&gt; a = [1,4,6]&lt;br /&gt;&gt;&gt;&gt; a.__doc__&lt;br /&gt;"list() -&gt; new list\nlist(sequence) -&gt; new list initialized from sequence's items"&lt;br /&gt;&gt;&gt;&gt; class C:&lt;br /&gt;...  a = 0&lt;br /&gt;...  def work(self):&lt;br /&gt;...    print("hello world")&lt;br /&gt;...&lt;br /&gt;&gt;&gt;&gt; c = C()&lt;br /&gt;&gt;&gt;&gt; c.__dict__&lt;br /&gt;{}&lt;br /&gt;&gt;&gt;&gt; C.__dict__&lt;br /&gt;{'a': 0, '__module__': '__main__', 'work': &lt;function&gt;, '__doc__': None}&lt;br /&gt;# There are many other built-in attributes for classes, instances, modules ...&lt;br /&gt;&lt;br /&gt;Reference: &lt;span style="font-weight: bold;"&gt;Python Essential Reference&lt;/span&gt; by &lt;span style="font-weight: bold;"&gt;David M. Beazley&lt;/span&gt;&lt;br /&gt;&lt;/function&gt;&lt;/type&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1254518247533161511-8712081167304691609?l=cshinyee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cshinyee.blogspot.com/feeds/8712081167304691609/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1254518247533161511&amp;postID=8712081167304691609&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1254518247533161511/posts/default/8712081167304691609'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1254518247533161511/posts/default/8712081167304691609'/><link rel='alternate' type='text/html' href='http://cshinyee.blogspot.com/2006/09/python-core-language-quick-reference.html' title='Python Core Language Quick Reference'/><author><name>xman</name><uri>http://www.blogger.com/profile/05695636905017529897</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-1254518247533161511.post-3472368378243024159</id><published>2006-09-09T23:32:00.000+08:00</published><updated>2006-09-09T23:53:10.605+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SSH'/><title type='text'>Setup Passwordless SSH</title><content type='html'>It's convenient to setup passwordless SSH in a closed environment. Connecting to remote hosts becomes handy. Passwordless SSH Setup Step-by-Step:&lt;br /&gt;1. Generate RSA public and private keys.&lt;br /&gt;&lt;blockquote&gt;xman@sai ~ $ ssh-keygen -t ssh-rsa&lt;br /&gt;Generating public/private rsa key pair.&lt;br /&gt;Enter file in which to save the key (/home/xman/.ssh/id_rsa):&lt;br /&gt;Created directory '/home/xman/.ssh'.&lt;br /&gt;Enter passphrase (empty for no passphrase):&lt;br /&gt;Enter same passphrase again:&lt;br /&gt;Your identification has been saved in /home/xman/.ssh/id_rsa.&lt;br /&gt;Your public key has been saved in /home/xman/.ssh/id_rsa.pub.&lt;br /&gt;The key fingerprint is:&lt;br /&gt;xx:xx:xx:xxcommand prompt PS for root:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx xman@sai&lt;/blockquote&gt;&lt;br /&gt;You have to enter empty passphrase, trading off security for the convenient connecting to remote hosts.&lt;br /&gt;&lt;br /&gt;2. Append the content of the generated public key, id_rsa.pub, into the file $HOME/.ssh/authorized_keys at the remote host. The folder .ssh and the file authorized_keys at remote host must not allow group, or other access, in particular, set the permissions of .ssh to 700 and authorized_keys to 600.&lt;br /&gt;&lt;br /&gt;Now you can simply "ssh remotehost" without the need to type password. :) The first time you connect to remote host using ssh:&lt;br /&gt;&lt;blockquote&gt;xman@sai ~ $ ssh remotehost&lt;br /&gt;The authenticity of host 'remotehost (192.168.1.100)' can't be established.&lt;br /&gt;RSA key fingerprint is xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx.&lt;br /&gt;Are you sure you want to continue connecting (yes/no)? yes&lt;br /&gt;Warning: Permanently added 'remotehost' (RSA) to the list of known hosts.&lt;br /&gt;Last login: Sat Sep  9 23:50:33 2006 from localhost&lt;br /&gt;xman@remotehost ~ $&lt;br /&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1254518247533161511-3472368378243024159?l=cshinyee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cshinyee.blogspot.com/feeds/3472368378243024159/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1254518247533161511&amp;postID=3472368378243024159&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1254518247533161511/posts/default/3472368378243024159'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1254518247533161511/posts/default/3472368378243024159'/><link rel='alternate' type='text/html' href='http://cshinyee.blogspot.com/2006/09/setup-passwordless-ssh.html' title='Setup Passwordless SSH'/><author><name>xman</name><uri>http://www.blogger.com/profile/05695636905017529897</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-1254518247533161511.post-2421286878391679695</id><published>2006-09-08T11:30:00.000+08:00</published><updated>2006-09-08T16:33:30.188+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Make'/><category scheme='http://www.blogger.com/atom/ns#' term='Quick reference'/><title type='text'>Make Quick Reference</title><content type='html'>Inside Makefile:&lt;blockquote style="font-weight: bold;"&gt;TARGET: DEPENDENCY LINE OR RULES LINE&lt;blockquote&gt;COMMAND&lt;br /&gt;COMMAND&lt;br /&gt;...&lt;/blockquote&gt;&lt;/blockquote&gt;A command line (with TAB in front) is running in a subshell by itself.&lt;br /&gt;&lt;table border="1"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;# A comment.&lt;/td&gt;&lt;td&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;name = text in name&lt;/td&gt;&lt;td&gt;Macro definition.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;$A&lt;/td&gt;&lt;td&gt;Single character macro reference.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;$(name) or ${name}&lt;/td&gt;&lt;td&gt;Macro references.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;make -p&lt;/td&gt;&lt;td&gt;Print internally defined macros.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;make target "DIR=/dir /dir2"&lt;/td&gt;&lt;td&gt;Use DIR defined in command even if you defined DIR in your Makefile!&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;DIR=/bin make target&lt;/td&gt;&lt;td&gt;Use DIR in Makefile if any, otherwise use DIR=/bin.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;make -e&lt;/td&gt;&lt;td&gt;Shell variables have higher priority than file macro definitions.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;FILE=a.c b.c&lt;blockquote&gt;@echo ${FILE:.c=.o}&lt;br /&gt;&lt;b&gt;a.o b.o&lt;/b&gt;&lt;/blockquote&gt;&lt;/td&gt;&lt;td&gt;Replace suffix .c by .o. The @ suppress the printing of commands executed.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;$@&lt;/td&gt;&lt;td&gt;Current target. Use in command line only.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;$?&lt;/td&gt;&lt;td&gt;List of pre-requisites newer than current target. Use in command line only.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;$$@&lt;/td&gt;&lt;td&gt;Current target. Use in dependency line only.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;$*&lt;/td&gt;&lt;td&gt;File name without suffix part. Use in commands in suffix rule only.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;$%&lt;/td&gt;&lt;td&gt;Name of the .o when target is a library module.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;$&lt;&lt;/td&gt;&lt;td&gt;The pre-requisite file. Use in commands in suffix rule only.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;.SUFFIXES: .o .c&lt;/td&gt;&lt;td&gt;Suffixes that &lt;i&gt;make&lt;/i&gt; will consider.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;.c.o:&lt;blockquote&gt;${CC} -c $&lt;&lt;/blockquote&gt;&lt;/td&gt;&lt;td&gt;Suffix rule. To produce .o from a .c.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;t: libm.a(sin.o)&lt;/td&gt;&lt;td&gt;Target t depends on sin.o in libm.a. Hence, if sin.o is newer than libm.a, implicit rule replace newer sin.o into libm.a, then create target t.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;libm.a :: sin.c&lt;br /&gt;libm.a :: cos.c&lt;/td&gt;&lt;td&gt;Rebuild libm.a using different commands depends on the pre-requisites.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;- rm -f *.o&lt;/td&gt;&lt;td&gt;Ignore errors in the command rm, hence, errors will not stop the make process.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;t: a.c \&lt;br /&gt;b.c&lt;/td&gt;&lt;td&gt;Use '\' to continue with the next line.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;.SUFFIXES:&lt;br /&gt;    .SUFFIXES: .a .b&lt;br /&gt;    .SUFFIXES: .c&lt;/td&gt;&lt;td&gt;1. Clear implicit suffixes. 2. Define .a .b suffixes. 3. Add .c into the suffix list.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;.c.a:&lt;blockquote&gt;true&lt;/blockquote&gt;&lt;/td&gt;&lt;td&gt;Override default suffix rule with null command&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;t:&lt;blockquote&gt;echo $$HOME&lt;/blockquote&gt;&lt;/td&gt;&lt;td&gt;Use $$ in commands for environment variable.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;.IGNORE&lt;/td&gt;&lt;td&gt;Force &lt;i&gt;make&lt;/i&gt; to ignore errors and keep going.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;${&amp;#60;D}, ${&amp;#60;F}&lt;/td&gt;&lt;td&gt;Pre-requisite file directory, pre-requisite file name.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;VPATH&lt;/td&gt;&lt;td&gt;View path.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;include inc.mk&lt;/td&gt;&lt;td&gt;Include the file inc.mk.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;.PRECIOUS: a.x b.x&lt;/td&gt;&lt;td&gt;Do not let &lt;i&gt;make&lt;/i&gt; deletes files a.x and b.x.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;.SILENT&lt;/td&gt;&lt;td&gt;Do not echo commands while executing.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;.DEFAULT:&lt;blockquote&gt;echo "hello"&lt;/blockquote&gt;&lt;/td&gt;&lt;td&gt;Define a default action.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Reference: &lt;b&gt;C Programming Utility: Managing Projects with make&lt;/b&gt; by &lt;b&gt;Andrew Oram and Steve Talbott&lt;/b&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1254518247533161511-2421286878391679695?l=cshinyee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cshinyee.blogspot.com/feeds/2421286878391679695/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1254518247533161511&amp;postID=2421286878391679695&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1254518247533161511/posts/default/2421286878391679695'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1254518247533161511/posts/default/2421286878391679695'/><link rel='alternate' type='text/html' href='http://cshinyee.blogspot.com/2006/09/make-quick-reference.html' title='Make Quick Reference'/><author><name>xman</name><uri>http://www.blogger.com/profile/05695636905017529897</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-1254518247533161511.post-8033489119700304676</id><published>2006-09-06T20:18:00.000+08:00</published><updated>2006-09-06T22:45:00.085+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Gawk'/><category scheme='http://www.blogger.com/atom/ns#' term='Quick reference'/><title type='text'>Gawk Quick Reference</title><content type='html'>By default, a record is a line. A line is made up of fields with default delimiter. Main programs are mainly based on C program syntax.&lt;table border="1"&gt;&lt;tr&gt;&lt;td&gt;BEGIN { FS="\t+" }&lt;/td&gt;&lt;td&gt;Initialization. Set field separator to be one or more TABs. Take the string as regular expression if more than 1 characters.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;END { ... }&lt;/td&gt;&lt;td&gt;Finalization. Execute ... after all files have been processed.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;gawk -F"\t" '{ ... }'&lt;/td&gt;&lt;td&gt;Execute with field separator TAB.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;/xyz/ { print }&lt;/td&gt;&lt;td&gt;For each line contain xyz, print the line.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;$1 == 100 { print $2, $3 }&lt;/td&gt;&lt;td&gt;For each line with first field equals 100, print the 2nd and 3rd fields separated by space.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;$3 ~ /PAT/ { print $2 $3 }&lt;/td&gt;&lt;td&gt;If the 3rd field matches PAT, print the concatenated 2nd and 3rd fields.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;$3 !~ /PAT/ { x = 0 }&lt;/td&gt;&lt;td&gt;If the 3rd field doesnt match PAT, let x = 0.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;print $1 OFS $2&lt;/td&gt;&lt;td&gt;Print 1st and 2nd fields separated by output field separator.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;FS, OFS, RS, ORS&lt;/td&gt;&lt;td&gt;Field &amp; output field separator, record &amp; output record separator.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;NF, NR&lt;/td&gt;&lt;td&gt;Number of fields and records.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;FILENAME&lt;/td&gt;&lt;td&gt;Current input file.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;$NF&lt;/td&gt;&lt;td&gt;Last field&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;'${val:-hello}'&lt;/td&gt;&lt;td&gt;In matching region, represents value of $val from the BASH environment, but use "hello" if val is not defined.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;"'${val}'"&lt;/td&gt;&lt;td&gt;In code region, represents value of $val from the BASH environment.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;array[2]="hello"&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;array["i"]="world"&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;for(i in array) print array[i]&lt;/td&gt;&lt;td&gt;Also works for multi-dimensional array.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;if("i" in array) print "found"&lt;/td&gt;&lt;td&gt;Print if "i" is a subscript of array.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;n = split($1, array, ":")&lt;br&gt;for(i = 1; i &lt;= n ; i++) print array[i]&lt;/td&gt;&lt;td&gt;Split 1st field into array with ":" as delimiter.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;array[2,5]="val25"&lt;/td&gt;&lt;td&gt;Equivalent to array["2" SUBSEP "5"]="val25". SUBSEP is a subscript-component separator such as "\034" by default.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;if((i,j) in array)&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;ARGC, ARGV, ENVIRON&lt;/td&gt;&lt;td&gt;Number of arguments, argument array, and environment array.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;index(s,t)&lt;/td&gt;&lt;td&gt;Position of t in s.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;length(s)&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;sub(r,s[,t])&lt;/td&gt;&lt;td&gt;Substitute first match of r in t by s. t is $0 by default.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;match(s,p)&lt;/td&gt;&lt;td&gt;Return starting position of the substring in s that regular expression p matches.&lt;/td&gt;&lt;tr&gt;&lt;td&gt;sprintf("fmt",expr)&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;substr(s,p,n)&lt;/td&gt;&lt;td&gt;The substring of s at position p up to n long.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;toupper(s), tolower(s)&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;function name(list) {&lt;br&gt;statement&lt;br&gt;}&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;getline&lt;/td&gt;&lt;td&gt;Get next line.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;getline &lt;"-"&lt;/td&gt;&lt;td&gt;Get a line from stdin.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;print &gt; "out.txt"&lt;/td&gt;&lt;td&gt;Print to the file out.txt.&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;Reference: &lt;b&gt;UNIX Power Tools: sed &amp; awk&lt;/b&gt; by &lt;b&gt;Dale Dougherty&lt;/b&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1254518247533161511-8033489119700304676?l=cshinyee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cshinyee.blogspot.com/feeds/8033489119700304676/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1254518247533161511&amp;postID=8033489119700304676&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1254518247533161511/posts/default/8033489119700304676'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1254518247533161511/posts/default/8033489119700304676'/><link rel='alternate' type='text/html' href='http://cshinyee.blogspot.com/2006/09/gawk-quick-reference.html' title='Gawk Quick Reference'/><author><name>xman</name><uri>http://www.blogger.com/profile/05695636905017529897</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-1254518247533161511.post-9202865045064776805</id><published>2006-09-04T21:01:00.000+08:00</published><updated>2006-09-04T23:29:21.739+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Sed'/><category scheme='http://www.blogger.com/atom/ns#' term='Quick reference'/><title type='text'>Sed Quick Reference</title><content type='html'>Generic command format:&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;blockquote&gt;[address]command&lt;/blockquote&gt;&lt;/span&gt;command = d, a, i, c, r, w, q, ... d: Delete. a: Append. i: Insert. c: Change. r: Read. w: Write. q: Quit.&lt;br /&gt;&lt;br /&gt;Group command format:&lt;br /&gt;&lt;blockquote style="font-weight: bold;"&gt;address{&lt;br /&gt;command1&lt;br /&gt;command2&lt;br /&gt;command3&lt;br /&gt;}&lt;/blockquote&gt;Substitution format:&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-weight: bold;"&gt;[address]s/pattern/replacement/flags&lt;/span&gt;&lt;/blockquote&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;   flags = n, g, p, or w file. n: A number n represents nth occurrence. g: Global. p: Print. w file: Write to file.&lt;br /&gt;&lt;br /&gt;Transform format:&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;blockquote&gt;[address]y/abc/xyz/&lt;/blockquote&gt;&lt;/span&gt;   Translate a-&gt;x, b-&gt;y, and c-&gt;z.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;[address]&lt;/span&gt; can be lines found by regular expression matches, range of lines.&lt;br /&gt;&lt;table border="1"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;s/abc/xyz/p&lt;/td&gt;&lt;td&gt;Replace abc by xyz, and print (required 'p' if we use "sed -n" to suppress printing all lines).&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;s/abc/pqr/&lt;br /&gt;s/pqr/xyz/&lt;/td&gt;&lt;td&gt;Replace abc by pqr, then replace pqr by xyz. Effectively, abc and pqr becomes xyz.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;/abc/s/pqr/xyz/g&lt;/td&gt;&lt;td&gt;Find lines with abc, then replace pqr in the line by xyz. 'g' -&gt; Replaces all pqr in the line.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1d&lt;/td&gt;&lt;td&gt;Deletes the first line.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;$d&lt;/td&gt;&lt;td&gt;Deletes the last line.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;/^$/d&lt;/td&gt;&lt;td&gt;Deletes blank lines.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;3,10d&lt;/td&gt;&lt;td&gt;Deletes line 3 to line 10 inclusive.&lt;/td&gt;&lt;tr&gt;&lt;td&gt;3,10!d&lt;/td&gt;&lt;td&gt;Deletes all lines except line 3 to line 10 inclusive.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;10,$d&lt;/td&gt;&lt;td&gt;Deletes line 10 to last line inclusive.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;\(abc\)\+&lt;/td&gt;&lt;td&gt;Match one or more abc. Regular expression needs '\'.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;abc+&lt;/td&gt;&lt;td&gt;Match literal abc+.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;# A comment&lt;/td&gt;&lt;td&gt;Comment.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;s!abc!xyz!&lt;/td&gt;&lt;td&gt;Replace abc by xyz, but using ! as delimiter.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;a\abc&lt;/td&gt;&lt;td&gt;Append abc to the matching line.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;i\abc&lt;/td&gt;&lt;td&gt;Insert abc before the matching line.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;c\abc&lt;/td&gt;&lt;td&gt;Change the matching line to abc.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;=&lt;/td&gt;&lt;td&gt;Print line with line number.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;n&lt;/td&gt;&lt;td&gt;Output the contents of the pattern space and read next line.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;r file&lt;/td&gt;&lt;td&gt;Read file.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;w file&lt;/td&gt;&lt;td&gt;Write file.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&amp;amp;&lt;/td&gt;&lt;td&gt;Represent the regular expression matching string (used in replacement string).&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;\3&lt;/td&gt;&lt;td&gt;Match 3th substring in the regular expression using \( \).&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;s/\(a\)\(b\)/\2\1/&lt;/td&gt;&lt;td&gt;Replace ab by ba.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;s/abc/xyz/2&lt;/td&gt;&lt;td&gt;Replace the 2nd abc by xyz.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;There are other commands like multi-line commands (N, D, P), copying/appending pattern space to hold space vice versa (h,H,g,G,x), label(:labelname), branch to label (b), conditional branch (t).&lt;br /&gt;&lt;br /&gt;Reference: &lt;b&gt;UNIX Power Tools: sed &amp; awk&lt;/b&gt; by &lt;b&gt;Dale Dougherty&lt;/b&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1254518247533161511-9202865045064776805?l=cshinyee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cshinyee.blogspot.com/feeds/9202865045064776805/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1254518247533161511&amp;postID=9202865045064776805&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1254518247533161511/posts/default/9202865045064776805'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1254518247533161511/posts/default/9202865045064776805'/><link rel='alternate' type='text/html' href='http://cshinyee.blogspot.com/2006/09/sed-quick-reference.html' title='Sed Quick Reference'/><author><name>xman</name><uri>http://www.blogger.com/profile/05695636905017529897</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-1254518247533161511.post-4346303454446879198</id><published>2006-09-04T20:16:00.000+08:00</published><updated>2006-09-04T20:49:08.883+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Regular expression'/><category scheme='http://www.blogger.com/atom/ns#' term='Quick reference'/><title type='text'>Regular Expression Quick Reference</title><content type='html'>&lt;table border="1"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;.&lt;/td&gt;&lt;td&gt;Match single character except newline.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;x*&lt;/td&gt;&lt;td&gt;Match zero or more x.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;[xyz]&lt;/td&gt;&lt;td&gt;Match a character from x, y or z.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;[^xyz]&lt;/td&gt;&lt;td&gt;Match any single character except x, y, or z.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;[a-zA-Z0-9]&lt;/td&gt;&lt;td&gt;Match a character from a to z, A to Z, or 0 to 9 inclusive.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;^x&lt;/td&gt;&lt;td&gt;Match x at beginning of the line.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;x$&lt;/td&gt;&lt;td&gt;Match x at end of the line.&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;td&gt;x\{2,4\}&lt;/td&gt;&lt;td&gt;Match 2 to 4 x inclusive.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;x+&lt;/td&gt;&lt;td&gt;Match one or more x.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;x?&lt;/td&gt;&lt;td&gt;Match zero or one x.&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;td&gt;x|y&lt;/td&gt;&lt;td&gt;Match either x or y.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;\&lt;/td&gt;&lt;td&gt;Escapes the special character e.g. \t =&gt; TAB, \n =&gt; newline.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;()&lt;/td&gt;&lt;td&gt;Groups regular expressions e.g. (x|y)+.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;Reference: &lt;b&gt;UNIX Power Tools: sed &amp; awk&lt;/b&gt; by &lt;b&gt;Dale Dougherty&lt;/b&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1254518247533161511-4346303454446879198?l=cshinyee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cshinyee.blogspot.com/feeds/4346303454446879198/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1254518247533161511&amp;postID=4346303454446879198&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1254518247533161511/posts/default/4346303454446879198'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1254518247533161511/posts/default/4346303454446879198'/><link rel='alternate' type='text/html' href='http://cshinyee.blogspot.com/2006/09/regular-expression-quick-reference.html' title='Regular Expression Quick Reference'/><author><name>xman</name><uri>http://www.blogger.com/profile/05695636905017529897</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-1254518247533161511.post-5584463261316122924</id><published>2006-08-27T21:20:00.000+08:00</published><updated>2006-08-27T21:50:28.374+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Parallel computing'/><category scheme='http://www.blogger.com/atom/ns#' term='BASH'/><title type='text'>Concurrent BASH: Utilize your Dual-Core or Quad-Core processors</title><content type='html'>We can use &lt;span style="font-weight: bold;"&gt;batch&lt;/span&gt; command to send a series of tasks into a queue, and let it runs by itself. It monitors the &lt;span style="font-weight: bold;"&gt;load average&lt;/span&gt; and admit more tasks when it is low. However, the &lt;span style="font-weight: bold;"&gt;load average&lt;/span&gt; is not changing fast enough for many purposes. In addition, it lacks synchronization facility which is important when you want to make sure some concurrent operations complete before you proceed. Making it &lt;span style="font-weight: bold;"&gt;user-unfriendly&lt;/span&gt;, we have to write the script into a command stream for the batch command.&lt;br /&gt;&lt;br /&gt;Hence, I'm trying to design a system to overcome problems as mentioned. Your BASH program can do like the following:&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-weight: bold;"&gt;prun.bash:&lt;/span&gt;&lt;br /&gt;#!/bin/bash&lt;br /&gt;cd /tmp/xman&lt;br /&gt;date&lt;br /&gt;for i in *.ogg ; do&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-weight: bold;"&gt;    spawn&lt;/span&gt; oggdec *.ogg&lt;/blockquote&gt;done&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;synchronize&lt;br /&gt;&lt;/span&gt;echo "Done"&lt;br /&gt;date&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;exit 0&lt;br /&gt;&lt;br /&gt;xman@sai xman $ &lt;span style="font-weight: bold;"&gt;time ./prun.bash&lt;/span&gt;&lt;br /&gt;Sun Aug 27 21:44:13 SGT 2006&lt;br /&gt;Done&lt;br /&gt;Sun Aug 27 21:44:26 SGT 2006&lt;br /&gt;real    &lt;span style="font-weight: bold;"&gt;0m13.279s&lt;/span&gt;&lt;br /&gt;user    0m0.020s&lt;br /&gt;sys     0m0.072s&lt;br /&gt;&lt;/blockquote&gt;Isnt that's cool? Multiple &lt;span style="font-weight: bold;"&gt;oggdec&lt;/span&gt; which decode ogg files will run in parallel on your dual-core or quad-core machine but with limited max number of threads at a time. The Dual-Core machine completes the decoding in merely 13.3s.&lt;br /&gt;&lt;br /&gt;Now let me decode using serial script. The serial script:&lt;br /&gt;&lt;blockquote&gt;xman@sai xman $ cat run&lt;br /&gt;#!/bin/bash&lt;br /&gt;date&lt;br /&gt;for i in *.ogg ; do&lt;br /&gt; &lt;blockquote&gt;oggdec "$i" &amp;&gt; /dev/null&lt;/blockquote&gt;done&lt;br /&gt;echo "Done"&lt;br /&gt;date&lt;br /&gt;exit 0&lt;br /&gt;&lt;br /&gt;xman@sai xman $ &lt;span style="font-weight: bold;"&gt;time ./run&lt;/span&gt;&lt;br /&gt;Sun Aug 27 21:38:26 SGT 2006&lt;br /&gt;Done&lt;br /&gt;Sun Aug 27 21:38:46 SGT 2006&lt;br /&gt;real    &lt;span style="font-weight: bold;"&gt;0m20.625s&lt;/span&gt;&lt;br /&gt;user    0m19.273s&lt;br /&gt;sys     0m1.004s&lt;br /&gt;&lt;/blockquote&gt;Serial script is unable to utilize two cores simultenously. Hence, it's important to use concurrent facility in order to fully utilize the processors that you are using.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1254518247533161511-5584463261316122924?l=cshinyee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cshinyee.blogspot.com/feeds/5584463261316122924/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1254518247533161511&amp;postID=5584463261316122924&amp;isPopup=true' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1254518247533161511/posts/default/5584463261316122924'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1254518247533161511/posts/default/5584463261316122924'/><link rel='alternate' type='text/html' href='http://cshinyee.blogspot.com/2006/08/concurrent-bash-utilize-your-dual-core.html' title='Concurrent BASH: Utilize your Dual-Core or Quad-Core processors'/><author><name>xman</name><uri>http://www.blogger.com/profile/05695636905017529897</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>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1254518247533161511.post-8719840203242342878</id><published>2006-08-24T21:54:00.000+08:00</published><updated>2006-08-24T22:06:05.668+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='BASH'/><title type='text'>Using BASH to manipulate all files in a directory - Cont</title><content type='html'>&lt;a href="http://blog.chris.tylers.info/"&gt;Chris&lt;/a&gt; pointed out I can simply do&lt;br /&gt;&lt;blockquote style="font-weight: bold;"&gt;for i in *; do echo $i ; done&lt;/blockquote&gt;I can recall I struggled on the problem file names broken into parts. I spent much time to solve it. There is nothing much to argue if all other programs except your current script were written correctly. If you forgot to " " your &lt;strong&gt;$i&lt;/strong&gt;, see what will happen below.&lt;br /&gt;&lt;blockquote&gt;&lt;strong&gt;xman@sai tmp $ ls -Q&lt;br /&gt;"text1.txt" "text version 2.txt"&lt;br /&gt;xman@sai tmp $ for i in * ; do mv $i $i.txt ; done&lt;br /&gt;mv: target `2.txt.txt' is not a directory&lt;br /&gt;xman@sai tmp $&lt;/strong&gt; &lt;/blockquote&gt;Now we have two solutions.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Solution I:&lt;/span&gt;&lt;br /&gt;&lt;blockquote style="font-weight: bold;"&gt;for i in *; do mv "$i" "$i.txt" ; done&lt;/blockquote&gt;But do remember to double quote your file names. ;)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Solution II:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;blockquote&gt;&lt;span style="font-weight: bold;"&gt;export IFS=$'\n'&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;for i in * ; do $i $i.txt ; done&lt;/span&gt;&lt;/blockquote&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;There is nothing wrong if you use "$i".&lt;br /&gt;&lt;br /&gt;Currently, I'm not sure what will break what will not if I set IFS=$'\n'. Certainly, if you are using some broken scripts that forgot to " ", with IFS=$'\n', you are still fine. Then, I'll rather locally use IFS=$'\n'. ;) If IFS=$'\n' does break other things, please tell me!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1254518247533161511-8719840203242342878?l=cshinyee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cshinyee.blogspot.com/feeds/8719840203242342878/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1254518247533161511&amp;postID=8719840203242342878&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1254518247533161511/posts/default/8719840203242342878'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1254518247533161511/posts/default/8719840203242342878'/><link rel='alternate' type='text/html' href='http://cshinyee.blogspot.com/2006/08/using-bash-to-manipulate-all-files-in.html' title='Using BASH to manipulate all files in a directory - Cont'/><author><name>xman</name><uri>http://www.blogger.com/profile/05695636905017529897</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-1254518247533161511.post-4598805249967885676</id><published>2006-08-24T20:48:00.000+08:00</published><updated>2006-08-24T21:42:55.243+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Reversi'/><category scheme='http://www.blogger.com/atom/ns#' term='Benchmark'/><title type='text'>Running Reversi on Multiple Platforms</title><content type='html'>I have made little changes to let the xversi-c to play by itself. Get a copy of the benchmark version now &lt;a href="http://www.cshinyee.zoomshare.com/files/xversi-c-benchmark-v0.1.tgz"&gt;xversi-c-benchmark-v0.1.tgz&lt;/a&gt; with binaries for Linux x86 or x86_64 included. It basically sets evaluation level to 6, so that it will run for a while. I first run it on my PC, surprisingly, the 64bit version is running much faster.&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-weight: bold;"&gt;Host: AMD64 X2 4200+ (2.2GHz)&lt;/span&gt;&lt;br /&gt;Compiler: GCC 4.1.1 64bit&lt;br /&gt;Time    3m0.532s&lt;br /&gt;&lt;br /&gt;Compiler: GCC 4.1.1 32bit&lt;br /&gt;Time    5m7.210s&lt;br /&gt;&lt;/blockquote&gt;Before running this, I thought applications that do not use 64bit data types extensively probably would not benefit from running in 64bit mode. I have yet to investigate the exact causes of this performance difference. I do hope you can shed the light for me if you are experience in this. :)&lt;br /&gt;&lt;br /&gt;See performance of the same program on other platforms, you probably will find another surprises.&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-weight: bold;"&gt;Host: Itanium II 1.5GHz&lt;/span&gt;&lt;br /&gt;Compiler: Intel(R) C Itanium(R) Compiler for Itanium(R)-based applications Version 9.0 Build 20050430 Package ID: l_cc_p_9.0.021&lt;br /&gt;Time    6m35.306s&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Host: Itanium II 1.4GHz&lt;/span&gt;&lt;br /&gt;Compiler: Intel(R) C Itanium(R) Compiler for Itanium(R)-based applications Version 9.0 Build 20051201 Package ID: l_cc_c_9.0.030&lt;br /&gt;Time    7m16.698s&lt;br /&gt;&lt;br /&gt;Compiler: GCC 4.1.0&lt;br /&gt;Time    6m8.471s&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Host: Intel Core Duo 1.83GHz&lt;/span&gt;&lt;br /&gt;Compiler: GCC&lt;br /&gt;Time    5m5.423s&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Host: Intel Pentium 4 HT 3GHz&lt;/span&gt;&lt;br /&gt;Compiler: Intel(R) C Compiler for 32-bit applications, Version 9.0 Build 20051201Z Package ID: l_cc_c_9.0.030&lt;br /&gt;Time    5m7.080s&lt;br /&gt;&lt;br /&gt;Compiler: GCC 4.1.0&lt;br /&gt;Time    4m37.404s&lt;/blockquote&gt;It's quite impressive to see that Intel Core Duo is on par with the Pentium 4 HT 3GHz, considering the clockspeed difference. And the GCC 4.1.0 is actually outperforms the Intel compiler v9 quite significantly. However, I didnt try out all the compiler switches in Intel compiler. On all the platforms, I merely use -O3. Regarding Itanium II, they are famous with their floating-point performance. In this case, that does not apply, as evaluations merely use Integer operations. In addition, Itanium II has lower clockspeed than other platforms. With higher clockspeed, it will probably work faster than other platforms.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1254518247533161511-4598805249967885676?l=cshinyee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cshinyee.blogspot.com/feeds/4598805249967885676/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1254518247533161511&amp;postID=4598805249967885676&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1254518247533161511/posts/default/4598805249967885676'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1254518247533161511/posts/default/4598805249967885676'/><link rel='alternate' type='text/html' href='http://cshinyee.blogspot.com/2006/08/running-reversi-on-multiple-platforms.html' title='Running Reversi on Multiple Platforms'/><author><name>xman</name><uri>http://www.blogger.com/profile/05695636905017529897</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-1254518247533161511.post-8042539777265721645</id><published>2006-08-23T22:12:00.000+08:00</published><updated>2006-08-23T22:23:44.254+08:00</updated><title type='text'>Using BASH to print/manipulate all files in a directory</title><content type='html'>There are two files in my tmp directory.&lt;br /&gt;&lt;blockquote&gt;xman@sai tmp $ &lt;span style="font-weight: bold;"&gt;ls&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;file1.txt  file version 2.txt&lt;/span&gt;&lt;/blockquote&gt;You are probably familiar with simple for-loop in BASH script. But, see the following:&lt;br /&gt;&lt;blockquote&gt;xman@sai tmp $ &lt;span style="font-weight: bold;"&gt;for i in `ls`&lt;/span&gt;&lt;br /&gt;&gt; &lt;span style="font-weight: bold;"&gt;do&lt;/span&gt;&lt;br /&gt;&gt; &lt;span style="font-weight: bold;"&gt;echo $i&lt;/span&gt;&lt;br /&gt;&gt; &lt;span style="font-weight: bold;"&gt;done&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;file1.txt&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;file&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;version&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;2.txt&lt;/span&gt;&lt;br /&gt;xman@sai tmp $&lt;br /&gt;&lt;/blockquote&gt;Opssss, it doesnt print out each of the file names properly when there is space characters in the file names. The file names will be broken when there are spaces. Instead, you probably want to do the following:&lt;br /&gt;&lt;blockquote&gt;xman@sai tmp $ &lt;span style="font-weight: bold;"&gt;export IFS=$'\n'&lt;/span&gt;&lt;br /&gt;xman@sai tmp $ &lt;span style="font-weight: bold;"&gt;for i in `ls`&lt;/span&gt;&lt;br /&gt;&gt; &lt;span style="font-weight: bold;"&gt;do&lt;/span&gt;&lt;br /&gt;&gt; &lt;span style="font-weight: bold;"&gt;echo $i&lt;/span&gt;&lt;br /&gt;&gt; &lt;span style="font-weight: bold;"&gt;done&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;file1.txt&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;file version 2.txt&lt;/span&gt;&lt;br /&gt;xman@sai tmp $&lt;br /&gt;&lt;/blockquote&gt;So now you can manipulate each of the files in a directory properly.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1254518247533161511-8042539777265721645?l=cshinyee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cshinyee.blogspot.com/feeds/8042539777265721645/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1254518247533161511&amp;postID=8042539777265721645&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1254518247533161511/posts/default/8042539777265721645'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1254518247533161511/posts/default/8042539777265721645'/><link rel='alternate' type='text/html' href='http://cshinyee.blogspot.com/2006/08/using-bash-to-printmanipulate-all-files.html' title='Using BASH to print/manipulate all files in a directory'/><author><name>xman</name><uri>http://www.blogger.com/profile/05695636905017529897</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-1254518247533161511.post-4515722604643220146</id><published>2006-08-23T21:18:00.000+08:00</published><updated>2006-08-23T21:51:20.829+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Maui'/><category scheme='http://www.blogger.com/atom/ns#' term='Scheduler'/><category scheme='http://www.blogger.com/atom/ns#' term='Torque'/><category scheme='http://www.blogger.com/atom/ns#' term='PBS'/><title type='text'>Installing &amp; Configuring a Batch Scheduler: Torque + Maui</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Installing Torque (PBS)&lt;/span&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Download and extract the source from &lt;a href="http://www.clusterresources.com/pages/products.php"&gt;Cluster Resources&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&gt; &lt;span style="font-weight: bold;"&gt;./configure --prefix=/usr/local/torque --set-cflags=-O2&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&gt; &lt;span style="font-weight: bold;"&gt;make&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&gt; &lt;span style="font-weight: bold;"&gt;make install&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&gt; &lt;span style="font-weight: bold;"&gt;make packages&lt;/span&gt; &lt;span style="font-style: italic;"&gt;(will generate .sh files for distribution)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;Create a system account TORQUEADMIN&lt;/li&gt;&lt;li&gt;Add /usr/local/torque/bin and /usr/local/torque/sbin to path.&lt;/li&gt;&lt;li&gt;Initialize PBS server files and create default queue.&lt;/li&gt;&lt;ol&gt;&lt;li&gt;&gt; &lt;span style="font-weight: bold;"&gt;./torque.setup TORQUEADMIN&lt;/span&gt;&lt;br /&gt;Note that &lt;span style="font-weight: bold;"&gt;"pbs_server -t create"&lt;/span&gt; is running in background.&lt;br /&gt;torque.setup is similar to following:&lt;/li&gt;&lt;ol&gt;&lt;li&gt;&gt; pbs_server -t create&lt;/li&gt;&lt;li&gt;&gt; qmgr -c "set server scheduling=true"&lt;/li&gt;&lt;li&gt;&gt; qmgr -c "create queue batch queue_type=execution"&lt;/li&gt;&lt;li&gt;&gt; qmgr -c "set queue batch started=true"&lt;/li&gt;&lt;li&gt;&gt; qmgr -c "set queue batch enabled=true"&lt;/li&gt;&lt;li&gt;&gt; qmgr -c "set queue batch resources_default.nodes=1"&lt;/li&gt;&lt;li&gt;&gt; qmgr -c "set queue batch resources_default.walltime=3600"&lt;/li&gt;&lt;li&gt;&gt; qmgr -c "set server default_queue=batch"&lt;/li&gt;&lt;li&gt;&gt; qmgr -c "set server operators += TORQUEADMIN@SERVERNAME"&lt;/li&gt;&lt;li&gt;&gt; qmgr -c "set server managers += TORQUEADMIN@SERVERNAME"&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/ol&gt;&lt;li&gt;Check pbs_server running status.&lt;/li&gt;&lt;ol&gt;&lt;li&gt;&gt; qstat -q&lt;/li&gt;&lt;li&gt;&gt; qmgr -c 'p s'&lt;/li&gt;&lt;li&gt;Stop the pbs_server, runs &lt;span style="font-weight: bold;"&gt;"qterm -t quick"&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;Install pbs_mom into all compute nodes by running the generated script &lt;span style="font-weight: bold;"&gt;torque-package-mom-linux-ia64.sh&lt;/span&gt; in all compute nodes.&lt;/li&gt;&lt;li&gt;Add server node information to compute nodes.&lt;/li&gt;&lt;ol&gt;&lt;li&gt;Create /usr/spool/PBS/server_name with the server hostname.&lt;/li&gt;&lt;ul&gt;&lt;li&gt;&gt; cat /usr/spool/PBS/server_name&lt;br /&gt;&lt;span style="font-style: italic;"&gt;shannon&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Create /usr/spool/PBS/mom_priv/config&lt;/li&gt;&lt;/ol&gt;&lt;ol&gt;&lt;ol&gt;&lt;li&gt;Create the file with the following lines.&lt;br /&gt;$pbsserver     shannon1 # note: IP address of host running pbs_server&lt;br /&gt;$logevent       255&lt;br /&gt;$restricted     shannon1 # note: IP address of host running pbs_server&lt;br /&gt;$usecp shannon1:/home /home&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/ol&gt;&lt;li&gt;Add compute node information to server node&lt;/li&gt;&lt;ol&gt;&lt;li&gt;Create /usr/spool/PBS/server_priv/nodes&lt;/li&gt;&lt;ol&gt;&lt;li&gt;Create the file with the hostnames. e.g.&lt;br /&gt;shannon2 np=2&lt;br /&gt;shannon3 np=2&lt;br /&gt;shannon4 np=2&lt;br /&gt;shannon5 np=2&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/ol&gt;&lt;li&gt;Start pbs_server on server node, and pbs_mom on all compute nodes.&lt;/li&gt;&lt;ol&gt;&lt;li&gt;&gt; &lt;span style="font-weight: bold;"&gt;qterm -t quick&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&gt; &lt;span style="font-weight: bold;"&gt;pbs_server&lt;/span&gt; (in server node)&lt;/li&gt;&lt;li&gt;&gt; &lt;span style="font-weight: bold;"&gt;pbs_mom&lt;/span&gt; (in all compute nodes)&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;Verify torque&lt;/li&gt;&lt;ol&gt;&lt;li&gt;&gt; qstat -q&lt;/li&gt;&lt;li&gt;&gt; pbsnodes -a&lt;/li&gt;&lt;li&gt;&gt; echo "sleep 30" | qsub&lt;/li&gt;&lt;li&gt;&gt; qstat&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/ol&gt;End of Torque installation.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Installing Maui&lt;/span&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Download and extract the source from &lt;a href="http://www.clusterresources.com/pages/products.php"&gt;Cluster Resources&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&gt; &lt;span style="font-weight: bold;"&gt;CFLAGS=-O2 ./configure --with-pbs=/usr/local/torque --with-spooldir=/usr/spool/maui --prefix=/usr/local/maui-3.2.6p13&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&gt; &lt;span style="font-weight: bold;"&gt;make&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&gt; &lt;span style="font-weight: bold;"&gt;make install&lt;/span&gt;&lt;/li&gt;&lt;li&gt;Create a system user mauiadmin.&lt;/li&gt;&lt;li&gt;Edit /usr/spool/maui/maui.cfg&lt;/li&gt;&lt;ol&gt;&lt;li&gt;Set ADMIN1 mauiadmin&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;Add mauiadmin to PBS manager and operator list.&lt;/li&gt;&lt;ol&gt;&lt;li&gt;&gt; qmgr -c "set server managers += mauiadmin@shannon"&lt;/li&gt;&lt;/ol&gt;&lt;ol&gt;&lt;li&gt;&gt; qmgr -c "set server operators += mauiadmin@shannon"&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;Change owner of /usr/spool/maui and /usr/local/maui/sbin to mauiadmin.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;End of installing Maui.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Running Torque and Maui&lt;/span&gt;&lt;br /&gt;1. &lt;span style="font-weight: bold;"&gt;pbs_server&lt;/span&gt; (on server node only, must be started using root).&lt;br /&gt;2. &lt;span style="font-weight: bold;"&gt;pbs_mom&lt;/span&gt; (on compute nodes only, must be started using root).&lt;br /&gt;3. &lt;span style="font-weight: bold;"&gt;maui&lt;/span&gt; (on server node only)&lt;br /&gt;&lt;br /&gt;# Prepared at 16 March 2006&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1254518247533161511-4515722604643220146?l=cshinyee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cshinyee.blogspot.com/feeds/4515722604643220146/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1254518247533161511&amp;postID=4515722604643220146&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1254518247533161511/posts/default/4515722604643220146'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1254518247533161511/posts/default/4515722604643220146'/><link rel='alternate' type='text/html' href='http://cshinyee.blogspot.com/2006/08/installing-configuring-batch-scheduler.html' title='Installing &amp; Configuring a Batch Scheduler: Torque + Maui'/><author><name>xman</name><uri>http://www.blogger.com/profile/05695636905017529897</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-1254518247533161511.post-1246869625007075896</id><published>2006-08-21T21:45:00.000+08:00</published><updated>2006-08-21T22:25:28.695+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Coding style'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Reversi'/><title type='text'>Does it do what you claim it does?</title><content type='html'>I was adding functionality to the Parallel Reversi. I came across this code:&lt;br /&gt;&lt;blockquote style="font-weight: bold;"&gt;    numMove = list.GetNum() ;&lt;br /&gt;  for(i = 0 ; i &lt;= numMove ; i++) { ... }&lt;/blockquote&gt;Oh oooooo ...... how could I make such a mistake? That will cause the accesses to the movelist array out of bound. But it's strange that I had been running the Parallel Reversi for many times without problems. Strange~~~~ I checked the move list implementation to confirm:&lt;br /&gt;&lt;blockquote style="font-weight: bold;"&gt;    public int GetNum() {&lt;br /&gt;      return num ;&lt;br /&gt;  }&lt;/blockquote&gt;Mmmmm, seems like I made a mistake since long time ago. I then changed to&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;blockquote&gt;    for(i = 0 ; i &lt; numMove ; i++) { ... } &lt;/blockquote&gt;&lt;/span&gt;and declared I fix I bug that never give any complaints. Today I checked again and surprisingly find that the variable &lt;span style="font-weight: bold;"&gt;num&lt;/span&gt; range from &lt;span style="font-weight: bold;"&gt;0&lt;/span&gt; to &lt;span style="font-weight: bold;"&gt;Number_of_moves - 1&lt;/span&gt;. Oh nooooooo, I just fixed a correct implementation and introduced a bug. :S :'( ...... The variable names &lt;span style="font-weight: bold;"&gt;num&lt;/span&gt;, &lt;span style="font-weight: bold;"&gt;numMove&lt;/span&gt; quickly lead me to an understanding that they contain value &lt;span style="font-style: italic;"&gt;number of moves&lt;/span&gt;. However, the move list implementation does not do what the variable names claim what they contain. It will be much better if I use &lt;span style="font-weight: bold;"&gt;GetMaxIndex() &lt;/span&gt;rather than &lt;span style="font-weight: bold;"&gt;GetNum()&lt;/span&gt;, or change &lt;span style="font-weight: bold;"&gt;num &lt;/span&gt;to &lt;span style="font-weight: bold;"&gt;index+1&lt;/span&gt;, any ways that make several components consistent. Phew ....... Now I declared the previous fix was a mistake, and now I fixed a mistaken fix.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Lesson learned:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Verify your program does what your variable, function names, or even comments claimed what it does. Otherwise, the consequences could be frustrating, dangering, destructive, ......&lt;/li&gt;&lt;li&gt;If I see such codes in a program, I'll definitely doubt the correctness of the entire program. I should have reviewed my codes for consistency. It's ashame to find this appears in my own programs.&lt;/li&gt;&lt;li&gt;Next question, should I update all calls to &lt;span style="font-weight: bold;"&gt;GetNum()&lt;/span&gt;? If this function is called everywhere, I guess it's not a good idea to anyhow update a reusable component, as my mass updates could be error prone. I shall just add in some &lt;span style="font-weight: bold;"&gt;CONSISTENT&lt;/span&gt; comments in &lt;span style="font-weight: bold;"&gt;GetNum()&lt;/span&gt; to clarify.&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1254518247533161511-1246869625007075896?l=cshinyee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cshinyee.blogspot.com/feeds/1246869625007075896/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1254518247533161511&amp;postID=1246869625007075896&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1254518247533161511/posts/default/1246869625007075896'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1254518247533161511/posts/default/1246869625007075896'/><link rel='alternate' type='text/html' href='http://cshinyee.blogspot.com/2006/08/does-it-do-what-you-claim-it-does.html' title='Does it do what you claim it does?'/><author><name>xman</name><uri>http://www.blogger.com/profile/05695636905017529897</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-1254518247533161511.post-1200904712162660575</id><published>2006-08-20T16:38:00.000+08:00</published><updated>2006-08-20T16:51:37.411+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Parallel computing'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Reversi'/><category scheme='http://www.blogger.com/atom/ns#' term='Board game'/><category scheme='http://www.blogger.com/atom/ns#' term='RMI'/><title type='text'>Running slow using the Parallel version?</title><content type='html'>I recall that the Distributed Parallel Reversi, &lt;a href="http://cshinyee.blogspot.com/2006/08/distributed-parallel-reversi-in-java.html"&gt;xversi-java-parallel-v0.8b&lt;/a&gt;, was able to achieve reasonable speedup when the level of evaluation is large enough. However, when I run it on my AMD Dual-Core machine, I realize the serial version, &lt;a href="http://cshinyee.blogspot.com/2006/08/latest-reversi-in-java-after-much.html"&gt;xversi-java-v0.7a&lt;/a&gt;, is much faster. :S (Jaw drops). I then went to check changes between the serial and parallel versions, what would cause this to happen? ...... after much struggling, I find that I'm using gcj package. Phew~~~~~ The serial version running on GCJ is reasonably fast, but the evaluation is extremely slow in the parallel version. I suppose, the RMI implementation in GCJ is causing delays. Finally, I simply install latest Java package from SUN, and it just runs fast. :) So, now I can increase the level of evaluation to improve the computer's reversi skill.&lt;br /&gt;From my timing of the runs of computer vs computer, it took merely 30 seconds to 1 minute for the SUN Java to complete. However, it took more than 10 minutes for the GCJ Java to run. I dont know how long it will take, I just give up running. :p&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1254518247533161511-1200904712162660575?l=cshinyee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cshinyee.blogspot.com/feeds/1200904712162660575/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1254518247533161511&amp;postID=1200904712162660575&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1254518247533161511/posts/default/1200904712162660575'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1254518247533161511/posts/default/1200904712162660575'/><link rel='alternate' type='text/html' href='http://cshinyee.blogspot.com/2006/08/running-slow-using-parallel-version.html' title='Running slow using the Parallel version?'/><author><name>xman</name><uri>http://www.blogger.com/profile/05695636905017529897</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-1254518247533161511.post-3470583801721851147</id><published>2006-08-20T10:35:00.000+08:00</published><updated>2006-08-20T11:11:27.726+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Parallel computing'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Reversi'/><category scheme='http://www.blogger.com/atom/ns#' term='Download'/><category scheme='http://www.blogger.com/atom/ns#' term='Board game'/><category scheme='http://www.blogger.com/atom/ns#' term='Multi-core'/><category scheme='http://www.blogger.com/atom/ns#' term='RMI'/><category scheme='http://www.blogger.com/atom/ns#' term='Latest release'/><category scheme='http://www.blogger.com/atom/ns#' term='Distributed computing'/><title type='text'>Distributed Parallel Reversi in Java: You have Dual-Core? Quad-Core Processors?</title><content type='html'>Let's catch up with the technology trends on multi-core processors. If you have bought a dual-core, or quad-core, or a large shared memory parallel machine, or a cluster of computers, then you can run this Distributed Parallel Reversi, &lt;a href="http://www.cshinyee.zoomshare.com/files/xversi-java-parallel-v0.8b.tgz"&gt;xversi-java-parallel-v0.8b.tgz&lt;/a&gt;, to make them busy.&lt;br /&gt;Running Distributed Parallel Reversi: Step-by-step&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Launch a server in each of your machines that will provide reversi evaluation services.&lt;br /&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;xman@sai xversi-java-parallel-v0.8b # &lt;span style="font-weight: bold;"&gt;java -Djava.security.policy=xversi.policy XversiEval localhost 9394&lt;/span&gt;&lt;br /&gt;Registered XversiInterface&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;localhost&lt;/span&gt;: Machine name, or its IP.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;9394&lt;/span&gt;: Port number for the client to connect to. Remember to set your firewall to allow this port.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Setup a machine info file called &lt;span style="font-weight: bold;"&gt;nodeinfo.txt&lt;/span&gt;.&lt;br /&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;xman@sai parallel # &lt;span style="font-weight: bold;"&gt;cat nodeinfo.txt&lt;/span&gt;&lt;br /&gt;2&lt;br /&gt;localhost:9394&lt;br /&gt;localhost:9394&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;2&lt;/span&gt;: There are 2 entries about machine information.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;localhost&lt;/span&gt;: Machine name or its IP. I include two identical lines because I'm running this on a dual-processor or dual-core processor machine. This will make the parallel reversi to utilize the two processors in the system.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Launch the Java Applet.&lt;/li&gt;&lt;ul&gt;&lt;li&gt;xman@sai parallel # &lt;span style="font-weight: bold;"&gt;appletviewer -J-Djava.security.policy=xversi.policy test.html&lt;/span&gt;&lt;br /&gt;Number of Node : 2&lt;br /&gt;before lookup&lt;br /&gt;Node 0 localhost:9394&lt;br /&gt;name 0 //localhost:9394/xversiInterface&lt;br /&gt;Node 1 localhost:9394&lt;br /&gt;name 0 //localhost:9394/xversiInterface&lt;br /&gt;after lookup&lt;/li&gt;&lt;li&gt;I've forgotten how do you specify the policy to a browser to launch the Java applet. TELL ME IF YOU KNOW! ;)&lt;/li&gt;&lt;/ul&gt;&lt;/ol&gt;Notice that in picture below, two processors in the system are running at full speed to evaluate different moves at the same time. :) Hence, if you bought a dual-core, quad-core, ... or even a cluster of computers, enjoy the benefit of parallel computing. :) Ideally it will run N times faster with N processors.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;Click to see larger picture&lt;br /&gt;&lt;/div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.cshinyee.zoomshare.com/files/image/parallel_reversi_snapshot1.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://photos1.blogger.com/blogger2/3111/153139434513325/200/parallel_reversi_snapshot1_thumbnail.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1254518247533161511-3470583801721851147?l=cshinyee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cshinyee.blogspot.com/feeds/3470583801721851147/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1254518247533161511&amp;postID=3470583801721851147&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1254518247533161511/posts/default/3470583801721851147'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1254518247533161511/posts/default/3470583801721851147'/><link rel='alternate' type='text/html' href='http://cshinyee.blogspot.com/2006/08/distributed-parallel-reversi-in-java.html' title='Distributed Parallel Reversi in Java: You have Dual-Core? Quad-Core Processors?'/><author><name>xman</name><uri>http://www.blogger.com/profile/05695636905017529897</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-1254518247533161511.post-1861769449907183708</id><published>2006-08-20T09:58:00.000+08:00</published><updated>2006-08-20T10:23:48.458+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Reversi'/><category scheme='http://www.blogger.com/atom/ns#' term='Download'/><category scheme='http://www.blogger.com/atom/ns#' term='Board game'/><category scheme='http://www.blogger.com/atom/ns#' term='Latest release'/><title type='text'>Latest Reversi in Java: After much "backup recovery"</title><content type='html'>The latest Reversi in Java had been kept safely in my backups for quite some time. I recall that I did backup it into CDs, together with many versions of reversi I developed. After backup into CDs, all the files become capital letters, hence, I have to change all the files into correct case before I can launch the Java applet (Stupid backup). That took me quite some time, together with cleaning up many different versions. It was a mistake I didnt use any version control software such as CVS, SVN, ... during development. From now onwards, all changes shall check-in into my svn repository.&lt;br /&gt;Here is the latest Reversi in Java, &lt;a href="http://www.cshinyee.zoomshare.com/files/xversi-java-v0.7a.tgz"&gt;xversi-java-v0.7a.tgz&lt;/a&gt; under GPL, which added some little features on top of xversi-java-v0.6b:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Show a green dot of computer's last move.&lt;/li&gt;&lt;li&gt;Compute end game when the game is near end.&lt;/li&gt;&lt;li&gt;Draws the piece with better aspect ratio as we resize the board.&lt;/li&gt;&lt;/ol&gt;Lessons learned:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Always document your changes to your documents, codes, ... Use tools such as CVS, SVN, ... to help tracking the changes.&lt;/li&gt;&lt;li&gt;I shall prepare a changelog file in the future releases.&lt;/li&gt;&lt;li&gt;Backup each version of your programs into a package such as .tgz, or .zip, such that when you recover from your backup, program files attributes, from filenames to their permissions, are recovered to the original. Versioning helps you to clean up the mess.&lt;/li&gt;&lt;li&gt;Portable is good. :) After few years, these reversi programs are still running properly without much issues. :)&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1254518247533161511-1861769449907183708?l=cshinyee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cshinyee.blogspot.com/feeds/1861769449907183708/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1254518247533161511&amp;postID=1861769449907183708&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1254518247533161511/posts/default/1861769449907183708'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1254518247533161511/posts/default/1861769449907183708'/><link rel='alternate' type='text/html' href='http://cshinyee.blogspot.com/2006/08/latest-reversi-in-java-after-much.html' title='Latest Reversi in Java: After much &quot;backup recovery&quot;'/><author><name>xman</name><uri>http://www.blogger.com/profile/05695636905017529897</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-1254518247533161511.post-342667248205914673</id><published>2006-08-16T23:37:00.000+08:00</published><updated>2006-08-16T23:48:13.029+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Parallel computing'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Reversi'/><category scheme='http://www.blogger.com/atom/ns#' term='Download'/><category scheme='http://www.blogger.com/atom/ns#' term='Board game'/><category scheme='http://www.blogger.com/atom/ns#' term='RMI'/><title type='text'>Reversi in Java: The first presentable board game</title><content type='html'>I believe you'll not want to use command interface to play board game Reversi. Try this out, Reversi in Java &lt;a href="http://www.cshinyee.zoomshare.com/files/xversi-java.tgz"&gt;xversi-java&lt;/a&gt; under GPL. The package includes both source codes and .class files. To play, simply extract files in the package and open the test.html using appletviewer or a browser with Java support.  The implementation is lightweight, all the drawings are generated real-time, without using any picture files.&lt;br /&gt;This had been further extended to use RMI (remote method invocation) to support parallel evaluation. However, it's troublesome to run and requires some security setting of the Java applet to be able to access host file. If you think it's interesting, stay tuned. :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1254518247533161511-342667248205914673?l=cshinyee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cshinyee.blogspot.com/feeds/342667248205914673/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1254518247533161511&amp;postID=342667248205914673&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1254518247533161511/posts/default/342667248205914673'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1254518247533161511/posts/default/342667248205914673'/><link rel='alternate' type='text/html' href='http://cshinyee.blogspot.com/2006/08/reversi-in-java-first-presentable-board.html' title='Reversi in Java: The first presentable board game'/><author><name>xman</name><uri>http://www.blogger.com/profile/05695636905017529897</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-1254518247533161511.post-99772894759755288</id><published>2006-08-16T22:31:00.000+08:00</published><updated>2006-08-16T23:08:35.510+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Alpha beta prunning'/><category scheme='http://www.blogger.com/atom/ns#' term='Reversi'/><category scheme='http://www.blogger.com/atom/ns#' term='Download'/><category scheme='http://www.blogger.com/atom/ns#' term='Board game'/><category scheme='http://www.blogger.com/atom/ns#' term='Game tree'/><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><title type='text'>REVERSI: Yet another program that I had put in storeroom for a long time</title><content type='html'>I started with writing a Reversi board game in Java. Then I ported it to C++, called &lt;a href="http://www.cshinyee.zoomshare.com/files/xversi-c.tgz"&gt;xversi-c&lt;/a&gt; which is under GPL and hope that it will run much faster. The implementation ideas are simple:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Generate all possible moves.&lt;/li&gt;&lt;li&gt;For each of the moves generated above, evaluate and keep the best move.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The real question is, how do we evaluate each of the possible moves?&lt;/li&gt;&lt;li&gt;Just use your imagination, to determine whether a move is good, just find out what are all the next possible moves? what are all the next next possible moves? ...... eventually, the board will be filled up with all the possible moves :)&lt;/li&gt;&lt;li&gt;Practically, we cannot imagine too many moves. At one point, we will want to use some criteria to determine whether a move is good. I have use some simple heuristics to calculate a score for each move.&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Count number of pieces. When game started, we dont want to have many pieces. But as game closer to end game, we want more pieces.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Count mobility, that's the number of moves that each player has. Having more moves, probably means having more controlling power over opponent.&lt;/li&gt;&lt;li&gt;Count the number of corners obtained.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;As the game closer to the end, number of possible moves are limited. Thus, when game is near end, I set it to compute all the possible moves till the end. At the end, evaluation is simple, simply count the number of pieces each player has.&lt;/li&gt;&lt;li&gt;For more information about evaluation, search for Game tree generation with alpha-beta prunning.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Phew..... no point having too many explainations. :) Read the codes if you care. :) I hope it's readable enough. :p&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1254518247533161511-99772894759755288?l=cshinyee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cshinyee.blogspot.com/feeds/99772894759755288/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1254518247533161511&amp;postID=99772894759755288&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1254518247533161511/posts/default/99772894759755288'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1254518247533161511/posts/default/99772894759755288'/><link rel='alternate' type='text/html' href='http://cshinyee.blogspot.com/2006/08/reversi-yet-another-program-that-i-had.html' title='REVERSI: Yet another program that I had put in storeroom for a long time'/><author><name>xman</name><uri>http://www.blogger.com/profile/05695636905017529897</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-1254518247533161511.post-6893498304889570722</id><published>2006-08-15T22:23:00.000+08:00</published><updated>2006-08-15T22:30:28.334+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Download'/><category scheme='http://www.blogger.com/atom/ns#' term='Linux utility'/><category scheme='http://www.blogger.com/atom/ns#' term='BASH'/><category scheme='http://www.blogger.com/atom/ns#' term='Latest release'/><title type='text'>My first open source programs</title><content type='html'>Have been writing many toy programs which end up in the recycle bin, and then flush to no place. I hope from now onwards, my programs can have longer livespan. Let me start with some bash scripts, &lt;a href="http://www.cshinyee.zoomshare.com/files/xmanutility.tgz"&gt;xman utility&lt;/a&gt; under GPL:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;xman_rm: Move given files into the folder ".deleted". So that I can recover the files in the future if we need to.&lt;/li&gt;&lt;li&gt;xman_list_rb: List files deleted using xman_rm.&lt;/li&gt;&lt;li&gt;xman_clean_rb: Delete all files found by xman_list_rb permanently.&lt;/li&gt;&lt;li&gt;xman_create_pdfdb: Process given folder recursively for .pdf files. Convert all .pdf files into .txt and store in database folder.&lt;/li&gt;&lt;li&gt;xman_lowercase: Convert all given file names to lowercase.&lt;/li&gt;&lt;li&gt;xman_uppercase: Convert all given file names to uppercase.&lt;/li&gt;&lt;li&gt;xman_chext: Convert file extension to another extension.&lt;/li&gt;&lt;li&gt;xman_tolower_filter: Convert strings from stdin to lowercase.&lt;/li&gt;&lt;li&gt;xman_toupper_filter: Convert strings from stdin to uppercase.&lt;/li&gt;&lt;/ul&gt;Hope these scripts may help you for your work. If not, you may still learn some bash scripts from these. :) You may also suggest useful scripts for routine work.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1254518247533161511-6893498304889570722?l=cshinyee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cshinyee.blogspot.com/feeds/6893498304889570722/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1254518247533161511&amp;postID=6893498304889570722&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1254518247533161511/posts/default/6893498304889570722'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1254518247533161511/posts/default/6893498304889570722'/><link rel='alternate' type='text/html' href='http://cshinyee.blogspot.com/2006/08/my-first-open-source-programs.html' title='My first open source programs'/><author><name>xman</name><uri>http://www.blogger.com/profile/05695636905017529897</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>
