<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def append(self, other):
 """ Add the rows of an SFrame to the end of this SFrame. Both SFrames must have the same set of columns with the same column names and column types. Parameters other : SFrame Another SFrame whose rows are appended to the current SFrame. Returns ------- out : SFrame The result SFrame from the append operation. Examples -------- +----+-----+ | id | val | +----+-----+ | 4 | D | | 6 | F | | 8 | H | | 1 | A | | 2 | B | | 3 | C | +----+-----+ [6 rows x 2 columns] """

        if type(other) is not SFrame:
            raise RuntimeError("SFrame append can only work with SFrame")

        left_empty = len(self.column_names()) == 0
        right_empty = len(other.column_names()) == 0

        if (left_empty and right_empty):
            return SFrame()

        if (left_empty or right_empty):
            non_empty_sframe = self if right_empty else other
            return non_empty_sframe.__copy__()

        my_column_names = self.column_names()
        my_column_types = self.column_types()
        other_column_names = other.column_names()
        if (len(my_column_names) != len(other_column_names)):
            raise RuntimeError("Two SFrames have to have the same number of columns")

        # check if the order of column name is the same
        column_name_order_match = True
        for i in range(len(my_column_names)):
            if other_column_names[i] != my_column_names[i]:
                column_name_order_match = False
                break

        processed_other_frame = other
        if not column_name_order_match:
            # we allow name order of two sframes to be different, so we create a new sframe from
            # "other" sframe to make it has exactly the same shape
            processed_other_frame = SFrame()
            for i in range(len(my_column_names)):
                col_name = my_column_names[i]
                if(col_name not in other_column_names):
                    raise RuntimeError("Column " + my_column_names[i] + " does not exist in second SFrame")

                other_column = other.select_column(col_name)
                processed_other_frame.add_column(other_column, col_name, inplace=True)

                # check column type
                if my_column_types[i] != other_column.dtype:
                    raise RuntimeError("Column " + my_column_names[i] + " type is not the same in two SFrames, one is " + str(my_column_types[i]) + ", the other is " + str(other_column.dtype))

        with cython_context():
            return SFrame(_proxy=self.__proxy__.append(processed_other_frame.__proxy__))