<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def query(self, query, table_name=None, decode_geom=False, is_select=None):
 """Pull the result from an arbitrary SQL SELECT query from a CARTO account into a pandas DataFrame. This is the default behavior, when `is_select=True` Can also be used to perform database operations (creating/dropping tables, adding columns, updates, etc.). In this case, you have to explicitly specify `is_select=False` This method is a helper for the `CartoContext.fetch` and `CartoContext.execute` methods. We strongly encourage you to use any of those methods depending on the type of query you want to run. If you want to get the results of a `SELECT` query into a pandas DataFrame, then use `CartoContext.fetch`. For any other query that performs an operation into the CARTO database, use `CartoContext.execute` Args: query (str):
 Query to run against CARTO user database. This data will then be converted into a pandas DataFrame. table_name (str, optional):
 If set (and `is_select=True`), this will create a new table in the user's CARTO account that is the result of the SELECT query provided. Defaults to None (no table created). decode_geom (bool, optional):
 Decodes CARTO's geometries into a `Shapely <https://github.com/Toblerity/Shapely>`__ object that can be used, for example, in `GeoPandas <http://geopandas.org/>`__. It only works for SELECT queries when `is_select=True` is_select (bool, optional):
 This argument has to be set depending on the query performed. True for SELECT queries, False for any other query. For the case of a SELECT SQL query (`is_select=True`) the result will be stored into a pandas DataFrame. When an arbitrary SQL query (`is_select=False`) it will perform a database operation (UPDATE, DROP, INSERT, etc.) By default `is_select=None` that means that the method will return a dataframe if the `query` starts with a `select` clause, otherwise it will just execute the query and return `None` Returns: pandas.DataFrame: When `is_select=True` and the query is actually a SELECT query this method returns a pandas DataFrame representation of query supplied otherwise returns None. Pandas data types are inferred from PostgreSQL data types. In the case of PostgreSQL date types, dates are attempted to be converted, but on failure a data type 'object' is used. Raises: CartoException: If there's any error when executing the query Examples: Query a table in CARTO and write a new table that is result of query. This query gets the 10 highest values from a table and returns a dataframe, as well as creating a new table called 'top_ten' in the CARTO account. .. code:: python topten_df = cc.query( ''' SELECT * FROM my_table ORDER BY value_column DESC LIMIT 10 ''', table_name='top_ten' ) This query joins points to polygons based on intersection, and aggregates by summing the values of the points in each polygon. The query returns a dataframe, with a geometry column that contains polygons and also creates a new table called 'points_aggregated_to_polygons' in the CARTO account. .. code:: python points_aggregated_to_polygons = cc.query( ''' SELECT polygons.*, sum(points.values) FROM polygons JOIN points ON ST_Intersects(points.the_geom, polygons.the_geom) GROUP BY polygons.the_geom, polygons.cartodb_id ''', table_name='points_aggregated_to_polygons', decode_geom=True ) Drops `my_table` .. code:: python cc.query( ''' DROP TABLE my_table ''' ) Updates the column `my_column` in the table `my_table` .. code:: python cc.query( ''' UPDATE my_table SET my_column = 1 ''' ) """

        dataframe = None

        is_select_query = is_select or (is_select is None and query.strip().lower().startswith('select'))
        if is_select_query:
            if table_name:
                dataset = Dataset.create_from_query(self, query, table_name)
                dataframe = dataset.download(decode_geom=decode_geom)
            else:
                dataframe = self.fetch(query, decode_geom=decode_geom)
        else:
            self.execute(query)

        return dataframe