Instruction:
Given the following Python 3 function, write the documentation
def _add_row(self, index):
        self._index.append(index)
        self._data.append(None)

Response: Add a new row to the Series


Instruction:
Can you generate a brief explanation for the following Python 3 code
def _insert_row(self, i, index):
        if i == len(self._index):
            self._add_row(index)
        else:
            self._index.insert(i, index)
            self._data.insert(i, None)

Response: Insert a new row in the Series.


Instruction:
Here you have a function in Python 3, explain what it does
def _add_missing_rows(self, indexes):
        new_indexes = [x for x in indexes if x not in self._index]
        for x in new_indexes:
            self._add_row(x)

Response: Given a list of indexes add missing rows to the Series.


Instruction:
How would you code a function in Python 3 to
give a list of indexes find all the indexes that are not currently in the Series and insert a new row for those that are not in the index.

Response:
def _insert_missing_rows(self, indexes):
        """
        Given a list of indexes, find all the indexes that are not currently in the Series and make a new row for
        that index, inserting into the index. This requires the Series to be sorted=True

        :param indexes: list of indexes
        :return: nothing
        """
        new_indexes = [x for x in indexes if x not in self._index]
        for x in new_indexes:
            self._insert_row(bisect_left(self._index, x), x)


Instruction:
How would you explain what the following Python 3 function does
def set_cell(self, index, value):
        if self._sort:
            exists, i = sorted_exists(self._index, index)
            if not exists:
                self._insert_row(i, index)
        else:
            try:
                i = self._index.index(index)
            except ValueError:
                i = len(self._index)
                self._add_row(index)
        self._data[i] = value

Response: Sets the value of a single cell.


Instruction:
Write a Python 3 function that can
set the rows of the current DataFrame to a single value or list of values.

Response:
def set_rows(self, index, values=None):
        """
        Set rows to a single value or list of values. If any of the index values are not in the current indexes
        then a new row will be created.

        :param index: list of index values or list of booleans. If a list of booleans then the list must be the same\
        length as the Series
        :param values: either a single value or a list. The list must be the same length as the index list if the index\
        list is values, or the length of the True values in the index list if the index list is booleans
        :return: nothing
        """
        if all([isinstance(i, bool) for i in index]):  # boolean list
            if not isinstance(values, (list, blist)):  # single value provided, not a list, so turn values into list
                values = [values for x in index if x]
            if len(index) != len(self._index):
                raise ValueError('boolean index list must be same size of existing index')
            if len(values) != index.count(True):
                raise ValueError('length of values list must equal number of True entries in index list')
            indexes = [i for i, x in enumerate(index) if x]
            for x, i in enumerate(indexes):
                self._data[i] = values[x]
        else:  # list of index
            if not isinstance(values, (list, blist)):  # single value provided, not a list, so turn values into list
                values = [values for _ in index]
            if len(values) != len(index):
                raise ValueError('length of values and index must be the same.')
            # insert or append indexes as needed
            if self._sort:
                exists_tuples = list(zip(*[sorted_exists(self._index, x) for x in index]))
                exists = exists_tuples[0]
                indexes = exists_tuples[1]
                if not all(exists):
                    self._insert_missing_rows(index)
                    indexes = [sorted_index(self._index, x) for x in index]
            else:
                try:  # all index in current index
                    indexes = [self._index.index(x) for x in index]
                except ValueError:  # new rows need to be added
                    self._add_missing_rows(index)
                    indexes = [self._index.index(x) for x in index]
            for x, i in enumerate(indexes):
                self._data[i] = values[x]


Instruction:
Can you tell what is the following Python 3 function doing
def set_locations(self, locations, values):

        indexes = [self._index[x] for x in locations]
        self.set(indexes, values)

Response: Set the values for a list of locations.


Instruction:
Here you have a function in Python 3, explain what it does
def append_row(self, index, value):
        if index in self._index:
            raise IndexError('index already in Series')

        self._index.append(index)
        self._data.append(value)

Response: Appends a row of value to the end of the data.


Instruction:
Create a Python 3 function to
append the values to the end of the data.

Response:
def append_rows(self, indexes, values):
        """
        Appends values to the end of the data. Be very careful with this function as for sort DataFrames it will not
        enforce sort order. Use this only for speed when needed, be careful.

        :param indexes: list of indexes to append
        :param values: list of values to append
        :return: nothing
        """

        # check that the values data is less than or equal to the length of the indexes
        if len(values) != len(indexes):
            raise ValueError('length of values is not equal to length of indexes')

        # check the indexes are not duplicates
        combined_index = self._index + indexes
        if len(set(combined_index)) != len(combined_index):
            raise IndexError('duplicate indexes in Series')

        # append index value
        self._index.extend(indexes)
        self._data.extend(values)


Instruction:
Create a Python 3 function to
delete rows from the DataFrame COOKIE table.

Response:
def delete(self, indexes):
        """
        Delete rows from the DataFrame

        :param indexes: either a list of values or list of booleans for the rows to delete
        :return: nothing
        """
        indexes = [indexes] if not isinstance(indexes, (list, blist)) else indexes
        if all([isinstance(i, bool) for i in indexes]):  # boolean list
            if len(indexes) != len(self._index):
                raise ValueError('boolean indexes list must be same size of existing indexes')
            indexes = [i for i, x in enumerate(indexes) if x]
        else:
            indexes = [sorted_index(self._index, x) for x in indexes] if self._sort \
                else [self._index.index(x) for x in indexes]
        indexes = sorted(indexes, reverse=True)  # need to sort and reverse list so deleting works
        for i in indexes:
            del self._data[i]
        # now remove from index
        for i in indexes:
            del self._index[i]


Instruction:
Write a Python 3 function that can
reset the index of the Series to simple integer list and the index name to index.

Response:
def reset_index(self):
        """
        Resets the index of the Series to simple integer list and the index name to 'index'.

        :return: nothing
        """
        self.index = list(range(self.__len__()))
        self.index_name = 'index'


Instruction:
Can you create a Python 3 function that
wraps function for get. It will return a list of values or booleans.

Response:
def value(self, indexes, int_as_index=False):
        """
        Wrapper function for get. It will return a list, no index. If the indexes are integers it will be assumed
        that they are locations unless int_as_index = True. If the indexes are locations then they will be rotated to
        the left by offset number of locations.

        :param indexes: integer location, single index, list of indexes or list of boolean
        :param int_as_index: if True then will treat int index values as indexes and not locations
        :return: value or list of values
        """
        # single integer value
        if isinstance(indexes, int):
            if int_as_index:
                return self.get(indexes, as_list=True)
            else:
                indexes = indexes - self._offset
                return self._data[indexes]

        # slice
        elif isinstance(indexes, slice):
            if isinstance(indexes.start, int) and not int_as_index:  # treat as location
                start = indexes.start - self._offset
                stop = indexes.stop - self._offset + 1  # to capture the last value
                # check locations are valid and will not return empty
                if start > stop:
                    raise IndexError('end of slice is before start of slice')
                if (start > 0 > stop) or (start < 0 < stop):
                    raise IndexError('slide indexes invalid with given offset:%f' % self._offset)
                # where end is the last element
                if (start < 0) and stop == 0:
                    return self._data[start:]
                return self._data[start:stop]
            else:  # treat as index
                indexes = self._slice_index(indexes)
                return self.get(indexes, as_list=True)

        # list of booleans
        elif all([isinstance(x, bool) for x in indexes]):
            return self.get(indexes, as_list=True)

        # list of values
        elif isinstance(indexes, list):
            if int_as_index or not isinstance(indexes[0], int):
                return self.get(indexes, as_list=True)
            else:
                indexes = [x - self._offset for x in indexes]
                return self.get_locations(indexes, as_list=True)

        # just a single value
        else:
            return self.get(indexes)


