# Buggy code
def animate_open(self):
    """Animate the menu sliding in

    :return:
    """
    self.state = "opening"  # required

    # position the menu off screen.  it will be slid into view with an animation
    right, height = prepare.SCREEN_SIZE

    # TODO: more robust API for sizing (kivy esque?)
    # TODO: after menu "add" merge, this can be simplified
    # this is highly irregular:
    # shrink to get the final width
    # record the width
    # turn off shrink, then adjust size
    self.shrink_to_items = True  # force shrink of menu
    self.menu_items.expand = False  # force shrink of items
    self.refresh_layout()  # rearrange items
    width = self.rect.width  # store the ideal width

    self.shrink_to_items = False  # force shrink of menu
    self.menu_items.expand = True  # force shrink of items
    self.refresh_layout()  # rearrange items
    self.rect = pygame.Rect(right, 0, width, height)  # set new rect

    # animate the menu sliding in
    ani = self.animate(self.rect, x=right - width, duration=0.50)
    ani.callback = lambda: setattr(self, "state", "normal")
    return ani


# Traceback (KeyError)
Traceback (most recent call last):
File "./tuxemon.py", line 60, in <module>
main()
File "/tmp/Tuxemon/tuxemon/core/main.py", line 109, in main
control.main()
File "/tmp/Tuxemon/tuxemon/core/control.py", line 512, in main
self.main_loop()
File "/tmp/Tuxemon/tuxemon/core/control.py", line 573, in main_loop
self.update(time_delta)
File "/tmp/Tuxemon/tuxemon/core/control.py", line 203, in update
state.update(dt)
File "/tmp/Tuxemon/tuxemon/core/states/combat/combat.py", line 156, in update
self.update_phase()
File "/tmp/Tuxemon/tuxemon/core/states/combat/combat.py", line 328, in update_phase
self.handle_action_queue()
File "/tmp/Tuxemon/tuxemon/core/states/combat/combat.py", line 338, in handle_action_queue
self.check_party_hp()
File "/tmp/Tuxemon/tuxemon/core/states/combat/combat.py", line 614, in check_party_hp
self.faint_monster(monster)
File "/tmp/Tuxemon/tuxemon/core/states/combat/combat.py", line 581, in faint_monster
awarded_exp = monster.total_experience/monster.level/len(self._damage_map[monster])
KeyError: <core.components.monster.Monster object at 0x7fb24236ddd0>

# Fixed code
def animate_open(self):
    """Animate the menu sliding in

    :return:
    """
    self.state = "opening"  # required

    # position the menu off screen.  it will be slid into view with an animation
    right, height = prepare.SCREEN_SIZE

    # TODO: more robust API for sizing (kivy esque?)
    # this is highly irregular:
    # shrink to get the final width
    # record the width
    # turn off shrink, then adjust size
    self.shrink_to_items = True  # force shrink of menu
    self.menu_items.expand = False  # force shrink of items
    self.refresh_layout()  # rearrange items
    width = self.rect.width  # store the ideal width

    self.shrink_to_items = False  # force shrink of menu
    self.menu_items.expand = True  # force shrink of items
    self.refresh_layout()  # rearrange items
    self.rect = pygame.Rect(right, 0, width, height)  # set new rect

    # animate the menu sliding in
    ani = self.animate(self.rect, x=right - width, duration=0.50)
    ani.callback = lambda: setattr(self, "state", "normal")
    return ani