Python

Rosetta.py

# Copyright (c) 2008 Art & Logic, Inc. All Rights Reserved.

# $Id: Rosetta.py,v 1.5 2008/02/05 19:48:39 bporter Exp $


# Above: [sf02], [sf03]


# a note on the stuff inside the square brackets:

# Each of the codes inside brackets is a reference to the rule(s) in the

# Style Guide that's being illustrated, as follows:

# [sf##] - StyleGuide/SourceFiles

# [cas##] - StyleGuide/ClassesAndStructures

# [nr##] - StyleGuide/NamingRules

# [cg##] - StyleGuide/Commenting

# [fmt##] - StyleGuide/Formatting


# Throughout: [fmt01]; all indentation done with space characters (0x20),

# three spaces per logical tab stop.


class ARosetta:

"""

A magical, multi-featured class that does many things in a

questionable fashion.

"""


kSomeConstant = 64

kSomeOtherConstant = 90


def __init__(self, fileName):

# [nr05] -- Class members in Python may optionally omit the f prefix,

# since the language requires that they are accessed by qualifying them

# with the current object's self.

self.fileName = fileName

self.inputFile = open(self.fileName, "r")


def close(self):

"""

close() provided in lieu of C++'s destructor syntax.

"""

# [fmt32] -- Explicitly check for None, instead of "if self.inputFile"

# [fmt33] -- Don't need to explicitly compare to True/False when dealing

# with booleans.

if self.inputFile is not None and not self.inputFile.closed:

self.inputFile.close()


def MemberFunctionWithMultipleWords(self):

"""

Demonstrates various code constructs.

"""

for i in range(self.kSomeConstant):

for j in range(self.kSomeOtherConstant):


""" !!! No pre-processor in Python.

// [fmt02] -- preprocessor directives go in column zero.

#ifdef qVerbose

std::clog << "testing: " << i << ", " << j << std::endl;

#endif

"""


# [nr07] -- Calls to member functions of the current object are

# made through an explicit "this" keyword ("self" in Python).

ok = self.Test(i, j)


# [fmt33] -- No need to explicitly compare to True/False when

# dealing with booleans.

if not ok:

print "Fatal error testing %d, %d" % (i, j)

return False


return True


def LongLineWrapping(self):

"""

Demonstrates code line wrapping.

"""

retval = False


# [fmt03] -- source lines should be less than 80 characters long.

# [fmt04] -- break lines at the most logical point

# 1 2 3 4 5 6 7

# 34567890123456789012345678901234567890123456789012345678901234567890123456789

retval = FunctionWithManyArguments(longArgumentName1, longArgumentName2,

longArgumentName3, longArgumentName4)


# alternative format #1

retval = FunctionWithManyArguments(longArgumentName1,

longArgumentName2,

longArgumentName3,

longArgumentName4)


# alternative format #2

retval = FunctionWithManyArguments(

longArgumentName1,

longArgumentName2,

longArgumentName3,

longArgumentName4)


# [fmt05] -- prefer to break after a comma

retval = anObject.SomeUsefulFunction(x.LeftMargin() + x.RightMargin(),

x.TopMargin() + x.BottomMargin() - 1)


# [fmt05] -- if that's not possible, break after an operator

retval = anObject.SomeUsefulFunction(x.LeftMargin() + x.RightMargin() +

anObject.HorizontalPadding(), x.TopMargin() + x.BottomMargin() - 1)


return retval


def Loops(self):

"""

Demonstrates various looping constructs.

"""

# !!! Python has no "for (init; test; increment)" construct.

for i in xrange(self.kSomeConstant):

SomeCodeHere(i)


# [fmt09]

while someBoolean:

someBoolean = SomeFunctionCall()


# [fmt09]

# In Python, use pass statement to indicate an empty block.

while self.SomeFuncReturningBool():

pass


# $$$ Python has no "do-while" syntax.


# [fmt10] -- do/while loop.

# [fmt18] -- exception to the bracing rule saying that braces should

# always be on a line by themselves

#do

#{

# // loop code here...

#} while (someBoolean);


# $$$ end


def Test(self, firstVal, secondVal):

"""

Determines whether the two variables are acceptable.

"""

retval = True


# [fmt07] -- if/else formatting

if firstVal < secondVal:

# [cg06] -- use '$$$' as a marker to indicate a request that the

# following block of code be reviewed before a change is considered

# complete

# $$$ before

# self.Process(secondVal)

# $$$ after

# Shouldn't this be processing the first value in this case?

self.Process(firstVal)

# $$$ end

elif secondVal > self.kSomeConstant:

self.Process(secondVal)

else:

retval = False


return retval


# Use two underscores to simulate private members in Python:

def __Process(self, val):

"""

Executes a process.

"""

result = val


# Python has no increment/precrement operators.


while True:

val -= 1

if 0 == val:

break


result *= val


self.processResult = result


def __Decide(self, midiEventType):

"""

Decides what to do with event described by midiEventType argument.

"""

# Python has no switch/case mechanism, so we either use if/elif/else or

# build some other mechanism with dictionaries.


# [fmt34] -- Place constant value on left side of equivalence tests.

if kNoteOn == midiEventType:

self.NoteOn(now)

if duration > 0:

self.NoteOff(now + duration)

elif kNoteOff == midiEventType:

self.NoteOff(now)

elif kPolyAfter == midiEventType:

after = channelValue

elif kChannelAfter == midiEventType:

self.AfterTouch(after)

elif kPitchBend == midiEventType:

pass

else:

assert False, "Unsupported event type!"

self.LogError("Unsupported event type!")