Instruction:
Create a Python 3 function to
create and return a Series from a DataFrame and specific columnname

Response:
def from_dataframe(cls, dataframe, column, offset=0):
        """
        Creates and return a Series from a DataFrame and specific column

        :param dataframe: raccoon DataFrame
        :param column: column name
        :param offset: offset value must be provided as there is no equivalent for a DataFrame
        :return: Series
        """
        return cls(data=dataframe.get_entire_column(column, as_list=True), index=dataframe.index,
                   data_name=column, index_name=dataframe.index_name, sort=dataframe.sort, offset=offset)


Instruction:
Can you create a Python 3 function that
creates and return a Series from a Series

Response:
def from_series(cls, series, offset=0):
        """
        Creates and return a Series from a Series

        :param series: raccoon Series
        :param offset: offset value must be provided as there is no equivalent for a DataFrame
        :return: Series
        """
        return cls(data=series.data, index=series.index, data_name=series.data_name, index_name=series.index_name,
                   sort=series.sort, offset=offset)


Instruction:
Here you have a function in Python 3, explain what it does
def get(self, timeout=None):
        if timeout:
            try:
                result = self._queue.get(True, timeout)
            except multiprocessing.Queue.Empty:
                return(False, None)
            return(True, result)
        return self._queue.get()

Response: Get the next available item from the tube.


Instruction:
Can you generate the documentation for the following Python 3 function
def get(self, timeout=None):
        valid = False
        result = None
        for tube in self._output_tubes:
            if timeout:
                valid, result = tube.get(timeout)
                if valid:
                    result = result[0]
            else:
                result = tube.get()[0]
        if timeout:
            return valid, result
        return result

Response: Retrieve results from all the output tubes.


Instruction:
Can you generate the documentation for the following Python 3 function
def link(self, next_stage):
        if next_stage is self: raise ValueError('cannot link stage to itself')
        self._output_tubes.append(next_stage._input_tube)
        self._next_stages.append(next_stage)
        return self

Response: Link this stage to the given downstream stage.


Instruction:
How would you explain what the following Python 3 function does
def getLeaves(self):
        result = list()
        if not self._next_stages:
            result.append(self)
        else:
            for stage in self._next_stages:
                leaves = stage.getLeaves()
                result += leaves
        return result

Response: Return the downstream leaf stages of this stage.


Instruction:
Write a Python 3 function that can
create and start up the internal workers.

Response:
def build(self):
        """Create and start up the internal workers."""

        # If there's no output tube, it means that this stage
        # is at the end of a fork (hasn't been linked to any stage downstream).
        # Therefore, create one output tube.
        if not self._output_tubes:
            self._output_tubes.append(self._worker_class.getTubeClass()())

        self._worker_class.assemble(
            self._worker_args,
            self._input_tube,
            self._output_tubes,
            self._size,
            self._disable_result,
            self._do_stop_task,
            )

        # Build all downstream stages.
        for stage in self._next_stages:
            stage.build()


Instruction:
Given the following Python 3 function, write the documentation
def get(self, timeout=None):
        if timeout:
            # Todo: Consider locking the poll/recv block.
            # Otherwise, this method is not thread safe.
            if self._conn1.poll(timeout):
                return (True, self._conn1.recv())
            else:
                return (False, None)
        return self._conn1.recv()

Response: Return the next available item from the tube.


Instruction:
Can you tell what is the following Python 3 function doing
def _sort_columns(self, columns_list):
        if not (all([x in columns_list for x in self._columns]) and all([x in self._columns for x in columns_list])):
            raise ValueError(
                'columns_list must be all in current columns, and all current columns must be in columns_list')
        new_sort = [self._columns.index(x) for x in columns_list]
        self._data = blist([self._data[x] for x in new_sort]) if self._blist else [self._data[x] for x in new_sort]
        self._columns = blist([self._columns[x] for x in new_sort]) if self._blist \
            else [self._columns[x] for x in new_sort]

Response: This function will sort the columns of the DataFrame to match the given order.


Instruction:
Create a Python 3 function to
pad the data in DataFrame with [ None ] to ensure that all columns have the same length.

Response:
def _pad_data(self, max_len=None):
        """
        Pad the data in DataFrame with [None} to ensure that all columns have the same length.

        :param max_len: If provided will extend all columns to this length, if not then will use the longest column
        :return: nothing
        """
        if not max_len:
            max_len = max([len(x) for x in self._data])
        for _, col in enumerate(self._data):
            col.extend([None] * (max_len - len(col)))


Instruction:
Given the following Python 3 function, write the documentation
def get(self, indexes=None, columns=None, as_list=False, as_dict=False):
        if (indexes is None) and (columns is not None) and (not isinstance(columns, (list, blist))):
            return self.get_entire_column(columns, as_list)

        if indexes is None:
            indexes = [True] * len(self._index)
        if columns is None:
            columns = [True] * len(self._columns)

        if isinstance(indexes, (list, blist)) and isinstance(columns, (list, blist)):
            return self.get_matrix(indexes, columns)
        elif isinstance(indexes, (list, blist)) and (not isinstance(columns, (list, blist))):
            return self.get_rows(indexes, columns, as_list)
        elif (not isinstance(indexes, (list, blist))) and isinstance(columns, (list, blist)):
            return self.get_columns(indexes, columns, as_dict)
        else:
            return self.get_cell(indexes, columns)

Response: This method will return a sub - set of the DataFrame.


Instruction:
Can you generate the documentation for the following Python 3 function
def get_cell(self, index, column):
        i = sorted_index(self._index, index) if self._sort else self._index.index(index)
        c = self._columns.index(column)
        return self._data[c][i]

Response: Returns the value of the cell with the given index and column.


Instruction:
How would you implement a function in Python 3 that
returns a DataFrame containing the values of the indexes in that column.

