Prompt:
Implement the Python class `BattleRoundController` described below.

Class description:
Controller for Battle Rounds

Method signatures and docstrings:
- def __init__(self, battle, screen): Initialize the Battle Round Controller
- def performGameCycle(self): Tells the battle object what to perform
- def performEntireRound(self): Perform an Entire Round
- def performRound(self): Perform a Single Round
- def refillSides(self): Refill the Battle Sides

Implement the Python class `BattleRoundController` described below.

Class description:
Controller for Battle Rounds

Method signatures and docstrings:
- def __init__(self, battle, screen): Initialize the Battle Round Controller
- def performGameCycle(self): Tells the battle object what to perform
- def performEntireRound(self): Perform an Entire Round
- def performRound(self): Perform a Single Round
- def refillSides(self): Refill the Battle Sides

<|skeleton|>
class BattleRoundController:
    """Controller for Battle Rounds"""

    def __init__(self, battle, screen):
        """Initialize the Battle Round Controller"""
        <|body_0|>

    def performGameCycle(self):
        """Tells the battle object what to perform"""
        <|body_1|>

    def performEntireRound(self):
        """Perform an Entire Round"""
        <|body_2|>

    def performRound(self):
        """Perform a Single Round"""
        <|body_3|>

    def refillSides(self):
        """Refill the Battle Sides"""
        <|body_4|>

<|end_skeleton|>

<|body_start_0|>
        self.battle = battle
        PygameController.__init__(self, screen)
        self.coroutine = self.performEntireRound()
<|end_body_0|>

<|body_start_1|>
        self.screen.setBottomView(None)
        PerformEvents(self.battle.eventQueue, self)
        self.coroutine.send(None)
        if self.battle.over:
            self.stopRunning()
<|end_body_1|>

<|body_start_2|>
        while not self.battle.over:
            self.performRound()
            yield
            self.refillSides()
            yield
<|end_body_2|>

<|body_start_3|>
        pokemonActions = {}
        for pokemon in self.battle.playerSide.pkmnInPlay:
            if not pokemon.actionLock:
                actionMenuController = ActionMenuController(pokemon, self.battle, self.screen)
                self.runController(actionMenuController)
                if actionMenuController.action is None:
                    return
                else:
                    pokemonActions[pokemon] = actionMenuController.action
        self.battle.performRound(pokemonActions)
<|end_body_3|>

<|body_start_4|>
        pokemonReplacements = {}
        if self.battle.playerSide.hasMorePokemon():
            for pokemon in self.battle.playerSide.pkmnInPlay:
                if pokemon.fainted():
                    switchMenuController = SwitchMenuController(pokemon, cancellable=False)
                    self.runController(switchMenuController)
                    pokemonReplacements[pokemon] = switchMenuController.action.pkmnToSwitchTo
        self.battle.refillSides(pokemonReplacements)
<|end_body_4|>

Solution:
class BattleRoundController:
    """Controller for Battle Rounds"""

    def __init__(self, battle, screen):
        """Initialize the Battle Round Controller"""
        self.battle = battle
        PygameController.__init__(self, screen)
        self.coroutine = self.performEntireRound()

    def performGameCycle(self):
        """Tells the battle object what to perform"""
        self.screen.setBottomView(None)
        PerformEvents(self.battle.eventQueue, self)
        self.coroutine.send(None)
        if self.battle.over:
            self.stopRunning()

    def performEntireRound(self):
        """Perform an Entire Round"""
        while not self.battle.over:
            self.performRound()
            yield
            self.refillSides()
            yield

    def performRound(self):
        """Perform a Single Round"""
        pokemonActions = {}
        for pokemon in self.battle.playerSide.pkmnInPlay:
            if not pokemon.actionLock:
                actionMenuController = ActionMenuController(pokemon, self.battle, self.screen)
                self.runController(actionMenuController)
                if actionMenuController.action is None:
                    return
                else:
                    pokemonActions[pokemon] = actionMenuController.action
        self.battle.performRound(pokemonActions)

    def refillSides(self):
        """Refill the Battle Sides"""
        pokemonReplacements = {}
        if self.battle.playerSide.hasMorePokemon():
            for pokemon in self.battle.playerSide.pkmnInPlay:
                if pokemon.fainted():
                    switchMenuController = SwitchMenuController(pokemon, cancellable=False)
                    self.runController(switchMenuController)
                    pokemonReplacements[pokemon] = switchMenuController.action.pkmnToSwitchTo
        self.battle.refillSides(pokemonReplacements)


