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!")