<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def get_rolls(self, root_symbol, start, end, offset):
 """ Get the rolls, i.e. the session at which to hop from contract to contract in the chain. Parameters root_symbol : str The root symbol for which to calculate rolls. start : Timestamp Start of the date range. end : Timestamp End of the date range. offset : int Offset from the primary. Returns ------- rolls - list[tuple(sid, roll_date)] A list of rolls, where first value is the first active `sid`, and the `roll_date` on which to hop to the next contract. The last pair in the chain has a value of `None` since the roll is after the range. """

        oc = self.asset_finder.get_ordered_contracts(root_symbol)
        front = self._get_active_contract_at_offset(root_symbol, end, 0)
        back = oc.contract_at_offset(front, 1, end.value)
        if back is not None:
            end_session = self.trading_calendar.minute_to_session_label(end)
            first = self._active_contract(oc, front, back, end_session)
        else:
            first = front
        first_contract = oc.sid_to_contract[first]
        rolls = [((first_contract >> offset).contract.sid, None)]
        tc = self.trading_calendar
        sessions = tc.sessions_in_range(tc.minute_to_session_label(start),
                                        tc.minute_to_session_label(end))
        freq = sessions.freq
        if first == front:
            # This is a bit tricky to grasp. Once we have the active contract
            # on the given end date, we want to start walking backwards towards
            # the start date and checking for rolls. For this, we treat the
            # previous month's contract as the 'first' contract, and the
            # contract we just found to be active as the 'back'. As we walk
            # towards the start date, if the 'back' is no longer active, we add
            # that date as a roll.
            curr = first_contract << 1
        else:
            curr = first_contract << 2
        session = sessions[-1]

        while session > start and curr is not None:
            front = curr.contract.sid
            back = rolls[0][0]
            prev_c = curr.prev
            while session > start:
                prev = session - freq
                if prev_c is not None:
                    if prev < prev_c.contract.auto_close_date:
                        break
                if back != self._active_contract(oc, front, back, prev):
                    # TODO: Instead of listing each contract with its roll date
                    # as tuples, create a series which maps every day to the
                    # active contract on that day.
                    rolls.insert(0, ((curr >> offset).contract.sid, session))
                    break
                session = prev
            curr = curr.prev
            if curr is not None:
                session = min(session, curr.contract.auto_close_date + freq)

        return rolls