<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def TableDescriptionParser(table_description, depth=0):
 """Parses the table_description object for internal use. Parses the user-submitted table description into an internal format used by the Python DataTable class. Returns the flat list of parsed columns. Args: table_description: A description of the table which should comply with one of the formats described below. depth: Optional. The depth of the first level in the current description. Used by recursive calls to this function. Returns: List of columns, where each column represented by a dictionary with the keys: id, label, type, depth, container which means the following: - id: the id of the column - name: The name of the column - type: The datatype of the elements in this column. Allowed types are described in ColumnTypeParser(). - depth: The depth of this column in the table description - container: 'dict', 'iter' or 'scalar' for parsing the format easily. - custom_properties: The custom properties for this column. The returned description is flattened regardless of how it was given. Raises: DataTableException: Error in a column description or in the description structure. Examples: A column description can be of the following forms: 'id' ('id',) ('id', 'type') ('id', 'type', 'label') ('id', 'type', 'label', {'custom_prop1': 'custom_val1'}) or as a dictionary: 'id': 'type' 'id': ('type',) 'id': ('type', 'label') 'id': ('type', 'label', {'custom_prop1': 'custom_val1'}) If the type is not specified, we treat it as string. If no specific label is given, the label is simply the id. If no custom properties are given, we use an empty dictionary. input: [('a', 'date'), ('b', 'timeofday', 'b', {'foo': 'bar'})] output: [{'id': 'a', 'label': 'a', 'type': 'date', 'depth': 0, 'container': 'iter', 'custom_properties': {}}, {'id': 'b', 'label': 'b', 'type': 'timeofday', 'depth': 0, 'container': 'iter', 'custom_properties': {'foo': 'bar'}}] input: {'a': [('b', 'number'), ('c', 'string', 'column c')]} output: [{'id': 'a', 'label': 'a', 'type': 'string', 'depth': 0, 'container': 'dict', 'custom_properties': {}}, {'id': 'b', 'label': 'b', 'type': 'number', 'depth': 1, 'container': 'iter', 'custom_properties': {}}, {'id': 'c', 'label': 'column c', 'type': 'string', 'depth': 1, 'container': 'iter', 'custom_properties': {}}] input: {('a', 'number', 'column a'):
 { 'b': 'number', 'c': 'string'}} output: [{'id': 'a', 'label': 'column a', 'type': 'number', 'depth': 0, 'container': 'dict', 'custom_properties': {}}, {'id': 'b', 'label': 'b', 'type': 'number', 'depth': 1, 'container': 'dict', 'custom_properties': {}}, {'id': 'c', 'label': 'c', 'type': 'string', 'depth': 1, 'container': 'dict', 'custom_properties': {}}] input: { ('w', 'string', 'word'):
 ('c', 'number', 'count') } output: [{'id': 'w', 'label': 'word', 'type': 'string', 'depth': 0, 'container': 'dict', 'custom_properties': {}}, {'id': 'c', 'label': 'count', 'type': 'number', 'depth': 1, 'container': 'scalar', 'custom_properties': {}}] input: {'a': ('number', 'column a'), 'b': ('string', 'column b')} output: [{'id': 'a', 'label': 'column a', 'type': 'number', 'depth': 0, 'container': 'dict', 'custom_properties': {}}, {'id': 'b', 'label': 'column b', 'type': 'string', 'depth': 0, 'container': 'dict', 'custom_properties': {}} NOTE: there might be ambiguity in the case of a dictionary representation of a single column. For example, the following description can be parsed in 2 different ways: {'a': ('b', 'c')} can be thought of a single column with the id 'a', of type 'b' and the label 'c', or as 2 columns: one named 'a', and the other named 'b' of type 'c'. We choose the first option by default, and in case the second option is the right one, it is possible to make the key into a tuple (i.e. {('a',):
 ('b', 'c')}) or add more info into the tuple, thus making it look like this: {'a': ('b', 'c', 'b', {})} -- second 'b' is the label, and {} is the custom properties field. """

    # For the recursion step, we check for a scalar object (string or tuple)
    if isinstance(table_description, (six.string_types, tuple)):
      parsed_col = DataTable.ColumnTypeParser(table_description)
      parsed_col["depth"] = depth
      parsed_col["container"] = "scalar"
      return [parsed_col]

    # Since it is not scalar, table_description must be iterable.
    if not hasattr(table_description, "__iter__"):
      raise DataTableException("Expected an iterable object, got %s" %
                               type(table_description))
    if not isinstance(table_description, dict):
      # We expects a non-dictionary iterable item.
      columns = []
      for desc in table_description:
        parsed_col = DataTable.ColumnTypeParser(desc)
        parsed_col["depth"] = depth
        parsed_col["container"] = "iter"
        columns.append(parsed_col)
      if not columns:
        raise DataTableException("Description iterable objects should not"
                                 " be empty.")
      return columns
    # The other case is a dictionary
    if not table_description:
      raise DataTableException("Empty dictionaries are not allowed inside"
                               " description")

    # To differentiate between the two cases of more levels below or this is
    # the most inner dictionary, we consider the number of keys (more then one
    # key is indication for most inner dictionary) and the type of the key and
    # value in case of only 1 key (if the type of key is string and the type of
    # the value is a tuple of 0-3 items, we assume this is the most inner
    # dictionary).
    # NOTE: this way of differentiating might create ambiguity. See docs.
    if (len(table_description) != 1 or
        (isinstance(next(six.iterkeys(table_description)), six.string_types) and
         isinstance(next(six.itervalues(table_description)), tuple) and
         len(next(six.itervalues(table_description))) < 4)):
      # This is the most inner dictionary. Parsing types.
      columns = []
      # We sort the items, equivalent to sort the keys since they are unique
      for key, value in sorted(table_description.items()):
        # We parse the column type as (key, type) or (key, type, label) using
        # ColumnTypeParser.
        if isinstance(value, tuple):
          parsed_col = DataTable.ColumnTypeParser((key,) + value)
        else:
          parsed_col = DataTable.ColumnTypeParser((key, value))
        parsed_col["depth"] = depth
        parsed_col["container"] = "dict"
        columns.append(parsed_col)
      return columns
    # This is an outer dictionary, must have at most one key.
    parsed_col = DataTable.ColumnTypeParser(sorted(table_description.keys())[0])
    parsed_col["depth"] = depth
    parsed_col["container"] = "dict"
    return ([parsed_col] + DataTable.TableDescriptionParser(
        sorted(table_description.values())[0], depth=depth + 1))