nodes: 0, module; 1, function_definition; 2, function_name:ToCsv; 3, parameters; 4, block; 5, identifier:self; 6, default_parameter; 7, default_parameter; 8, default_parameter; 9, expression_statement; 10, expression_statement; 11, expression_statement; 12, if_statement; 13, expression_statement; 14, function_definition; 15, expression_statement; 16, comment:# We now go over the data and add each row; 17, for_statement; 18, return_statement; 19, identifier:columns_order; 20, None; 21, identifier:order_by; 22, tuple; 23, identifier:separator; 24, string:","; 25, comment:"""Writes the data table as a CSV string.
  
      Output is encoded in UTF-8 because the Python "csv" module can't handle
      Unicode properly according to its documentation.
  
      Args:
        columns_order: Optional. Specifies the order of columns in the
                       output table. Specify a list of all column IDs in the order
                       in which you want the table created.
                       Note that you must list all column IDs in this parameter,
                       if you use it.
        order_by: Optional. Specifies the name of the column(s) to sort by.
                  Passed as is to _PreparedData.
        separator: Optional. The separator to use between the values.
  
      Returns:
        A CSV string representing the table.
        Example result:
         'a','b','c'
         1,'z',2
         3,'w',''
  
      Raises:
        DataTableException: The data does not match the type.
      """; 26, assignment; 27, assignment; 28, comparison_operator:columns_order is None; 29, block; 30, assignment; 31, function_name:ensure_str; 32, parameters; 33, block; 34, call; 35, pattern_list; 36, call; 37, block; 38, call; 39, identifier:csv_buffer; 40, call; 41, identifier:writer; 42, call; 43, identifier:columns_order; 44, None; 45, expression_statement; 46, identifier:col_dict; 47, call; 48, identifier:s; 49, expression_statement; 50, if_statement; 51, return_statement; 52, attribute; 53, argument_list; 54, identifier:row; 55, identifier:unused_cp; 56, attribute; 57, argument_list; 58, expression_statement; 59, comment:# We add all the elements of this row by their order; 60, for_statement; 61, expression_statement; 62, attribute; 63, argument_list; 64, attribute; 65, argument_list; 66, attribute; 67, argument_list; 68, assignment; 69, identifier:dict; 70, argument_list; 71, string:"Compatibility function. Ensures using of str rather than unicode."; 72, call; 73, block; 74, call; 75, identifier:writer; 76, identifier:writerow; 77, list_comprehension; 78, identifier:self; 79, identifier:_PreparedData; 80, identifier:order_by; 81, assignment; 82, identifier:col; 83, identifier:columns_order; 84, block; 85, call; 86, identifier:csv_buffer; 87, identifier:getvalue; 88, identifier:six; 89, identifier:StringIO; 90, identifier:csv; 91, identifier:writer; 92, identifier:csv_buffer; 93, keyword_argument; 94, identifier:columns_order; 95, list_comprehension; 96, list_comprehension; 97, identifier:isinstance; 98, argument_list; 99, return_statement; 100, attribute; 101, argument_list; 102, call; 103, for_in_clause; 104, identifier:cells_list; 105, list; 106, expression_statement; 107, if_statement; 108, if_statement; 109, attribute; 110, argument_list; 111, identifier:delimiter; 112, identifier:separator; 113, subscript; 114, for_in_clause; 115, tuple; 116, for_in_clause; 117, identifier:s; 118, identifier:str; 119, identifier:s; 120, identifier:s; 121, identifier:encode; 122, string:"utf-8"; 123, identifier:ensure_str; 124, argument_list; 125, identifier:col; 126, identifier:columns_order; 127, assignment; 128, boolean_operator; 129, block; 130, call; 131, comment:# We have a formatted value. Using it only for date/time types.; 132, block; 133, else_clause; 134, identifier:writer; 135, identifier:writerow; 136, identifier:cells_list; 137, identifier:col; 138, string:"id"; 139, identifier:col; 140, attribute; 141, subscript; 142, identifier:col; 143, identifier:col; 144, attribute; 145, subscript; 146, identifier:value; 147, string:""; 148, comparison_operator:col in row; 149, comparison_operator:row[col] is not None; 150, expression_statement; 151, identifier:isinstance; 152, argument_list; 153, if_statement; 154, block; 155, identifier:self; 156, identifier:__columns; 157, identifier:col; 158, string:"id"; 159, identifier:self; 160, identifier:__columns; 161, subscript; 162, string:"label"; 163, identifier:col; 164, identifier:row; 165, subscript; 166, None; 167, assignment; 168, identifier:value; 169, identifier:tuple; 170, comparison_operator:col_dict[col]["type"] in ["date", "datetime", "timeofday"]; 171, block; 172, else_clause; 173, expression_statement; 174, identifier:col_dict; 175, identifier:col; 176, identifier:row; 177, identifier:col; 178, identifier:value; 179, call; 180, subscript; 181, list; 182, expression_statement; 183, block; 184, call; 185, attribute; 186, argument_list; 187, subscript; 188, string:"type"; 189, string:"date"; 190, string:"datetime"; 191, string:"timeofday"; 192, call; 193, expression_statement; 194, attribute; 195, argument_list; 196, identifier:self; 197, identifier:CoerceValue; 198, subscript; 199, subscript; 200, identifier:col_dict; 201, identifier:col; 202, attribute; 203, argument_list; 204, call; 205, identifier:cells_list; 206, identifier:append; 207, call; 208, identifier:row; 209, identifier:col; 210, subscript; 211, string:"type"; 212, identifier:cells_list; 213, identifier:append; 214, call; 215, attribute; 216, argument_list; 217, identifier:ensure_str; 218, argument_list; 219, identifier:col_dict; 220, identifier:col; 221, identifier:ensure_str; 222, argument_list; 223, identifier:cells_list; 224, identifier:append; 225, call; 226, call; 227, call; 228, identifier:ensure_str; 229, argument_list; 230, attribute; 231, argument_list; 232, attribute; 233, argument_list; 234, call; 235, identifier:self; 236, identifier:ToString; 237, identifier:value; 238, identifier:self; 239, identifier:ToString; 240, subscript; 241, attribute; 242, argument_list; 243, identifier:value; 244, integer:1; 245, identifier:self; 246, identifier:ToString; 247, subscript; 248, identifier:value; 249, integer:0
code: def ToCsv(self, columns_order=None, order_by=(), separator=","):
      """Writes the data table as a CSV string.
  
      Output is encoded in UTF-8 because the Python "csv" module can't handle
      Unicode properly according to its documentation.
  
      Args:
        columns_order: Optional. Specifies the order of columns in the
                       output table. Specify a list of all column IDs in the order
                       in which you want the table created.
                       Note that you must list all column IDs in this parameter,
                       if you use it.
        order_by: Optional. Specifies the name of the column(s) to sort by.
                  Passed as is to _PreparedData.
        separator: Optional. The separator to use between the values.
  
      Returns:
        A CSV string representing the table.
        Example result:
         'a','b','c'
         1,'z',2
         3,'w',''
  
      Raises:
        DataTableException: The data does not match the type.
      """
  
      csv_buffer = six.StringIO()
      writer = csv.writer(csv_buffer, delimiter=separator)
  
      if columns_order is None:
        columns_order = [col["id"] for col in self.__columns]
      col_dict = dict([(col["id"], col) for col in self.__columns])
  
      def ensure_str(s):
        "Compatibility function. Ensures using of str rather than unicode."
        if isinstance(s, str):
          return s
        return s.encode("utf-8")
  
      writer.writerow([ensure_str(col_dict[col]["label"])
                       for col in columns_order])
  
      # We now go over the data and add each row
      for row, unused_cp in self._PreparedData(order_by):
        cells_list = []
        # We add all the elements of this row by their order
        for col in columns_order:
          value = ""
          if col in row and row[col] is not None:
            value = self.CoerceValue(row[col], col_dict[col]["type"])
          if isinstance(value, tuple):
            # We have a formatted value. Using it only for date/time types.
            if col_dict[col]["type"] in ["date", "datetime", "timeofday"]:
              cells_list.append(ensure_str(self.ToString(value[1])))
            else:
              cells_list.append(ensure_str(self.ToString(value[0])))
          else:
            cells_list.append(ensure_str(self.ToString(value)))
        writer.writerow(cells_list)
      return csv_buffer.getvalue()