<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def choice(self, message, choices=None, select=None, cancel=None, msg_position='above', choices_to_return=None):
 """ prompt user to make a choice. :param message: string to display before list of choices :type message: unicode :param choices: dict of possible choices :type choices: dict: keymap->choice (both str) :param choices_to_return: dict of possible choices to return for the choices of the choices of paramter :type choices: dict: keymap->choice key is str and value is any obj) :param select: choice to return if enter/return is hit. Ignored if set to `None`. :type select: str :param cancel: choice to return if escape is hit. Ignored if set to `None`. :type cancel: str :param msg_position: determines if `message` is above or left of the prompt. Must be `above` or `left`. :type msg_position: str :rtype: asyncio.Future """

        choices = choices or {'y': 'yes', 'n': 'no'}
        assert select is None or select in choices.values()
        assert cancel is None or cancel in choices.values()
        assert msg_position in ['left', 'above']

        fut = asyncio.get_event_loop().create_future()  # Create a returned future
        oldroot = self.mainloop.widget

        def select_or_cancel(text):
            """Restore the main screen and invoce the callback (delayed return)
            with the given text."""
            self.mainloop.widget = oldroot
            self._passall = False
            fut.set_result(text)

        # set up widgets
        msgpart = urwid.Text(message)
        choicespart = ChoiceWidget(choices,
                                   choices_to_return=choices_to_return,
                                   callback=select_or_cancel, select=select,
                                   cancel=cancel)

        # build widget
        if msg_position == 'left':
            both = urwid.Columns(
                [
                    ('fixed', len(message), msgpart),
                    ('weight', 1, choicespart),
                ], dividechars=1)
        else:  # above
            both = urwid.Pile([msgpart, choicespart])
        att = settings.get_theming_attribute('global', 'prompt')
        both = urwid.AttrMap(both, att, att)

        # put promptwidget as overlay on main widget
        overlay = urwid.Overlay(both, oldroot,
                                ('fixed left', 0),
                                ('fixed right', 0),
                                ('fixed bottom', 1),
                                None)
        self.mainloop.widget = overlay
        self._passall = True
        return fut