put

Prompt:
Implement the Python class `LRUCache` described below.

Class description:
Implement the LRUCache class.

Method signatures and docstrings:
- def __init__(self, capacity): :type capacity: int
- def get(self, key): :type key: int :rtype: int
- def put(self, key, value): :type key: int :type value: int :rtype: void

Implement the Python class `LRUCache` described below.

Class description:
Implement the LRUCache class.

Method signatures and docstrings:
- def __init__(self, capacity): :type capacity: int
- def get(self, key): :type key: int :rtype: int
- def put(self, key, value): :type key: int :type value: int :rtype: void

<|skeleton|>
class LRUCache:

    def __init__(self, capacity):
        """:type capacity: int"""
        <|body_0|>

    def get(self, key):
        """:type key: int :rtype: int"""
        <|body_1|>

    def put(self, key, value):
        """:type key: int :type value: int :rtype: void"""
        <|body_2|>

<|end_skeleton|>

<|body_start_0|>
        self.capacity = capacity
        self.l = DoublyLL()
        self.d = {}
<|end_body_0|>

<|body_start_1|>
        try:
            n = self.d[key]
        except KeyError:
            return -1
        self.l.Remove(n)
        self.l.InsertFirst(n)
        return n.value
<|end_body_1|>

<|body_start_2|>
        if key in self.d:
            node = self.d[key]
            self.l.Remove(node)
            self.l.InsertFirst(node)
            node.value = value
        else:
            if self.l.count >= self.capacity:
                node = self.l.RemoveTail()
                del self.d[node.key]
            node = Node(key, value)
            self.l.InsertFirst(node)
            self.d[key] = node
<|end_body_2|>

Solution:
class LRUCache:
    def __init__(self, capacity):
        """:type capacity: int"""
        self.capacity = capacity
        self.l = DoublyLL()
        self.d = {}

    def get(self, key):
        """:type key: int :rtype: int"""
        try:
            n = self.d[key]
        except KeyError:
            return -1
        self.l.Remove(n)
        self.l.InsertFirst(n)
        return n.value

    def put(self, key, value):
        """:type key: int :type value: int :rtype: void"""
        if key in self.d:
            node = self.d[key]
            self.l.Remove(node)
            self.l.InsertFirst(node)
            node.value = value
        else:
            if self.l.count >= self.capacity:
                node = self.l.RemoveTail()
                del self.d[node.key]
            node = Node(key, value)
            self.l.InsertFirst(node)
            self.d[key] = node


Prompt:
Implement the Python class `ObjectPrinter` described below.

Class description:
A Printer for objects in C++. The current version won't extract the dynamic/actual type of objects, and the member variable of a parent/child class won't be printed. We expect to support this function later.

