CS2911
Network Protocols

Source File Structure

  • A source file maintains the following order:
    1. File docstring with required fields
    2. Import statement(s)
    3. Methods
    4. A call to main
  • The file docstring is placed at the start of each source file. It includes the following:
    1. Course
    2. Section
    3. Quarter
    4. Year
    5. Assignment or lab name or number
    6. Student name(s)
    7. A description of the file in one or two sentences.
  • An example of a file docstring is:
    """
    - CS2911 - 021
    - Fall 2017
    - Lab 1 - My First Program
    - Names: 
      - Phileas Fogg
      - Jean Passepartout
      - Aouda
    
    A simple HTTP client.
    """

Special Characters - Never type a literal tab

  • "\t" is used rather than a literal tab character.
  • Four spaces are used instead of a tab character for indentation.

Comments

  • All methods are commented with a docstring. Each parameter and the return value is commented in the Sphinx style. It is not necessary to document the return value if it is always None. Example:
    def send_message(sender, recipient, message_body, priority=1):
       """
       Send a message to a recipient
    
       :param str sender: The person sending the message
       :param str recipient: The recipient of the message
       :param str message_body: The body of the message
       :param priority: The priority of the message, can be a number 1-5
       :type priority: int or None
       :return: the message id
       :rtype: int
       :raises ValueError: if the message_body exceeds 160 characters
       :raises TypeError: if the message_body is not a basestring
       :author: Phileas Fogg
       """
    
  • Inline comments - used when necessary. These are used when the meaning of the code is not obvious from reading the method heading text or to document key design decisions, algorithms, or tasks.
  • Self-documenting code:
    • Meaningful names are used for all variables, parameters, classes, and methods. Names consist of complete words where practical.
    • Named constants are used instead of numeric literals.
    • Boolean variables and methods are not compared to boolean literals.
    • Loop exit/continue conditions are clearly specified in the loop's condition statement. For example, instead of this
      while not isDone:
        # ...
        if len(str) > 0 and str[0] == 'A':
          isDone = true
      
      write
      while len(str) == 0 or str[0] != 'A':
        # ...
      
    • Global variables are not used, but global constants may be. Where it is necessary to move data from one method to another, include it in the return value from one method and pass it as an argument to the other method. Python allows multiple return values, making this easier. For example, instead of
      name = None
      def ask():
          print()
          global name
          name = input('Enter your name: ')
      def greet():
          global name
          print('Welcome, ' + name)
      def main():
          ask()
          greet()
      
      write
      def ask():
          print()
          return input('Enter your name: ')
      def greet(name):
          print('Welcome, ' + name)
      def main():
          name = ask()
          greet(name)
      
  • Flower-boxes or other designs - comments are not enclosed in boxes drawn with asterisks or other characters.

Formatting

  • Variable and Method names - all letters are lowercase and words are separated by underscores if this improves clarity, e.g., python_naming_convention.
  • Global constants - the entire word is capitalized; multiple words are separated by underscores, e.g., DEFAULT_LINE_LENGTH.
  • Braces
    • Indentation - code is indented four spaces for each level of braces.
    • Continued lines - each line of a continuation is formatted in a logical and understandable manner.
    • Column Limit - no line of code (including comments) contains more than 120 characters (the default in PyCharm).

Avoid magic methods

IntelliJ may suggest methods to you with double-underscores before and after the name, like my_list.__contains__('HTTP') or my_bytes.__str__(). These methods are not meant to be called directly. Instead, Python provides special methods or syntax for calling these methods. Learn to use the special syntax instead of using the magic methods directly. Here are some common translations
magic method preferred form
a.__contains__(b) b in a
not a.__contains__(b) b not in a
b.__str__() str(b)
or b.decode('utf-8')
or str(int.from_bytes(b,'big'))
a.__lt__(b) a < b

There are about 100 such methods in Python 3. Most of them are as easy to guess as the str(b) example, but for the rest, you can consult this table

Acknowledgement

This coding standard was developed by the MSOE software engineering faculty and is based upon the SE1011 style guide, PEP 8, PEP 256 (docstrings), the Sphinx docs, Stack Overflow, and other sources.