Response:
def get_rows(self, indexes, column, as_list=False):
        """
        For a list of indexes and a single column name return the values of the indexes in that column.

        :param indexes: either a list of index values or a list of booleans with same length as all indexes
        :param column: single column name
        :param as_list: if True return a list, if False return DataFrame
        :return: DataFrame is as_list if False, a list if as_list is True
        """
        c = self._columns.index(column)
        if all([isinstance(i, bool) for i in indexes]):  # boolean list
            if len(indexes) != len(self._index):
                raise ValueError('boolean index list must be same size of existing index')
            if all(indexes):  # the entire column
                data = self._data[c]
                index = self._index
            else:
                data = list(compress(self._data[c], indexes))
                index = list(compress(self._index, indexes))
        else:  # index values list
            locations = [sorted_index(self._index, x) for x in indexes] if self._sort \
                else [self._index.index(x) for x in indexes]
            data = [self._data[c][i] for i in locations]
            index = [self._index[i] for i in locations]
        return data if as_list else DataFrame(data={column: data}, index=index, index_name=self._index_name,
                                              sort=self._sort)


Instruction:
Can you generate a brief explanation for the following Python 3 code
def get_columns(self, index, columns=None, as_dict=False):
        i = sorted_index(self._index, index) if self._sort else self._index.index(index)
        return self.get_location(i, columns, as_dict)

Response: Get the columns of a single index and list of column names


Instruction:
Create a Python 3 function to
get the entire column of the data table.

Response:
def get_entire_column(self, column, as_list=False):
        """
        Shortcut method to retrieve a single column all rows. Since this is a common use case this method will be
        faster than the more general method.

        :param column: single column name
        :param as_list: if True return a list, if False return DataFrame
        :return: DataFrame is as_list if False, a list if as_list is True
        """
        c = self._columns.index(column)
        data = self._data[c]
        return data if as_list else DataFrame(data={column: data}, index=self._index, index_name=self._index_name,
                                              sort=self._sort)


Instruction:
Write a Python 3 script for
returning a DataFrame of the values for a list of indexes and columns.

Response:
def get_matrix(self, indexes, columns):
        """
        For a list of indexes and list of columns return a DataFrame of the values.

        :param indexes: either a list of index values or a list of booleans with same length as all indexes
        :param columns: list of column names
        :return: DataFrame
        """
        if all([isinstance(i, bool) for i in indexes]):  # boolean list
            is_bool_indexes = True
            if len(indexes) != len(self._index):
                raise ValueError('boolean index list must be same size of existing index')
            bool_indexes = indexes
            indexes = list(compress(self._index, indexes))
        else:
            is_bool_indexes = False
            locations = [sorted_index(self._index, x) for x in indexes] if self._sort \
                else [self._index.index(x) for x in indexes]

        if all([isinstance(i, bool) for i in columns]):  # boolean list
            if len(columns) != len(self._columns):
                raise ValueError('boolean column list must be same size of existing columns')
            columns = list(compress(self._columns, columns))

        col_locations = [self._columns.index(x) for x in columns]
        data_dict = dict()

        for c in col_locations:
            data_dict[self._columns[c]] = list(compress(self._data[c], bool_indexes)) if is_bool_indexes \
                else [self._data[c][i] for i in locations]

        return DataFrame(data=data_dict, index=indexes, columns=columns, index_name=self._index_name,
                         sort=self._sort)


Instruction:
How would you implement a function in Python 3 that
returns a DataFrame or dictionary of the values of the column with the given location.

Response:
def get_location(self, location, columns=None, as_dict=False, index=True):
        """
        For an index location and either (1) list of columns return a DataFrame or dictionary of the values or
        (2) single column name and return the value of that cell. This is optimized for speed because it does not need
        to lookup the index location with a search. Also can accept relative indexing from the end of the DataFrame
        in standard python notation [-3, -2, -1]

        :param location: index location in standard python form of positive or negative number
        :param columns: list of columns, single column name, or None to include all columns
        :param as_dict: if True then return a dictionary
        :param index: if True then include the index in the dictionary if as_dict=True
        :return: DataFrame or dictionary if columns is a list or value if columns is a single column name
        """
        if columns is None:
            columns = self._columns
        elif not isinstance(columns, list):  # single value for columns
            c = self._columns.index(columns)
            return self._data[c][location]
        elif all([isinstance(i, bool) for i in columns]):
            if len(columns) != len(self._columns):
                raise ValueError('boolean column list must be same size of existing columns')
            columns = list(compress(self._columns, columns))
        data = dict()
        for column in columns:
            c = self._columns.index(column)
            data[column] = self._data[c][location]
        index_value = self._index[location]
        if as_dict:
            if index:
                data[self._index_name] = index_value
            return data
        else:
            data = {k: [data[k]] for k in data}  # this makes the dict items lists
            return DataFrame(data=data, index=[index_value], columns=columns, index_name=self._index_name,
                             sort=self._sort)


Instruction:
Write a Python 3 script to
return a DataFrame or tuple of the index and data values of the entry in the table.

Response:
def get_slice(self, start_index=None, stop_index=None, columns=None, as_dict=False):
        """
        For sorted DataFrames will return either a DataFrame or dict of all of the rows where the index is greater than
        or equal to the start_index if provided and less than or equal to the stop_index if provided. If either the
        start or stop index is None then will include from the first or last element, similar to standard python
        slide of [:5] or [:5]. Both end points are considered inclusive.

        :param start_index: lowest index value to include, or None to start from the first row
        :param stop_index: highest index value to include, or None to end at the last row
        :param columns: list of column names to include, or None for all columns
        :param as_dict: if True then return a tuple of (list of index, dict of column names: list data values)
        :return: DataFrame or tuple
        """
        if not self._sort:
            raise RuntimeError('Can only use get_slice on sorted DataFrames')

        if columns is None:
            columns = self._columns
        elif all([isinstance(i, bool) for i in columns]):
            if len(columns) != len(self._columns):
                raise ValueError('boolean column list must be same size of existing columns')
            columns = list(compress(self._columns, columns))

        start_location = bisect_left(self._index, start_index) if start_index is not None else None
        stop_location = bisect_right(self._index, stop_index) if stop_index is not None else None

        index = self._index[start_location:stop_location]
        data = dict()
        for column in columns:
            c = self._columns.index(column)
            data[column] = self._data[c][start_location:stop_location]

        if as_dict:
            return index, data
        else:
            data = data if data else None  # if the dict is empty, convert to None
            return DataFrame(data=data, index=index, columns=columns, index_name=self._index_name, sort=self._sort,
                             use_blist=self._blist)


Instruction:
Here you have a function in Python 3, explain what it does
def _insert_row(self, i, index):
        if i == len(self._index):
            self._add_row(index)
        else:
            self._index.insert(i, index)
            for c in range(len(self._columns)):
                self._data[c].insert(i, None)

Response: Insert a new row in the DataFrame.


Instruction:
Write a Python 3 function for
adding a new row to the DataFrame.

Response:
def _add_row(self, index):
        """
        Add a new row to the DataFrame

        :param index: index of the new row
        :return: nothing
        """
        self._index.append(index)
        for c, _ in enumerate(self._columns):
            self._data[c].append(None)


Instruction:
Can you create a Python 3 function that
adds a new column to the DataFrame.

