<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def ToJSCode(self, name, columns_order=None, order_by=()):
 """Writes the data table as a JS code string. This method writes a string of JS code that can be run to generate a DataTable with the specified data. Typically used for debugging only. Args: name: The name of the table. The name would be used as the DataTable's variable name in the created JS code. 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. Returns: A string of JS code that, when run, generates a DataTable with the given name and the data stored in the DataTable object. Example result: "var tab1 = new google.visualization.DataTable(); tab1.addColumn("string", "a", "a"); tab1.addColumn("number", "b", "b"); tab1.addColumn("boolean", "c", "c"); tab1.addRows(10); tab1.setCell(0, 0, "a"); tab1.setCell(0, 1, 1, null, {"foo": "bar"}); tab1.setCell(0, 2, true); tab1.setCell(9, 0, "c"); tab1.setCell(9, 1, 3, "3$"); tab1.setCell(9, 2, false);" Raises: DataTableException: The data does not match the type. """


    encoder = DataTableJSONEncoder()

    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])

    # We first create the table with the given name
    jscode = "var %s = new google.visualization.DataTable();\n" % name
    if self.custom_properties:
      jscode += "%s.setTableProperties(%s);\n" % (
          name, encoder.encode(self.custom_properties))

    # We add the columns to the table
    for i, col in enumerate(columns_order):
      jscode += "%s.addColumn(%s, %s, %s);\n" % (
          name,
          encoder.encode(col_dict[col]["type"]),
          encoder.encode(col_dict[col]["label"]),
          encoder.encode(col_dict[col]["id"]))
      if col_dict[col]["custom_properties"]:
        jscode += "%s.setColumnProperties(%d, %s);\n" % (
            name, i, encoder.encode(col_dict[col]["custom_properties"]))
    jscode += "%s.addRows(%d);\n" % (name, len(self.__data))

    # We now go over the data and add each row
    for (i, (row, cp)) in enumerate(self._PreparedData(order_by)):
      # We add all the elements of this row by their order
      for (j, col) in enumerate(columns_order):
        if col not in row or row[col] is None:
          continue
        value = self.CoerceValue(row[col], col_dict[col]["type"])
        if isinstance(value, tuple):
          cell_cp = ""
          if len(value) == 3:
            cell_cp = ", %s" % encoder.encode(row[col][2])
          # We have a formatted value or custom property as well
          jscode += ("%s.setCell(%d, %d, %s, %s%s);\n" %
                     (name, i, j,
                      self.EscapeForJSCode(encoder, value[0]),
                      self.EscapeForJSCode(encoder, value[1]), cell_cp))
        else:
          jscode += "%s.setCell(%d, %d, %s);\n" % (
              name, i, j, self.EscapeForJSCode(encoder, value))
      if cp:
        jscode += "%s.setRowProperties(%d, %s);\n" % (
            name, i, encoder.encode(cp))
    return jscode