<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def dropna(self, columns=None, how='any'):
 """ Remove missing values from an SFrame. A missing value is either ``None`` or ``NaN``. If ``how`` is 'any', a row will be removed if any of the columns in the ``columns`` parameter contains at least one missing value. If ``how`` is 'all', a row will be removed if all of the columns in the ``columns`` parameter are missing values. If the ``columns`` parameter is not specified, the default is to consider all columns when searching for missing values. Parameters columns : list or str, optional The columns to use when looking for missing values. By default, all columns are used. how : {'any', 'all'}, optional Specifies whether a row should be dropped if at least one column has missing values, or if all columns have missing values. 'any' is default. Returns ------- out : SFrame SFrame with missing values removed (according to the given rules). See Also -------- dropna_split : Drops missing rows from the SFrame and returns them. Examples -------- Drop all missing values. +---+---+ | a | b | +---+---+ | 1 | a | +---+---+ [1 rows x 2 columns] Drop rows where every value is missing. +------+---+ | a | b | +------+---+ | 1 | a | | None | b | +------+---+ [2 rows x 2 columns] Drop rows where column 'a' has a missing value. +---+---+ | a | b | +---+---+ | 1 | a | +---+---+ [1 rows x 2 columns] """


        # If the user gives me an empty list (the indicator to use all columns)
        # NA values being dropped would not be the expected behavior. This
        # is a NOOP, so let's not bother the server
        if type(columns) is list and len(columns) == 0:
            return SFrame(_proxy=self.__proxy__)

        (columns, all_behavior) = self.__dropna_errchk(columns, how)

        with cython_context():
            return SFrame(_proxy=self.__proxy__.drop_missing_values(columns, all_behavior, False))