<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def sort(self, key_column_names, ascending=True):
 """ Sort current SFrame by the given columns, using the given sort order. Only columns that are type of str, int and float can be sorted. Parameters key_column_names : str | list of str | list of (str, bool) pairs Names of columns to be sorted. The result will be sorted first by first column, followed by second column, and so on. All columns will be sorted in the same order as governed by the `ascending` parameter. To control the sort ordering for each column individually, `key_column_names` must be a list of (str, bool) pairs. Given this case, the first value is the column name and the second value is a boolean indicating whether the sort order is ascending. ascending : bool, optional Sort all columns in the given order. Returns ------- out : SFrame A new SFrame that is sorted according to given sort criteria See Also -------- topk Examples -------- Suppose 'sf' is an sframe that has three columns 'a', 'b', 'c'. To sort by column 'a', ascending +---+---+---+ | a | b | c | +---+---+---+ | 1 | a | x | | 3 | c | y | | 2 | b | z | | 1 | b | y | +---+---+---+ [4 rows x 3 columns] +---+---+---+ | a | b | c | +---+---+---+ | 1 | a | x | | 1 | b | y | | 2 | b | z | | 3 | c | y | +---+---+---+ [4 rows x 3 columns] To sort by column 'a', descending +---+---+---+ | a | b | c | +---+---+---+ | 3 | c | y | | 2 | b | z | | 1 | a | x | | 1 | b | y | +---+---+---+ [4 rows x 3 columns] To sort by column 'a' and 'b', all ascending +---+---+---+ | a | b | c | +---+---+---+ | 1 | a | x | | 1 | b | y | | 2 | b | z | | 3 | c | y | +---+---+---+ [4 rows x 3 columns] To sort by column 'a' ascending, and then by column 'c' descending +---+---+---+ | a | b | c | +---+---+---+ | 1 | b | y | | 1 | a | x | | 2 | b | z | | 3 | c | y | +---+---+---+ [4 rows x 3 columns] """

        sort_column_names = []
        sort_column_orders = []

        # validate key_column_names
        if (type(key_column_names) == str):
            sort_column_names = [key_column_names]
        elif (type(key_column_names) == list):
            if (len(key_column_names) == 0):
                raise ValueError("Please provide at least one column to sort")

            first_param_types = set([type(i) for i in key_column_names])
            if (len(first_param_types) != 1):
                raise ValueError("key_column_names element are not of the same type")

            first_param_type = first_param_types.pop()
            if (first_param_type == tuple):
                sort_column_names = [i[0] for i in key_column_names]
                sort_column_orders = [i[1] for i in key_column_names]
            elif(first_param_type == str):
                sort_column_names = key_column_names
            else:
                raise TypeError("key_column_names type is not supported")
        else:
            raise TypeError("key_column_names type is not correct. Supported types are str, list of str or list of (str,bool) pair.")

        # use the second parameter if the sort order is not given
        if (len(sort_column_orders) == 0):
            sort_column_orders = [ascending for i in sort_column_names]

        # make sure all column exists
        my_column_names = set(self.column_names())
        for column in sort_column_names:
            if (type(column) != str):
                raise TypeError("Only string parameter can be passed in as column names")
            if (column not in my_column_names):
                raise ValueError("SFrame has no column named: '" + str(column) + "'")
            if (self[column].dtype not in (str, int, float,datetime.datetime)):
                raise TypeError("Only columns of type (str, int, float) can be sorted")


        with cython_context():
            return SFrame(_proxy=self.__proxy__.sort(sort_column_names, sort_column_orders))