Response:
def _add_column(self, column):
        """
        Add a new column to the DataFrame

        :param column: column name
        :return: nothing
        """
        self._columns.append(column)
        if self._blist:
            self._data.append(blist([None] * len(self._index)))
        else:
            self._data.append([None] * len(self._index))


Instruction:
Create a Python 3 function for
giving indexes and columns will set a sub-set of the DataFrame to the values provided. This method will direct to the below methods based on what types are passed in for the indexes and columns. If the indexes or columns contains values not in the DataFrame then new rows or columns will be added. :param indexes: indexes value, list of indexes values, or a list of booleans. If None then all indexes are used :param columns: columns name, if None then all columns are used. Currently can only handle a single column or\ all columns :param values: value or list of values to set (index, column) to. If setting just a single row, then must be a\ dict where the keys are the column names. If a list then must be the same length as the indexes parameter, if\ indexes=None, then must be the same and length of DataFrame :return: nothing

Response:
def set(self, indexes=None, columns=None, values=None):
        """
        Given indexes and columns will set a sub-set of the DataFrame to the values provided. This method will direct
        to the below methods based on what types are passed in for the indexes and columns. If the indexes or columns
        contains values not in the DataFrame then new rows or columns will be added.

        :param indexes: indexes value, list of indexes values, or a list of booleans. If None then all indexes are used
        :param columns: columns name, if None then all columns are used. Currently can only handle a single column or\
        all columns
        :param values: value or list of values to set (index, column) to. If setting just a single row, then must be a\
        dict where the keys are the column names. If a list then must be the same length as the indexes parameter, if\
        indexes=None, then must be the same and length of DataFrame
        :return: nothing
        """
        if (indexes is not None) and (columns is not None):
            if isinstance(indexes, (list, blist)):
                self.set_column(indexes, columns, values)
            else:
                self.set_cell(indexes, columns, values)
        elif (indexes is not None) and (columns is None):
            self.set_row(indexes, values)
        elif (indexes is None) and (columns is not None):
            self.set_column(indexes, columns, values)
        else:
            raise ValueError('either or both of indexes or columns must be provided')


Instruction:
Can you implement a function in Python 3 that
sets the value of a single cell.

Response:
def set_cell(self, index, column, value):
        """
        Sets the value of a single cell. If the index and/or column is not in the current index/columns then a new
        index and/or column will be created.

        :param index: index value
        :param column: column name
        :param value: value to set
        :return: nothing
        """
        if self._sort:
            exists, i = sorted_exists(self._index, index)
            if not exists:
                self._insert_row(i, index)
        else:
            try:
                i = self._index.index(index)
            except ValueError:
                i = len(self._index)
                self._add_row(index)
        try:
            c = self._columns.index(column)
        except ValueError:
            c = len(self._columns)
            self._add_column(column)
        self._data[c][i] = value


Instruction:
Can you generate the documentation for the following Python 3 function
def set_row(self, index, values):
        if self._sort:
            exists, i = sorted_exists(self._index, index)
            if not exists:
                self._insert_row(i, index)
        else:
            try:
                i = self._index.index(index)
            except ValueError:  # new row
                i = len(self._index)
                self._add_row(index)
        if isinstance(values, dict):
            if not (set(values.keys()).issubset(self._columns)):
                raise ValueError('keys of values are not all in existing columns')
            for c, column in enumerate(self._columns):
                self._data[c][i] = values.get(column, self._data[c][i])
        else:
            raise TypeError('cannot handle values of this type.')

Response: Sets the values of the columns in a single row.


Instruction:
Write a Python 3 function that can
set a column to a single value or list of values.

Response:
def set_column(self, index=None, column=None, values=None):
        """
        Set a column to a single value or list of values. If any of the index values are not in the current indexes
        then a new row will be created.

        :param index: list of index values or list of booleans. If a list of booleans then the list must be the same\
        length as the DataFrame
        :param column: column name
        :param values: either a single value or a list. The list must be the same length as the index list if the index\
        list is values, or the length of the True values in the index list if the index list is booleans
        :return: nothing
        """
        try:
            c = self._columns.index(column)
        except ValueError:  # new column
            c = len(self._columns)
            self._add_column(column)
        if index:  # index was provided
            if all([isinstance(i, bool) for i in index]):  # boolean list
                if not isinstance(values, (list, blist)):  # single value provided, not a list, so turn values into list
                    values = [values for x in index if x]
                if len(index) != len(self._index):
                    raise ValueError('boolean index list must be same size of existing index')
                if len(values) != index.count(True):
                    raise ValueError('length of values list must equal number of True entries in index list')
                indexes = [i for i, x in enumerate(index) if x]
                for x, i in enumerate(indexes):
                    self._data[c][i] = values[x]
            else:  # list of index
                if not isinstance(values, (list, blist)):  # single value provided, not a list, so turn values into list
                    values = [values for _ in index]
                if len(values) != len(index):
                    raise ValueError('length of values and index must be the same.')
                # insert or append indexes as needed
                if self._sort:
                    exists_tuples = list(zip(*[sorted_exists(self._index, x) for x in index]))
                    exists = exists_tuples[0]
                    indexes = exists_tuples[1]
                    if not all(exists):
                        self._insert_missing_rows(index)
                        indexes = [sorted_index(self._index, x) for x in index]
                else:
                    try:  # all index in current index
                        indexes = [self._index.index(x) for x in index]
                    except ValueError:  # new rows need to be added
                        self._add_missing_rows(index)
                        indexes = [self._index.index(x) for x in index]
                for x, i in enumerate(indexes):
                    self._data[c][i] = values[x]
        else:  # no index, only values
            if not isinstance(values, (list, blist)):  # values not a list, turn into one of length same as index
                values = [values for _ in self._index]
            if len(values) != len(self._index):
                raise ValueError('values list must be at same length as current index length.')
            else:
                self._data[c] = blist(values) if self._blist else values


Instruction:
Can you create a Python 3 function that
sets the values for the column values for the row at the given location.

Response:
def set_location(self, location, values, missing_to_none=False):
        """
        Sets the column values, as given by the keys of the values dict, for the row at location to the values of the
        values dict. If missing_to_none is False then columns not in the values dict will be left unchanged, if it is
        True then they are set to None. This method does not add new columns and raises an error.

        :param location: location
        :param values: dict of column names as keys and the value as the value to set the row for that column to
        :param missing_to_none: if True set any column missing in the values to None, otherwise leave unchanged
        :return: nothing
        """
        if missing_to_none:
            # populate the dict with None in any column missing
            for column in self._columns:
                if column not in values:
                    values[column] = None

        for column in values:
            i = self._columns.index(column)
            self._data[i][location] = values[column]


Instruction:
Can you create a Python 3 function that
appends a row of values to the end of the data.