Method signatures and docstrings:
- def to_json_without_expanding_base_class(self): A helper function for the to_json method. It tries to extract all member variables of an object without casting it into base classes.
- def to_json(self, cast_to_dynamic_type=True): Output format: { 'type': 'struct', 'ctype': string format type in C++, 'address': string format address, 'base_classes': [] # a list of value casted into each base class 'fields': [] # a list of struct fields }. For each field in fields, its format is: { 'field': string format of field name, 'field_type': 'base_class'/'member', if it is a base class. the value will be the object which is casted into that base_class. Otherwise, the value is the json of the member variable. 'value': json of the field }.

Implement the Python class `ObjectPrinter` described below.

Class description:
A Printer for objects in C++. The current version won't extract the dynamic/actual type of objects, and the member variable of a parent/child class won't be printed. We expect to support this function later.

Method signatures and docstrings:
- def to_json_without_expanding_base_class(self): A helper function for the to_json method. It tries to extract all member variables of an object without casting it into base classes.
- def to_json(self, cast_to_dynamic_type=True): Output format: { 'type': 'struct', 'ctype': string format type in C++, 'address': string format address, 'base_classes': [] # a list of value casted into each base class 'fields': [] # a list of struct fields }. For each field in fields, its format is: { 'field': string format of field name, 'field_type': 'base_class'/'member', if it is a base class. the value will be the object which is casted into that base_class. Otherwise, the value is the json of the member variable. 'value': json of the field }.

<|skeleton|>
class ObjectPrinter:
    """A Printer for objects in C++. The current version won't extract the dynamic/actual type of objects, and the member variable of a parent/child class won't be printed. We expect to support this function later."""

    def to_json_without_expanding_base_class(self):
        """A helper function for the to_json method. It tries to extract all member variables of an object without casting it into base classes."""
        <|body_0|>

    def to_json(self, cast_to_dynamic_type=True):
        """Output format: { 'type': 'struct', 'ctype': string format type in C++, 'address': string format address, 'base_classes': [] # a list of value casted into each base class 'fields': [] # a list of struct fields }. For each field in fields, its format is: { 'field': string format of field name, 'field_type': 'base_class'/'member', if it is a base class. the value will be the object which is casted into that base_class. Otherwise, the value is the json of the member variable. 'value': json of the field }."""
        <|body_1|>

<|end_skeleton|>

<|body_start_0|>
        value_json = {'type': 'struct', 'ctype': str(self.value.type), 'address': self.address, 'fields': []}
        for field in self.value.type.fields():
            if not field.is_base_class:
                field_json = {'field': field.name, 'value': None}
                field_printer = general_lookup_function(self.value[field.name], self.visited_addresses_and_types)
                try:
                    field_json['value'] = field_printer.to_json()
                except:
                    field_json['value'] = 'extract failed'
                value_json['fields'].append(field_json)
        return value_json
<|end_body_0|>

<|body_start_1|>
        if cast_to_dynamic_type and self.value.type.strip_typedefs() != self.value.dynamic_type.strip_typedefs():
            self.value = self.value.cast(self.value.dynamic_type)
        value_json = self.to_json_without_expanding_base_class()
        if value_json['type'] != 'visited':
            base_classes_list = []
            for field in self.value.type.fields():
                if field.is_base_class:
                    field_json = {'base_class': field.name, 'value': None}
                    base_class_printer = ObjectPrinter(self.value.cast(field.type), self.visited_addresses_and_types)
                    field_json['value'] = base_class_printer.to_json(cast_to_dynamic_type=False)
                    base_classes_list.append(field_json)
            value_json['base_classes'] = base_classes_list
        return value_json
<|end_body_1|>

Solution:
class ObjectPrinter:
    """A Printer for objects in C++. The current version won't extract the dynamic/actual type of objects, and the member variable of a parent/child class won't be printed. We expect to support this function later."""

    def to_json_without_expanding_base_class(self):
        """A helper function for the to_json method. It tries to extract all member variables of an object without casting it into base classes."""
        value_json = {'type': 'struct', 'ctype': str(self.value.type), 'address': self.address, 'fields': []}
        for field in self.value.type.fields():
            if not field.is_base_class:
                field_json = {'field': field.name, 'value': None}
                field_printer = general_lookup_function(self.value[field.name], self.visited_addresses_and_types)
                try:
                    field_json['value'] = field_printer.to_json()
                except:
                    field_json['value'] = 'extract failed'
                value_json['fields'].append(field_json)
        return value_json

    def to_json(self, cast_to_dynamic_type=True):
        """Output format: { 'type': 'struct', 'ctype': string format type in C++, 'address': string format address, 'base_classes': [] # a list of value casted into each base class 'fields': [] # a list of struct fields }. For each field in fields, its format is: { 'field': string format of field name, 'field_type': 'base_class'/'member', if it is a base class. the value will be the object which is casted into that base_class. Otherwise, the value is the json of the member variable. 'value': json of the field }."""
        if cast_to_dynamic_type and self.value.type.strip_typedefs() != self.value.dynamic_type.strip_typedefs():
            self.value = self.value.cast(self.value.dynamic_type)
        value_json = self.to_json_without_expanding_base_class()
        if value_json['type'] != 'visited':
            base_classes_list = []
            for field in self.value.type.fields():
                if field.is_base_class:
                    field_json = {'base_class': field.name, 'value': None}
                    base_class_printer = ObjectPrinter(self.value.cast(field.type), self.visited_addresses_and_types)
                    field_json['value'] = base_class_printer.to_json(cast_to_dynamic_type=False)
                    base_classes_list.append(field_json)
            value_json['base_classes'] = base_classes_list
        return value_json


Prompt:
Implement the Python class `CommanderSubcommand` described below.

Class description:
@brief `pyocd commander` subcommand.

Method signatures and docstrings:
- def get_args(cls) -> List[argparse.ArgumentParser]: @brief Add this subcommand to the subparsers object.
- def invoke(self) -> int: @brief Handle 'commander' subcommand.

Implement the Python class `CommanderSubcommand` described below.

Class description:
@brief `pyocd commander` subcommand.

Method signatures and docstrings:
- def get_args(cls) -> List[argparse.ArgumentParser]: @brief Add this subcommand to the subparsers object.
- def invoke(self) -> int: @brief Handle 'commander' subcommand.

<|skeleton|>
class CommanderSubcommand:
    """@brief `pyocd commander` subcommand."""

    def get_args(cls) -> List[argparse.ArgumentParser]:
        """@brief Add this subcommand to the subparsers object."""
        <|body_0|>

    def invoke(self) -> int:
        """@brief Handle 'commander' subcommand."""
        <|body_1|>

<|end_skeleton|>

<|body_start_0|>
        commander_parser = argparse.ArgumentParser(description=cls.HELP, add_help=False)
        commander_options = commander_parser.add_argument_group('commander options')
        commander_options.add_argument('-H', '--halt', action='store_true', default=None, help='Halt core upon connect. (Deprecated, see --connect.)')
        commander_options.add_argument('-N', '--no-init', action='store_true', help='Do not init debug system.')
        commander_options.add_argument('--elf', metavar='PATH', help='Optionally specify ELF file being debugged.')
        commander_options.add_argument('-c', '--command', dest='commands', metavar='CMD', action='append', nargs='+', help='Run commands.')
        commander_options.add_argument('-x', '--execute', dest='commands', metavar='FILE', action='append', type=argparse.FileType('r'), help='Execute commands from file. Pass - for stdin.')
        commander_options.add_argument('-i', '--interactive', action='store_true', help='Stay in interactive mode after running commands specified from command line or file.')
        return [cls.CommonOptions.COMMON, cls.CommonOptions.CONNECT, commander_parser]
<|end_body_0|>

<|body_start_1|>
        if self._args.commands is not None:
            cmds = []
            for cmd in self._args.commands:
                if isinstance(cmd, io.IOBase):
                    cmds.append(cmd)
                else:
                    cmds.append(' '.join(cmd))
        else:
            cmds = None
        PyOCDCommander(self._args, cmds).run()
        return 0
<|end_body_1|>

Solution:
class CommanderSubcommand:
    """@brief `pyocd commander` subcommand."""

    def get_args(cls) -> List[argparse.ArgumentParser]:
        """@brief Add this subcommand to the subparsers object."""
        commander_parser = argparse.ArgumentParser(description=cls.HELP, add_help=False)
        commander_options = commander_parser.add_argument_group('commander options')
        commander_options.add_argument('-H', '--halt', action='store_true', default=None, help='Halt core upon connect. (Deprecated, see --connect.)')
        commander_options.add_argument('-N', '--no-init', action='store_true', help='Do not init debug system.')
        commander_options.add_argument('--elf', metavar='PATH', help='Optionally specify ELF file being debugged.')
        commander_options.add_argument('-c', '--command', dest='commands', metavar='CMD', action='append', nargs='+', help='Run commands.')
        commander_options.add_argument('-x', '--execute', dest='commands', metavar='FILE', action='append', type=argparse.FileType('r'), help='Execute commands from file. Pass - for stdin.')
        commander_options.add_argument('-i', '--interactive', action='store_true', help='Stay in interactive mode after running commands specified from command line or file.')
        return [cls.CommonOptions.COMMON, cls.CommonOptions.CONNECT, commander_parser]

    def invoke(self) -> int:
        """@brief Handle 'commander' subcommand."""
        if self._args.commands is not None:
            cmds = []
            for cmd in self._args.commands:
                if isinstance(cmd, io.IOBase):
                    cmds.append(cmd)
                else:
                    cmds.append(' '.join(cmd))
        else:
            cmds = None
        PyOCDCommander(self._args, cmds).run()
        return 0


countAndSay

Prompt:
Implement the Python class `Solution` described below.

Class description:
Implement the Solution class.

Method signatures and docstrings:
- def countAndSay(self, n): 从左往右推 使用队列存储上一个数,然后不断删掉第一个数,直到队列删光了,使用c计数 :type n: int :rtype: str
- def countAndSay3(self, n): 优化空间 :type n: int :rtype: str
- def countAndSay2(self, nums): 骚方法:使用re 暂时还学不来 :param nums: :return:

Implement the Python class `Solution` described below.

Class description:
Implement the Solution class.

Method signatures and docstrings:
- def countAndSay(self, n): 从左往右推 使用队列存储上一个数,然后不断删掉第一个数,直到队列删光了,使用c计数 :type n: int :rtype: str
- def countAndSay3(self, n): 优化空间 :type n: int :rtype: str
- def countAndSay2(self, nums): 骚方法:使用re 暂时还学不来 :param nums: :return:

<|skeleton|>
class Solution:

    def countAndSay(self, n):
        """从左往右推 使用队列存储上一个数,然后不断删掉第一个数,直到队列删光了,使用c计数 :type n: int :rtype: str"""
        <|body_0|>

    def countAndSay3(self, n):
        """优化空间 :type n: int :rtype: str"""
        <|body_1|>

    def countAndSay2(self, nums):
        """骚方法:使用re 暂时还学不来 :param nums: :return:"""
        <|body_2|>

<|end_skeleton|>

<|body_start_0|>
        dp = [''] * n
        dp[0] = '1'
        for i in range(1, n):
            queue = list(dp[i - 1])
            tmp = ''
            c = 1
            while queue:
                cur = queue.pop(0)
                if queue and queue[0] == cur:
                    c += 1
                else:
                    tmp += str(c) + cur
                    c = 1
            dp[i] = tmp
        return dp[n - 1]
<|end_body_0|>

<|body_start_1|>
        import collections
        res = '1'
        for i in range(1, n):
            queue = collections.deque(res)
            res = ''
            c = 1
            while queue:
                cur = queue.popleft()
                if queue and queue[0] == cur:
                    c += 1
                else:
                    res += str(c) + cur
                    c = 1
        return res
<|end_body_1|>

<|body_start_2|>
        s = '1'
        for _ in range(nums - 1):
            s = ''.join((str(len(p[0])) + p[1] for p in re.findall('((.)\\2*)', s)))
        return s
<|end_body_2|>

Solution:
class Solution:
    def countAndSay(self, n):
        """从左往右推 使用队列存储上一个数,然后不断删掉第一个数,直到队列删光了,使用c计数 :type n: int :rtype: str"""
        dp = [''] * n
        dp[0] = '1'
        for i in range(1, n):
            queue = list(dp[i - 1])
            tmp = ''
            c = 1
            while queue:
                cur = queue.pop(0)
                if queue and queue[0] == cur:
                    c += 1
                else:
                    tmp += str(c) + cur
                    c = 1
            dp[i] = tmp
        return dp[n - 1]

    def countAndSay3(self, n):
        """优化空间 :type n: int :rtype: str"""
        import collections
        res = '1'
        for i in range(1, n):
            queue = collections.deque(res)
            res = ''
            c = 1
            while queue:
                cur = queue.popleft()
                if queue and queue[0] == cur:
                    c += 1
                else:
                    res += str(c) + cur
                    c = 1
        return res

    def countAndSay2(self, nums):
        """骚方法:使用re 暂时还学不来 :param nums: :return:"""
        s = '1'
        for _ in range(nums - 1):
            s = ''.join((str(len(p[0])) + p[1] for p in re.findall('((.)\\2*)', s)))
        return s


ok

Prompt:
Implement the Python class `GetStringDialog` described below.

Class description:
A combination of Container, Label, TextBox and Button that asks the user for a string. Additional attributes: GetStringDialog.callback The callback to be called callback(string) when the input is confirmed.

Method signatures and docstrings:
- def __init__(self, prompt, callback, display): Initialise. callback will be called callback(GetStringDialog.textbox.text) after the GetStringDialog is destroyed. It should call render() and flip the display to remove the GetStringDialog from the screen. display.key_sensitive() will be used to register the TextBox of this dialog.
- def ok(self, plane): Button callback to destroy the GetStringDialog and call GetStringDialog.callback(string).
- def return_key(self, text): Return key callback to destroy the GetStringDialog and call GetStringDialog.callback(string).

Implement the Python class `GetStringDialog` described below.

Class description:
A combination of Container, Label, TextBox and Button that asks the user for a string. Additional attributes: GetStringDialog.callback The callback to be called callback(string) when the input is confirmed.

Method signatures and docstrings:
- def __init__(self, prompt, callback, display): Initialise. callback will be called callback(GetStringDialog.textbox.text) after the GetStringDialog is destroyed. It should call render() and flip the display to remove the GetStringDialog from the screen. display.key_sensitive() will be used to register the TextBox of this dialog.
- def ok(self, plane): Button callback to destroy the GetStringDialog and call GetStringDialog.callback(string).
- def return_key(self, text): Return key callback to destroy the GetStringDialog and call GetStringDialog.callback(string).

<|skeleton|>
class GetStringDialog:
    """A combination of Container, Label, TextBox and Button that asks the user for a string. Additional attributes: GetStringDialog.callback The callback to be called callback(string) when the input is confirmed."""

    def __init__(self, prompt, callback, display):
        """Initialise. callback will be called callback(GetStringDialog.textbox.text) after the GetStringDialog is destroyed. It should call render() and flip the display to remove the GetStringDialog from the screen. display.key_sensitive() will be used to register the TextBox of this dialog."""
        <|body_0|>

    def ok(self, plane):
        """Button callback to destroy the GetStringDialog and call GetStringDialog.callback(string)."""
        <|body_1|>

    def return_key(self, text):
        """Return key callback to destroy the GetStringDialog and call GetStringDialog.callback(string)."""
        <|body_2|>

<|end_skeleton|>

<|body_start_0|>
        Container.__init__(self, 'get_string_dialog', padding=5)
        self.callback = callback
        self.sub(Label('prompt', prompt, pygame.Rect((0, 0), (200, 30))))
        textbox = TextBox('textbox', pygame.Rect((0, 0), (200, 30)), return_callback=self.return_key)
        self.sub(textbox)
        display.key_sensitive(textbox)
        self.sub(Button('OK', pygame.Rect((0, 0), (90, 30)), self.ok))
        return
<|end_body_0|>

<|body_start_1|>
        self.textbox.deactivate()
        callback = self.callback
        string = self.textbox.text
        self.destroy()
        callback(string)
        return
<|end_body_1|>

<|body_start_2|>
        callback = self.callback
        self.destroy()
        callback(text)
        return
<|end_body_2|>

Solution:
class GetStringDialog:
    """A combination of Container, Label, TextBox and Button that asks the user for a string. Additional attributes: GetStringDialog.callback The callback to be called callback(string) when the input is confirmed."""

    def __init__(self, prompt, callback, display):
        """Initialise. callback will be called callback(GetStringDialog.textbox.text) after the GetStringDialog is destroyed. It should call render() and flip the display to remove the GetStringDialog from the screen. display.key_sensitive() will be used to register the TextBox of this dialog."""
        Container.__init__(self, 'get_string_dialog', padding=5)
        self.callback = callback
        self.sub(Label('prompt', prompt, pygame.Rect((0, 0), (200, 30))))
        textbox = TextBox('textbox', pygame.Rect((0, 0), (200, 30)), return_callback=self.return_key)
        self.sub(textbox)
        display.key_sensitive(textbox)
        self.sub(Button('OK', pygame.Rect((0, 0), (90, 30)), self.ok))
        return

    def ok(self, plane):
        """Button callback to destroy the GetStringDialog and call GetStringDialog.callback(string)."""
        self.textbox.deactivate()
        callback = self.callback
        string = self.textbox.text
        self.destroy()
        callback(string)
        return

    def return_key(self, text):
        """Return key callback to destroy the GetStringDialog and call GetStringDialog.callback(string)."""
        callback = self.callback
        self.destroy()
        callback(text)
        return


remove

Prompt:
Implement the Python class `DoubleLinkedList` described below.

Class description:
Util class to implement a double linked list, i.e. a linked list where items both have a connection to the previous and the next node. The list is circular, meaning that the successor of the last node is the first node in the list. The list has a "head" pointer to the first item in the list (arbitrarily chosen in the cycle as the first one added) and a "current" pointer to the currently selected node.

Method signatures and docstrings:
- def __init__(self, head): Initialization function for a double linked list. :param head: Reference to the first node in the list. :type head: DoubleLinkedListNode
- def print(self): Util function to display the double linked list, starting from the head (and stopping at the end of the first cycle).
- def add(self, data, set_ptr=False): Adds a node at the end of the double linked list. :param data: Value of the node to add. :type data: int :param set_ptr: If true, then the "current" pointer of the list will be assigned to the newly created node. :type set_ptr: bool
- def insert(self, offset, data, set_ptr=False): Inserts a node in the double linked list with a given offset from the currently selected node. :param offset: Offset from the currently selected node: if positive, the node will be inserted in the successors, else it will be inserted in the predecessors. :type offset: int :param data: Value of the node to insert. :type data: int :param set_ptr: If true, then the "current" pointer of the list will be assigned to the newly created node. :type set_ptr: bool
- def remove(self, offset, set_ptr=False): Removes a node in the double linked list with a given offset from the currently selected node. :param offset: Offset from the currently selected node: if positive, the node will be removed from the successors, else it will be removed from the predecessors. :type offset: int :param set_ptr: If true, then the "current" pointer of the list will be assigned to the successor of the removed node. :type set_ptr: bool

Implement the Python class `DoubleLinkedList` described below.

Class description:
Util class to implement a double linked list, i.e. a linked list where items both have a connection to the previous and the next node. The list is circular, meaning that the successor of the last node is the first node in the list. The list has a "head" pointer to the first item in the list (arbitrarily chosen in the cycle as the first one added) and a "current" pointer to the currently selected node.

Method signatures and docstrings:
- def __init__(self, head): Initialization function for a double linked list. :param head: Reference to the first node in the list. :type head: DoubleLinkedListNode
- def print(self): Util function to display the double linked list, starting from the head (and stopping at the end of the first cycle).
- def add(self, data, set_ptr=False): Adds a node at the end of the double linked list. :param data: Value of the node to add. :type data: int :param set_ptr: If true, then the "current" pointer of the list will be assigned to the newly created node. :type set_ptr: bool
- def insert(self, offset, data, set_ptr=False): Inserts a node in the double linked list with a given offset from the currently selected node. :param offset: Offset from the currently selected node: if positive, the node will be inserted in the successors, else it will be inserted in the predecessors. :type offset: int :param data: Value of the node to insert. :type data: int :param set_ptr: If true, then the "current" pointer of the list will be assigned to the newly created node. :type set_ptr: bool
- def remove(self, offset, set_ptr=False): Removes a node in the double linked list with a given offset from the currently selected node. :param offset: Offset from the currently selected node: if positive, the node will be removed from the successors, else it will be removed from the predecessors. :type offset: int :param set_ptr: If true, then the "current" pointer of the list will be assigned to the successor of the removed node. :type set_ptr: bool

<|skeleton|>
class DoubleLinkedList:
    """Util class to implement a double linked list, i.e. a linked list where items both have a connection to the previous and the next node. The list is circular, meaning that the successor of the last node is the first node in the list. The list has a "head" pointer to the first item in the list (arbitrarily chosen in the cycle as the first one added) and a "current" pointer to the currently selected node."""

    def __init__(self, head):
        """Initialization function for a double linked list. :param head: Reference to the first node in the list. :type head: DoubleLinkedListNode"""
        <|body_0|>

    def print(self):
        """Util function to display the double linked list, starting from the head (and stopping at the end of the first cycle)."""
        <|body_1|>

    def add(self, data, set_ptr=False):
        """Adds a node at the end of the double linked list. :param data: Value of the node to add. :type data: int :param set_ptr: If true, then the "current" pointer of the list will be assigned to the newly created node. :type set_ptr: bool"""
        <|body_2|>

    def insert(self, offset, data, set_ptr=False):
        """Inserts a node in the double linked list with a given offset from the currently selected node. :param offset: Offset from the currently selected node: if positive, the node will be inserted in the successors, else it will be inserted in the predecessors. :type offset: int :param data: Value of the node to insert. :type data: int :param set_ptr: If true, then the "current" pointer of the list will be assigned to the newly created node. :type set_ptr: bool"""
        <|body_3|>

    def remove(self, offset, set_ptr=False):
        """Removes a node in the double linked list with a given offset from the currently selected node. :param offset: Offset from the currently selected node: if positive, the node will be removed from the successors, else it will be removed from the predecessors. :type offset: int :param set_ptr: If true, then the "current" pointer of the list will be assigned to the successor of the removed node. :type set_ptr: bool"""
        <|body_4|>

<|end_skeleton|>

<|body_start_0|>
        self.head = head
        self.current = head
        self.length = 1
<|end_body_0|>

<|body_start_1|>
        iter = self.head
        output = []
        in_loop = False
        while iter is not None:
            if in_loop and iter == self.head:
                break
            if iter == self.current:
                output.append('(%s)' % iter.data)
            else:
                output.append(str(iter.data))
            iter = iter.next
            if not in_loop:
                in_loop = True
        print(' '.join(output))
<|end_body_1|>

<|body_start_2|>
        if self.length == 1:
            node = DoubleLinkedListNode(data, self.head, self.head)
            self.head.next = node
            self.head.prev = node
        else:
            prev = self.head.prev
            node = DoubleLinkedListNode(data, prev, self.head)
            if prev is not None:
                prev.next = node
            self.head.prev = node
        self.length += 1
        if set_ptr:
            self.current = node
<|end_body_2|>

<|body_start_3|>
        iter = self.current
        pace = 0
        if offset > 0:
            while iter.next is not None and pace < offset - 1:
                iter = iter.next
                pace += 1
            node = DoubleLinkedListNode(data, iter, iter.next)
            iter.next.prev = node
            iter.next = node
            self.length += 1
        elif offset < 0:
            while iter.prev is not None and pace < -offset - 1:
                iter = iter.prev
                pace += 1
            node = DoubleLinkedListNode(data, iter.prev, iter)
            iter.prev.next = node
            iter.prev = node
            self.length += 1
        else:
            self.current.data = data
        if set_ptr:
            self.current = node
<|end_body_3|>

<|body_start_4|>
        iter = self.current
        pace = 0
        if offset > 0:
            while iter.next is not None and pace < offset:
                iter = iter.next
                pace += 1
        elif offset < 0:
            while iter.prev is not None and pace < -offset:
                iter = iter.prev
                pace += 1
        d = iter.data
        p, n = (iter.prev, iter.next)
        iter.prev.next = n
        iter.next.prev = p
        self.length -= 1
        if iter == self.head:
            self.head = iter.next
        if set_ptr:
            self.current = iter.next
        return d
<|end_body_4|>

Solution:
class DoubleLinkedList:
    """Util class to implement a double linked list, i.e. a linked list where items both have a connection to the previous and the next node. The list is circular, meaning that the successor of the last node is the first node in the list. The list has a "head" pointer to the first item in the list (arbitrarily chosen in the cycle as the first one added) and a "current" pointer to the currently selected node."""

    def __init__(self, head):
        """Initialization function for a double linked list. :param head: Reference to the first node in the list. :type head: DoubleLinkedListNode"""
        self.head = head
        self.current = head
        self.length = 1

    def print(self):
        """Util function to display the double linked list, starting from the head (and stopping at the end of the first cycle)."""
        iter = self.head
        output = []
        in_loop = False
        while iter is not None:
            if in_loop and iter == self.head:
                break
            if iter == self.current:
                output.append('(%s)' % iter.data)
            else:
                output.append(str(iter.data))
            iter = iter.next
            if not in_loop:
                in_loop = True
        print(' '.join(output))

    def add(self, data, set_ptr=False):
        """Adds a node at the end of the double linked list. :param data: Value of the node to add. :type data: int :param set_ptr: If true, then the "current" pointer of the list will be assigned to the newly created node. :type set_ptr: bool"""
        if self.length == 1:
            node = DoubleLinkedListNode(data, self.head, self.head)
            self.head.next = node
            self.head.prev = node
        else:
            prev = self.head.prev
            node = DoubleLinkedListNode(data, prev, self.head)
            if prev is not None:
                prev.next = node
            self.head.prev = node
        self.length += 1
        if set_ptr:
            self.current = node

    def insert(self, offset, data, set_ptr=False):
        """Inserts a node in the double linked list with a given offset from the currently selected node. :param offset: Offset from the currently selected node: if positive, the node will be inserted in the successors, else it will be inserted in the predecessors. :type offset: int :param data: Value of the node to insert. :type data: int :param set_ptr: If true, then the "current" pointer of the list will be assigned to the newly created node. :type set_ptr: bool"""
        iter = self.current
        pace = 0
        if offset > 0:
            while iter.next is not None and pace < offset - 1:
                iter = iter.next
                pace += 1
            node = DoubleLinkedListNode(data, iter, iter.next)
            iter.next.prev = node
            iter.next = node
            self.length += 1
        elif offset < 0:
            while iter.prev is not None and pace < -offset - 1:
                iter = iter.prev
                pace += 1
            node = DoubleLinkedListNode(data, iter.prev, iter)
            iter.prev.next = node
            iter.prev = node
            self.length += 1
        else:
            self.current.data = data
        if set_ptr:
            self.current = node

    def remove(self, offset, set_ptr=False):
        """Removes a node in the double linked list with a given offset from the currently selected node. :param offset: Offset from the currently selected node: if positive, the node will be removed from the successors, else it will be removed from the predecessors. :type offset: int :param set_ptr: If true, then the "current" pointer of the list will be assigned to the successor of the removed node. :type set_ptr: bool"""
        iter = self.current
        pace = 0
        if offset > 0:
            while iter.next is not None and pace < offset:
                iter = iter.next
                pace += 1
        elif offset < 0:
            while iter.prev is not None and pace < -offset:
                iter = iter.prev
                pace += 1
        d = iter.data
        p, n = (iter.prev, iter.next)
        iter.prev.next = n
        iter.next.prev = p
        self.length -= 1
        if iter == self.head:
            self.head = iter.next
        if set_ptr:
            self.current = iter.next
        return d