1. Console I/O: I generally don't recommend trying to get input from stdin using Python, but if you insist, read on.

    1. Pre-Python 3: Use raw_input(prompt) to get input
      x = raw_input("Enter value: ")
      
      The input comes in as a string and you need to convert it to the appropriate representation using a cast. For example, to convert x to an int, you would use int(x).
    2. Python 3 and later: Use input(prompt) to get input
      1. input(prompt) was defined before Python 3 but it evaluated a string as though it were a python expression
    3. These commands expect input. If you type Ctrl-D to send the EOF character, you will get an exception, not normal termination.
    4. To read from stdin without prompting, use sys.stdin and treat input like a list:
      import sys    # sys is not pre-defined
      for line in sys.stdin:
         process the line of input
      
    5. To break a line of input into fields, use the str.split() method. Use str.strip to strip away leading and trailing whitespace, including the newline character.

  2. String Formatting for Output: Use print to print a string. This section tells you how to create a formatted string for printing
    1. String alignment: For simple alignment, you can use the following commands.
      1. Alignment commands
        1. str.ljust(width): left justifies the string in a field of the specified width
        2. str.rjust(width): right justifies the string in a field of the specified width
        3. str.center(width): centers the string in a field of the specified width
        4. str.zfill(width): left justifies the string in a field of the specified width and fills blanks with 0's
      2. General
        1. all justification commands return a new string rather than modifying the original string
        2. if the string is too big too fit in the specified justification field, then the original string is returned--no truncation is performed and no justification is performed
    2. Formatting a String for Output: The format() method can be used like C's printf method to format strings.
      1. formatstr.format(arg1, arg2, ... argn): returns a formatted string with arg1, arg2, ... argn substituted into formatstr. The original string is not modified.
      2. Examples:
        >>> x = 10
        >>> y = 'brad'
        >>> 'x = {0:8d} and y = {1:20s}--correct?'.format(x,y)
        'x =       10 and y = brad                --correct?'
        >>> 'x = {0:<8d} and y = {1:^20s}--correct?'.format(x,y)
        'x = 10       and y =         brad        --correct?'
        
      3. Syntax
        1. {}'s specify where the arguments should be placed in the string
          1. You may omit the numbers in curly braces, in which case the default numbering is 0, 1, 2, 3, ...
          2. {0.weight}: Accesses the weight property of the 0th argument
          3. {0[i]}: Accesses the element at index i in a sequence
            >>> x = [1, 2, 3, 4]
            >>> 'x[1] = {0[1]}'.format(x)
            'x[1] = 2'
            
          4. {player}: Accesses a keyword argument named player:
            >>> x = 10
            >>> 'x = {player}'.format(player=x)
            'x = 10'
            
          5. For readability put keyword arguments after positional arguments
        2. Format specifiers: Looks much like C's printf except for alignment specifiers
          1. Syntax: {0:formatSpecifiers}
          2. Abbreviated syntax for format specifiers: Everything in []'s is optional. For full syntax see the Formatting Mini-Language.
            [[fill]align][width][.precision][type]
            
          3. fill: any fill character
          4. align: by default numbers are right aligned and strings are left aligned
            OptionMeaning
            < left align
            > right align
            ^ center
          5. width: field width
          6. precision: number of digits after decimal point
          7. type: type of the argument--same types as for printf

  3. File I/O
    1. opening and closing files
      1. open(filename, mode) opens a file and returns a reference to a file object.
        1. mode can be 'r' for read, 'w' for write, and 'a' for append
        2. mode can be omitted in which case it defaults to read
      2. f.close(): closes the file object
      3. Since you often forget to close files, or exceptions may occur and the file does not get closed, it is good to get into the habit of opening files with with
        >>> with open('workfile', 'r') as f:
        ...     read_data = f.read()
        
        When with exits for any reason, the file is automatically closed.
    2. reading from files
      1. f.read(): reads the entire file into a string
      2. f.readline(): reads the next line in the file
        1. the string will include the newline character. Use the string's strip method to strip the newline character.
        2. readline() returns the empty string ('') when EOF is reached. If a line is blank, but not EOF, then readline returns "\n".
      3. You can treat a file like a list:
        for line in f:
           ... process line ...
        
      4. f.readlines(): returns a list of the lines in a file (each line will have the newline character appended)
      5. To break a line of input into fields, use the str.split() method. Use str.strip to strip away leading and trailing whitespace, including the newline character.

    3. writing to files
      1. f.write(string): writes a string to a file
      2. To write anything other than a string to a file, you must convert it to a string using str():
        f.write(str(20))
        
      3. Serialization/deserialization: Serialization refers to the conversion of a complex object to a string representation that can be written to a file. Deserialization refers to the conversion of this string representation back to an object when the string is read from the file.
        1. Two techniques in Python to serialize objects
          1. Json to write lists, dictionaries, sequences, and primitive types to files (but not classes!)

            1. JSON is a standard used for data exchange among applications
            2. Python has a json module that allows objects to be dumped to a file and then re-loaded
            3. json module commands
              1. json.dump(object, fileObject): dumps an object to a file. Only one object may be dumped to a file, so if you want to dump multiple objects, you must bundle them up into a list and then dump the list:
                >>> import json
                >>> a
                [3, 4, 5]
                >>> x
                {'nels': 5, 'brad': 3}
                >>> writeList = [a, x, 543]
                >>> json.dump(writeList, f)
                
              2. json.load(fileObject): Loads the json object from fileObject, parses it, and converts it to the correct Python object
          2. pickle: You can use the pickle module to serialize more complicated objects, such as classes. We won't discuss pickling in this course.