Response:
def append_row(self, index, values, new_cols=True):
        """
        Appends a row of values to the end of the data. If there are new columns in the values and new_cols is True
        they will be added. Be very careful with this function as for sort DataFrames it will not enforce sort order.
        Use this only for speed when needed, be careful.

        :param index: value of the index
        :param values: dictionary of values
        :param new_cols: if True add new columns in values, if False ignore
        :return: nothing
        """

        if index in self._index:
            raise IndexError('index already in DataFrame')

        if new_cols:
            for col in values:
                if col not in self._columns:
                    self._add_column(col)

        # append index value
        self._index.append(index)

        # add data values, if not in values then use None
        for c, col in enumerate(self._columns):
            self._data[c].append(values.get(col, None))


Instruction:
Write a Python 3 function that can
append rows of values to the end of the data.

Response:
def append_rows(self, indexes, values, new_cols=True):
        """
        Appends rows of values to the end of the data. If there are new columns in the values and new_cols is True
        they will be added. Be very careful with this function as for sort DataFrames it will not enforce sort order.
        Use this only for speed when needed, be careful.

        :param indexes: list of indexes
        :param values: dictionary of values where the key is the column name and the value is a list
        :param new_cols: if True add new columns in values, if False ignore
        :return: nothing
        """

        # check that the values data is less than or equal to the length of the indexes
        for column in values:
            if len(values[column]) > len(indexes):
                raise ValueError('length of %s column in values is longer than indexes' % column)

        # check the indexes are not duplicates
        combined_index = self._index + indexes
        if len(set(combined_index)) != len(combined_index):
            raise IndexError('duplicate indexes in DataFrames')

        if new_cols:
            for col in values:
                if col not in self._columns:
                    self._add_column(col)

        # append index value
        self._index.extend(indexes)

        # add data values, if not in values then use None
        for c, col in enumerate(self._columns):
            self._data[c].extend(values.get(col, [None] * len(indexes)))
        self._pad_data()


Instruction:
Write a Python 3 script for
returning a dict containing the key - value pairs of column names and the values of that column.

Response:
def to_dict(self, index=True, ordered=False):
        """
        Returns a dict where the keys are the column names and the values are lists of the values for that column.

        :param index: If True then include the index in the dict with the index_name as the key
        :param ordered: If True then return an OrderedDict() to preserve the order of the columns in the DataFrame
        :return: dict or OrderedDict()
        """
        result = OrderedDict() if ordered else dict()
        if index:
            result.update({self._index_name: self._index})
        if ordered:
            data_dict = [(column, self._data[i]) for i, column in enumerate(self._columns)]
        else:
            data_dict = {column: self._data[i] for i, column in enumerate(self._columns)}
        result.update(data_dict)
        return result


Instruction:
Write a Python 3 function that can
return a JSON string of the entire DataFrame that can be reconstructed back with raccoon. from_json.

Response:
def to_json(self):
        """
        Returns a JSON of the entire DataFrame that can be reconstructed back with raccoon.from_json(input). Any object
        that cannot be serialized will be replaced with the representation of the object using repr(). In that instance
        the DataFrame will have a string representation in place of the object and will not reconstruct exactly.

        :return: json string
        """
        input_dict = {'data': self.to_dict(index=False), 'index': list(self._index)}

        # if blist, turn into lists
        if self.blist:
            input_dict['index'] = list(input_dict['index'])
            for key in input_dict['data']:
                input_dict['data'][key] = list(input_dict['data'][key])

        meta_data = dict()
        for key in self.__slots__:
            if key not in ['_data', '_index']:
                value = self.__getattribute__(key)
                meta_data[key.lstrip('_')] = value if not isinstance(value, blist) else list(value)
        meta_data['use_blist'] = meta_data.pop('blist')
        input_dict['meta_data'] = meta_data
        return json.dumps(input_dict, default=repr)


Instruction:
Implement a function in Python 3 to
rename the columns of the table.

Response:
def rename_columns(self, rename_dict):
        """
        Renames the columns

        :param rename_dict: dict where the keys are the current column names and the values are the new names
        :return: nothing
        """
        if not all([x in self._columns for x in rename_dict.keys()]):
            raise ValueError('all dictionary keys must be in current columns')
        for current in rename_dict.keys():
            self._columns[self._columns.index(current)] = rename_dict[current]


Instruction:
Make a summary of the following Python 3 code
def delete_all_rows(self):
        del self._index[:]
        for c in range(len(self._columns)):
            del self._data[c][:]

Response: Deletes all rows in the DataFrame.


Instruction:
Can you generate the documentation for the following Python 3 function
def delete_columns(self, columns):
        columns = [columns] if not isinstance(columns, (list, blist)) else columns
        if not all([x in self._columns for x in columns]):
            raise ValueError('all columns must be in current columns')
        for column in columns:
            c = self._columns.index(column)
            del self._data[c]
            del self._columns[c]
        if not len(self._data):  # if all the columns have been deleted, remove index
            self.index = list()

Response: Delete columns from the DataFrame


Instruction:
Implement a Python 3 function for
sorting the DataFrame by the index. The sort modifies the DataFrame inplace

Response:
def sort_index(self):
        """
        Sort the DataFrame by the index. The sort modifies the DataFrame inplace

        :return: nothing
        """
        sort = sorted_list_indexes(self._index)
        # sort index
        self._index = blist([self._index[x] for x in sort]) if self._blist else [self._index[x] for x in sort]
        # each column
        for c in range(len(self._data)):
            self._data[c] = blist([self._data[c][i] for i in sort]) if self._blist else [self._data[c][i] for i in sort]


Instruction:
Make a summary of the following Python 3 code
def sort_columns(self, column, key=None, reverse=False):
        if isinstance(column, (list, blist)):
            raise TypeError('Can only sort by a single column  ')
        sort = sorted_list_indexes(self._data[self._columns.index(column)], key, reverse)
        # sort index
        self._index = blist([self._index[x] for x in sort]) if self._blist else [self._index[x] for x in sort]
        # each column
        for c in range(len(self._data)):
            self._data[c] = blist([self._data[c][i] for i in sort]) if self._blist else [self._data[c][i] for i in sort]

Response: Sort the DataFrame by one of the columns.


Instruction:
Write a Python 3 script to
validate the integrity of the DataFrame.

Response:
def validate_integrity(self):
        """
        Validate the integrity of the DataFrame. This checks that the indexes, column names and internal data are not
        corrupted. Will raise an error if there is a problem.

        :return: nothing
        """
        self._validate_columns(self._columns)
        self._validate_index(self._index)
        self._validate_data()


Instruction:
Make a summary of the following Python 3 code
def append(self, data_frame):
        if len(data_frame) == 0:  # empty DataFrame, do nothing
            return
        data_frame_index = data_frame.index
        combined_index = self._index + data_frame_index
        if len(set(combined_index)) != len(combined_index):
            raise ValueError('duplicate indexes in DataFrames')

        for c, column in enumerate(data_frame.columns):
            if PYTHON3:
                self.set(indexes=data_frame_index, columns=column, values=data_frame.data[c].copy())
            else:
                self.set(indexes=data_frame_index, columns=column, values=data_frame.data[c][:])

Response: Append another DataFrame to this DataFrame.


