Rosettas‎ > ‎

Python


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