Python Sample

The subclassable types in PythonLanguage 2.2+ make implementing a Stack too easy:

 class Stack(list):
	def push(self, object):

aStack = Stack() aStack.push("world!") aStack.push(3) aStack.push("Hello") print len(aStack) while aStack: print aStack.pop()

Here is a little PythonLanguage script that does a smart search-and-edit over a source tree. I think it shows that Python is just as good for throwaways as PerlLanguage, and much easier to write and understand. (Somebody should insert some tricky code after this to show Python's more advanced features.) -- MartinPool

 import find
 import re

has_id_re = re.compile('String _ID')

search_re = re.compile(r'^(public|protected|final|abstract|\s)*' + '(class|interface)[^{]*\{', re.MULTILINE); id_str = "\n public static final String _ID =\n \"$Id$\";\n";

for f in find.find('*.java'): try: contents = open(f).read() except IOError: continue print f + ": ", if print "*** already done" continue

match = if not match: print "*** no match!" continue

end = match.end()

outfs = open(f, 'w') outfs.write(contents[:end]) outfs.write(id_str) outfs.write(contents[end:]) outfs.close()

print "changed ok"
ouch! if that write fails, you lose. It's probably safer to try: open(f+',','w'), then write, then rename(f+',',f); except: delete(f+',') and puke. -- DanConnolly

The one area where PerlLanguage is better for throwaways than PythonLanguage is DollarUnderscore.

I think $_ is one of the things that makes PerlLanguage hard to read; there are a lot of implied things that happen in Perl that aren't stated in the code; you just have to know what's going on back there to make sense of what's written. This is similar to what makes ForthLanguage and other stack languages (PostScript) hard to read: you can't read it, you have to execute it in your head to keep track of what's on the stack. A small fragment of code can be meaningless out of context: if you don't know what's on the stack (Forth), or don't know what's going on in the implied globals (Perl), you can't say what the code does.

PythonLanguage uses indentation to delimit blocks, which nicely avoids the problem discussed on BadCodingStandards:

	if (a == 42)

Representing namespaces as explicit dictionaries allows, for example, this implementation of AdaLanguage-ish "import as". (By TimPeters:)

 def _pvt_import(globs, modname, *items):
    """globs, modname, *items -> import into globs with leading "_".
       If *items is empty, set globs["_" + modname] to module modname.
       If *items is not empty, import each item similarly but don't
       import the module into globs.
       Leave names that already begin with an underscore as-is.

# import math as _math >>> _pvt_import(globals(), "math") >>> round(_math.pi, 0) 3.0

# import math.sin as _sin and math.floor as _floor >>> _pvt_import(globals(), "math", "sin", "floor") >>> _floor(3.14) 3.0 """

mod = __import__(modname, globals()) if items: for name in items: xname = name if xname[0] != "_": xname = "_" + xname globs[xname] = getattr(mod, name) else: xname = modname if xname[0] != "_": xname = "_" + xname globs[xname] = mod

Here's another cute PythonLanguage sample by MosheZadka:

class CaseCorrector?:

    def __init__(self):
        self.cache = {}

def correct(self, name): try: return self.cache[name] except KeyError?: self.cache[name] = self._correct(name) return self.cache[name]

def _correct(self, name): if os.path.exists(name): return name dir, file = os.path.split(name) dir = self.correct(dir) return os.path.join(dir, self._find_file_in_dir(dir, file))

def _find_file_in_dir(self, dir, file): if os.path.exists(os.path.join(dir, file)): return file file = file.lower() files = dircache.listdir(dir) return files[map(str.lower, files).index(file)]

A few examples of number formatting along the line of readability spectrum by JuneKim:

The most obvious and simplest way is:
    >>> locale.setlocale(locale.LC_ALL,"")
    >>> locale.format("%s",-2345.6789,1)
And if there's some problem setting the locale in the platform:
    >>> def _temp(lc=locale.localeconv()):
            return lc
    >>> locale.localeconv=_temp
    >>> locale.format("%s",12345,1)
And the most elegant way is:
    def sep(s):
        if p==-1: p=len(s)
        for i in range(p-3,s[0] in ('+','-'),-3):
        return s
And the most (or more or less) obfuscated way as a one-liner is:
    def sep(s): return re.sub(r"([-+]?\d{1,3}(\.\d*)?)(?=(\d{3})*(\.|$))",r",\1",s)[1:]

This is a QuickSort function in PythonLanguage.

    def qsort(aList): 
        if not aList: 
                return [] 
        ltList=[y for y in aList[1:] if y<aList[0]] 
        gtList=[y for y in aList[1:] if y>=aList[0]] 
        return qsort(ltList)+[aList[0]]+qsort(gtList) 
-- JuneKim

And as merged into a perverted one-liner:

    def qsort(aList): return aList and qsort([y for y in aList[1:] if y<aList[0]])+[aList[0]]+qsort([y for y in aList[1:] if y>=aList[0]]) or []

Other contributed code: I take it from the examples above that PythonLanguage is soooo easy that no one believes any comments would add to the clarity or value of even an example program ???

Comments are a code smell. The problem with comments is you can't execute them. So they tend to get out of sync with the other parts of the program that you can execute. It is usually possible to structure your code so that it is easily understood without comments. See ToNeedComments, ReplaceCommentWithAssertion, CommentTheWhy

See those hash (#) symbols, and the strings between triple-quotes. These are comments. One can and should document code with docstrings.

 class A(list):
    "this is documentation for class A."
    def b(self, input):
        """The first string after module, class or function definition is docstring.

you can access it using __doc__ attribute. you can also access it by using help() on an instance of this class. Proper whitespacing must be used.""" pass # the pass command does absolutely nothing but something must be stated here, so we choose pass

Here is a little spike for an improved QuickDiff format that would highlight character differences within a slightly changed block (fixing a typo, for example). It uses reflection to map the strings returned by get_opcodes() to the handlers equal, delete, insert, and replace. Feel free to improve it... -- IanOsgood

 from difflib import SequenceMatcher

def styles(): return "span.del { background: yellow }\nspan.ins { background: lightgreen }\n"

def diff(s1,s2): def equal(i1,i2,j1,j2): return s1[i1:i2] def delete(i1,i2,j1,j2): return '<span class="del">' + s1[i1:i2] + '</span>' def insert(i1,i2,j1,j2): return '<span class="ins">' + s2[j1:j2] + '</span>' def replace(i1,i2,j1,j2): return delete(i1,i2,j1,j2) + insert(i1,i2,j1,j2)

sm = SequenceMatcher(None,s1,s2) #print sm.ratio() return ''.join([locals()[op](i1,i2,j1,j2) for op,i1,i2,j1,j2 in sm.get_opcodes()])

# tests

def header(): return "<head><style>\n" + styles() + "</style></head>\n"

def body(s1,s2): return "<body>\n" + diff(s1,s2) + "\n</body>"

print header() + body("Fixign a mispelling.", "Fixing a misspelling.")

External links of interest: See also:

View edit of August 2, 2011 or FindPage with title or text search