Instruction:
Can you generate the documentation for the following Python 3 function
def add(self, left_column, right_column, indexes=None):
        left_list, right_list = self._get_lists(left_column, right_column, indexes)
        return [l + r for l, r in zip(left_list, right_list)]

Response: This method adds element - wise two columns.


Instruction:
How would you implement a function in Python 3 that
returns a boolean list where each element in the column is in the compare_list.

Response:
def isin(self, column, compare_list):
        """
        Returns a boolean list where each elements is whether that element in the column is in the compare_list.

        :param column: single column name, does not work for multiple columns
        :param compare_list: list of items to compare to
        :return: list of booleans
        """
        return [x in compare_list for x in self._data[self._columns.index(column)]]


Instruction:
Implement a function in Python 3 to
iterate over DataFrame rows as dictionary of the values.

Response:
def iterrows(self, index=True):
        """
        Iterates over DataFrame rows as dictionary of the values. The index will be included.

        :param index: if True include the index in the results
        :return: dictionary
        """
        for i in range(len(self._index)):
            row = {self._index_name: self._index[i]} if index else dict()
            for c, col in enumerate(self._columns):
                row[col] = self._data[c][i]
            yield row


Instruction:
Can you implement a function in Python 3 that
iterates over DataFrame rows as tuple of the values.

Response:
def itertuples(self, index=True, name='Raccoon'):
        """
        Iterates over DataFrame rows as tuple of the values.

        :param index: if True then include the index
        :param name: name of the namedtuple
        :return: namedtuple
        """
        fields = [self._index_name] if index else list()
        fields.extend(self._columns)
        row_tuple = namedtuple(name, fields)
        for i in range(len(self._index)):
            row = {self._index_name: self._index[i]} if index else dict()
            for c, col in enumerate(self._columns):
                row[col] = self._data[c][i]
            yield row_tuple(**row)


Instruction:
How would you explain what the following Python 3 function does
def reset_index(self, drop=False):
        if not drop:
            if isinstance(self.index_name, tuple):
                index_data = list(map(list, zip(*self._index)))
                for i in range(len(self.index_name)):
                    self.set_column(column=self.index_name[i], values=index_data[i])
            else:
                col_name = self.index_name if self.index_name is not 'index' else 'index_0'
                self.set_column(column=col_name, values=self._index)
        self.index = list(range(self.__len__()))
        self.index_name = 'index'

Response: Resets the index of the DataFrame to simple integer list and the index name to index.


Instruction:
Explain what the following Python 3 code does
def from_json(cls, json_string):
        input_dict = json.loads(json_string)
        # convert index to tuple if required
        if input_dict['index'] and isinstance(input_dict['index'][0], list):
            input_dict['index'] = [tuple(x) for x in input_dict['index']]
        # convert index_name to tuple if required
        if isinstance(input_dict['meta_data']['index_name'], list):
            input_dict['meta_data']['index_name'] = tuple(input_dict['meta_data']['index_name'])
        data = input_dict['data'] if input_dict['data'] else None
        return cls(data=data, index=input_dict['index'], **input_dict['meta_data'])

Response: Creates and returns a DataFrame from a JSON string.


Instruction:
Can you generate the documentation for the following Python 3 function
def doTask(self, task):

        # If we're not caching, then clear the table of last results.
        if not self._cache_results:
            self._last_results = dict()

        # Iterate the list of pipelines, draining each one of any results.
        # For pipelines whose current stream has less than *max_tasks* tasks
        # remaining, feed them the current task.
        for pipe in self._pipelines:

            count = self._task_counts[pipe]

            # Let's attempt to drain all (if any) results from the pipeline.
            valid = True
            last_result = None
            while count and valid:
                valid, result = pipe.get(sys.float_info.min)
                if valid:
                    last_result = result
                    count -= 1

            # Unless we're dropping results, save the last result (if any).
            if not self._drop_results:
                if last_result is not None:
                    self._last_results[pipe] = last_result

            # If there is room for the task, or if it is a "stop" request,
            # put it on the pipeline.
            if count <= self._max_tasks-1 or task is None:
                pipe.put(task)
                count += 1

            # Update the task count for the pipeline.
            self._task_counts[pipe] = count

        # If we're only propagating the task, do so now.
        if self._drop_results:
            return task

        # Otherwise, also propagate the assembly of pipeline results.
        all_results = [res for res in self._last_results.values()]
        return task, all_results

Response: Filter input task to pipelines and return a tuple containing the task and the list of latest retrieved results from the pipelines.


Instruction:
How would you explain what the following Python 3 function does
def assert_frame_equal(left, right, data_function=None, data_args=None):
    if data_function:
        data_args = {} if not data_args else data_args
        data_function(left.data, right.data, **data_args)
    else:
        assert left.data == right.data
    assert left.index == right.index
    assert left.columns == right.columns
    assert left.index_name == right.index_name
    assert left.sort == right.sort
    assert left.blist == right.blist

Response: This function is used to assert that two DataFrames are equal.


Instruction:
How would you explain what the following Python 3 function does
def assert_series_equal(left, right, data_function=None, data_args=None):
    assert type(left) == type(right)
    if data_function:
        data_args = {} if not data_args else data_args
        data_function(left.data, right.data, **data_args)
    else:
        assert left.data == right.data
    assert left.index == right.index
    assert left.data_name == right.data_name
    assert left.index_name == right.index_name
    assert left.sort == right.sort
    if isinstance(left, rc.ViewSeries):
        assert left.offset == right.offset
    if isinstance(left, rc.Series):
        assert left.blist == right.blist

Response: This function is used to assert that two Series objects are equal.


Instruction:
Implement a function in Python 3 to
get the result from the pipeline.

Response:
def get(self, timeout=None):
        """Return result from the pipeline."""
        result = None
        for stage in self._output_stages:
            result = stage.get(timeout)
        return result


Instruction:
Can you implement a function in Python 3 that
loads the lyrics from MetroLyrics.

Response:
def load(self):
        """Load the lyrics from MetroLyrics."""
        page = requests.get(self._url)
        # Forces utf-8 to prevent character mangling
        page.encoding = 'utf-8'

        tree = html.fromstring(page.text)
        lyric_div = tree.get_element_by_id('lyrics-body-text')
        verses = [c.text_content() for c in lyric_div.find_class('verse')]
        self._lyrics = '\n\n'.join(verses)
        return self


Instruction:
Can you implement a function in Python 3 that
loads the list of songs.

Response:
def load(self, verbose=False):
        """
        Load the list of songs.

        Note that this only loads a list of songs that this artist was the main
        artist of.  If they were only featured in the song, that song won't be
        listed here.  There is a list on the artist page for that, I just
        haven't added any parsing code for that, since I don't need it.
        """
        self._songs = []
        page_num = 1
        total_pages = 1

        while page_num <= total_pages:
            if verbose:
                print('retrieving page %d' % page_num)
            page = requests.get(ARTIST_URL.format(artist=self.name,
                                                  n=page_num))
            tree = html.fromstring(page.text)
            song_rows_xp = r'//*[@id="popular"]/div/table/tbody/tr'
            songlist_pagination_xp = r'//*[@id="main-content"]/div[1]/'\
                                     'div[2]/p/span/a'

            rows = tree.xpath(song_rows_xp)
            for row in rows:
                song_link = row.xpath(r'./td/a[contains(@class,"title")]')
                assert len(song_link) == 1
                self._songs.append(Song(url=song_link[0].attrib['href']))

            total_pages = len(tree.xpath(songlist_pagination_xp))
            page_num += 1
        return self


Instruction:
How would you code a function in Python 3 to
return the distance between two points on the surface of the Earth.

Response:
def distance(p0, p1, deg=True, r=r_earth_mean):
    """
    Return the distance between two points on the surface of the Earth.

    Parameters
    ----------
    p0 : point-like (or array of point-like) [longitude, latitude] objects
    p1 : point-like (or array of point-like) [longitude, latitude] objects
    deg : bool, optional (default True)
        indicates if p0 and p1 are specified in degrees
    r : float, optional (default r_earth_mean)
        radius of the sphere

    Returns
    -------
    d : float

    Reference
    ---------
    http://www.movable-type.co.uk/scripts/latlong.html - Distance

    Note: Spherical earth model. By default uses radius of 6371.0 km.

    """
    single, (p0, p1) = _to_arrays((p0, 2), (p1, 2))
    if deg:
        p0 = np.radians(p0)
        p1 = np.radians(p1)

    lon0, lat0 = p0[:,0], p0[:,1]
    lon1, lat1 = p1[:,0], p1[:,1]

    # h_x used to denote haversine(x): sin^2(x / 2)
    h_dlat = sin((lat1 - lat0) / 2.0) ** 2
    h_dlon = sin((lon1 - lon0) / 2.0) ** 2
    h_angle = h_dlat + cos(lat0) * cos(lat1) * h_dlon
    angle = 2.0 * arcsin(sqrt(h_angle))
    d = r * angle

    if single:
        d = d[0]

    return d


Instruction:
Write a Python 3 script for
computing the initial bearing along the great circle from p0 to p1.

Response:
def course(p0, p1, deg=True, bearing=False):
    """
    Compute the initial bearing along the great circle from p0 to p1

    NB: The angle returned by course() is not the traditional definition of
    bearing. It is definted such that 0 degrees to due East increasing
    counter-clockwise such that 90 degrees is due North. To obtain the bearing
    (0 degrees is due North increasing clockwise so that 90 degrees is due
    East), set the bearing flag input to True.

    Parameters
    ----------
    p0 : point-like (or array of point-like) [lon, lat] objects
    p1 : point-like (or array of point-like) [lon, lat] objects
    deg : bool, optional (default True)
        indicates if p0 and p1 are specified in degrees. The returned
        angle is returned in the same units as the input.
    bearing : bool, optional (default False)
        If True, use the classical definition of bearing where 0 degrees is
        due North increasing clockwise so that and 90 degrees is due East.

    Reference
    ---------
    http://www.movable-type.co.uk/scripts/latlong.html - Bearing

    """
    single, (p0, p1) = _to_arrays((p0, 2), (p1, 2))
    if deg:
        p0 = np.radians(p0)
        p1 = np.radians(p1)

    lon0, lat0 = p0[:,0], p0[:,1]
    lon1, lat1 = p1[:,0], p1[:,1]

    dlon = lon1 - lon0
    a = sin(dlon) * cos(lat1)
    b = cos(lat0) * sin(lat1) - sin(lat0) * cos(lat1) * cos(dlon)

    if bearing:
        angle = arctan2(a, b)
    else:
        angle = arctan2(b, a)

    if deg:
        angle = np.degrees(angle)

    if single:
        angle = angle[0]

    return angle


Instruction:
Here you have a function in Python 3, explain what it does
def propagate(p0, angle, d, deg=True, bearing=False, r=r_earth_mean):
    single, (p0, angle, d) = _to_arrays((p0, 2), (angle, 1), (d, 1))
    if deg:
        p0 = np.radians(p0)
        angle = np.radians(angle)

    if not bearing:
        angle = np.pi / 2.0 - angle

    lon0, lat0 = p0[:,0], p0[:,1]

    angd = d / r
    lat1 = arcsin(sin(lat0) * cos(angd) + cos(lat0) * sin(angd) * cos(angle))

    a = sin(angle) * sin(angd) * cos(lat0)
    b = cos(angd) - sin(lat0) * sin(lat1)
    lon1 = lon0 + arctan2(a, b)

    p1 = np.column_stack([lon1, lat1])

    if deg:
        p1 = np.degrees(p1)

    if single:
        p1 = p1[0]

    return p1

Response:
Given an initial point and angle move distance d along the surface
    Returns a new object that is a copy of the base classical hierarchy.


Instruction:
Write a Python 3 script for
validating the signature sent by weixin.

Response:
def validate(self, signature, timestamp, nonce):
        """Validate request signature.

        :param signature: A string signature parameter sent by weixin.
        :param timestamp: A int timestamp parameter sent by weixin.
        :param nonce: A int nonce parameter sent by weixin.
        """
        if not self.token:
            raise RuntimeError('WEIXIN_TOKEN is missing')

        if self.expires_in:
            try:
                timestamp = int(timestamp)
            except (ValueError, TypeError):
                # fake timestamp
                return False

            delta = time.time() - timestamp
            if delta < 0:
                # this is a fake timestamp
                return False

            if delta > self.expires_in:
                # expired timestamp
                return False

        values = [self.token, str(timestamp), str(nonce)]
        s = ''.join(sorted(values))
        hsh = hashlib.sha1(s.encode('utf-8')).hexdigest()
        return signature == hsh


Instruction:
Create a Python 3 function to
parse the xml body sent by weixin.

Response:
def parse(self, content):
        """Parse xml body sent by weixin.

        :param content: A text of xml body.
        """
        raw = {}

        try:
            root = etree.fromstring(content)
        except SyntaxError as e:
            raise ValueError(*e.args)

        for child in root:
            raw[child.tag] = child.text

        formatted = self.format(raw)

        msg_type = formatted['type']
        msg_parser = getattr(self, 'parse_%s' % msg_type, None)
        if callable(msg_parser):
            parsed = msg_parser(raw)
        else:
            parsed = self.parse_invalid_type(raw)

        formatted.update(parsed)
        return formatted


Instruction:
Can you generate the documentation for the following Python 3 function
def reply(self, username, type='text', sender=None, **kwargs):
        sender = sender or self.sender
        if not sender:
            raise RuntimeError('WEIXIN_SENDER or sender argument is missing')

        if type == 'text':
            content = kwargs.get('content', '')
            return text_reply(username, sender, content)

        if type == 'music':
            values = {}
            for k in ('title', 'description', 'music_url', 'hq_music_url'):
                values[k] = kwargs.get(k)
            return music_reply(username, sender, **values)

        if type == 'news':
            items = kwargs.get('articles', [])
            return news_reply(username, sender, *items)

        if type == 'customer_service':
            service_account = kwargs.get('service_account', None)
            return transfer_customer_service_reply(username, sender,
                                                   service_account)

        if type == 'image':
            media_id = kwargs.get('media_id', '')
            return image_reply(username, sender, media_id)

        if type == 'voice':
            media_id = kwargs.get('media_id', '')
            return voice_reply(username, sender, media_id)

        if type == 'video':
            values = {}
            for k in ('media_id', 'title', 'description'):
                values[k] = kwargs.get(k)
            return video_reply(username, sender, **values)

Response: Create the reply text for the user.


Instruction:
Here you have a function in Python 3, explain what it does
def register(self, key=None, func=None, **kwargs):
        if func:
            if key is None:
                limitation = frozenset(kwargs.items())
                self._registry_without_key.append((func, limitation))
            else:
                self._registry[key] = func
            return func

        return self.__call__(key, **kwargs)

Response: Register a command helper function.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def view_func(self):
        if request is None:
            raise RuntimeError('view_func need Flask be installed')

        signature = request.args.get('signature')
        timestamp = request.args.get('timestamp')
        nonce = request.args.get('nonce')
        if not self.validate(signature, timestamp, nonce):
            return 'signature failed', 400

        if request.method == 'GET':
            echostr = request.args.get('echostr', '')
            return echostr

        try:
            ret = self.parse(request.data)
        except ValueError:
            return 'invalid', 400

        if 'type' not in ret:
            # not a valid message
            return 'invalid', 400

        if ret['type'] == 'text' and ret['content'] in self._registry:
            func = self._registry[ret['content']]
        else:
            ret_set = frozenset(ret.items())
            matched_rules = (
                _func for _func, _limitation in self._registry_without_key
                if _limitation.issubset(ret_set))
            func = next(matched_rules, None)  # first matched rule

        if func is None:
            if '*' in self._registry:
                func = self._registry['*']
            else:
                func = 'failed'

        if callable(func):
            text = func(**ret)
        else:
            # plain text
            text = self.reply(
                username=ret['sender'],
                sender=ret['receiver'],
                content=func,
            )

        return Response(text, content_type='text/xml; charset=utf-8')

Response: Default view function for Flask app.


Instruction:
Can you create a Python 3 function that
passes user inputs to GetGist and calls get

Response:
def run_getgist(filename, user, **kwargs):
    """Passes user inputs to GetGist() and calls get()"""
    assume_yes = kwargs.get("yes_to_all")
    getgist = GetGist(user=user, filename=filename, assume_yes=assume_yes)
    getgist.get()


Instruction:
Can you write a function in Python 3 where it
passes user inputs to GetGist and calls put

Response:
def run_putgist(filename, user, **kwargs):
    """Passes user inputs to GetGist() and calls put()"""
    assume_yes = kwargs.get("yes_to_all")
    private = kwargs.get("private")
    getgist = GetGist(
        user=user,
        filename=filename,
        assume_yes=assume_yes,
        create_private=private,
        allow_none=True,
    )
    getgist.put()


Instruction:
Explain what the following Python 3 code does
def get(self):
        if self.gist:
            content = self.github.read_gist_file(self.gist)
            self.local.save(content)

Response: Reads the remote file from Gist and saves it locally


Instruction:
Can you tell what is the following Python 3 function doing
def put(self):
        content = self.local.read()
        if self.gist:
            self.github.update(self.gist, content)
        else:
            self.github.create(content, public=self.public)

Response: Reads local file and updates the remote gist or creates a new one.


Instruction:
Here you have a function in Python 3, explain what it does
def oauth_only(function):

    def check_for_oauth(self, *args, **kwargs):
        """
        Returns False if GitHubTools instance is not authenticated, or return
        the decorated fucntion if it is.
        """
        if not self.is_authenticated:
            self.oops("To use putgist you have to set your GETGIST_TOKEN")
            self.oops("(see `putgist --help` for details)")
            return False
        return function(self, *args, **kwargs)

    return check_for_oauth

Response: Decorator to restrict some GitHubTools methods to run only with OAuth


Instruction:
How would you explain what the following Python 3 function does
def add_oauth_header(self):
        # abort if no token
        oauth_token = self._get_token()
        if not oauth_token:
            return

        # add oauth header & reach the api
        self.headers["Authorization"] = "token " + oauth_token
        url = self._api_url("user")
        raw_resp = self.requests.get(url)
        resp = raw_resp.json()

        # abort & remove header if token is invalid
        if resp.get("login", None) != self.user:
            self.oops("Invalid token for user " + self.user)
            self.headers.pop("Authorization")
            return

        self.is_authenticated = True
        self.yeah("User {} authenticated".format(self.user))

Response: Validate token and add the proper header for further requests.


Instruction:
Given the following Python 3 function, write the documentation
def get_gists(self):
        # fetch all gists
        if self.is_authenticated:
            url = self._api_url("gists")
        else:
            url = self._api_url("users", self.user, "gists")
        self.output("Fetching " + url)
        raw_resp = self.requests.get(url)

        # abort if user not found
        if raw_resp.status_code != 200:
            self.oops("User `{}` not found".format(self.user))
            return

        # abort if there are no gists
        resp = raw_resp.json()
        if not resp:
            self.oops("No gists found for user `{}`".format(self.user))
            return

        # parse response
        for gist in raw_resp.json():
            yield self._parse_gist(gist)

Response: Get all gists for the current user.


Instruction:
Can you tell what is the following Python 3 function doing
def select_gist(self, allow_none=False):
        # pick up all macthing gists
        matches = list()
        for gist in self.get_gists():
            for gist_file in gist.get("files"):
                if self.filename == gist_file.get("filename"):
                    matches.append(gist)

        # abort if no match is found
        if not matches:
            if allow_none:
                return None
            else:
                msg = "No file named `{}` found in {}'s gists"
                self.oops(msg.format(self.file_path, self.user))
                if not self.is_authenticated:
                    self.warn("To access private gists set the GETGIST_TOKEN")
                    self.warn("(see `getgist --help` for details)")
                return False

        # return if there's is only one match
        if len(matches) == 1 or self.assume_yes:
            return matches.pop(0)

        return self._ask_which_gist(matches)

Response: This method selects the proper gist for the given filename. If more than one gist is found it returns the proper gist ; if no gist is found it returns False


Instruction:
Create a Python 3 function for
reading a gist file from GitHub

Response:
def read_gist_file(self, gist):
        """
        Returns the contents of file hosted inside a gist at GitHub.
        :param gist: (dict) gist parsed by GitHubTools._parse()
        :return: (bytes) content of a gist loaded from GitHub
        """
        url = False
        files = gist.get("files")
        for gist_file in files:
            if gist_file.get("filename") == self.filename:
                url = gist_file.get("raw_url")
                break
        if url:
            self.output("Reading {}".format(url))
            response = self.requests.get(url)
            return response.content