from tabulate import tabulate

class DeckAnalysis(object):
    """Analyze how a specific hero performs.
    """

    def __init__(self, games: list, hero: str):
        """Create a new analysis given a list of games and a hero."""
        self.games = games
        self.hero = hero

        self.wins = 0
        self.losses = 0
        self.opponents = {}
        self.__analyze()

    def __analyze(self):
        """Analyze the game data in the context of the hero."""

        for game in self.games:
            if not self.hero == game.hero:
                continue

            if game.won():
                self.wins += 1
            else:
                self.losses += 1

            # Initialize a dict the first time we encounter a new opponent hero.
            opponent = game.opponent
            self.opponents[opponent] = self.opponents.get(opponent, {'games': 0, 'wins': 0, 'losses': 0})
            self.opponents[opponent]['games'] += 1
            if game.won():
                self.opponents[opponent]['wins'] += 1
            else:
                self.opponents[opponent]['losses'] += 1
                
    def summarize(self):
        """Print a table summarizing the game results."""
        
        # We'll be adding more columns based on the opponent classes we encountered.
        headers = ['games', 'wins', 'losses', 'win %']

        # Add the data for the first columns summarizing all games.
        # Tabulate expects a list of lists, where each list represents a row of data.
        game_count = self.wins + self.losses
        table = [[game_count, self.wins, self.losses, (self.wins / game_count) * 100]]

        for opponent, result in sorted(self.opponents.items(), key=lambda k_v: k_v[1]['games'], reverse=True):
            # Add headers and data for this opponent
            headers.append(opponent + ' games')
            table[-1].append(result['games'])
            headers.append('wins')
            table[-1].append(result['wins'])
            headers.append('losses')
            table[-1].append(result['losses'])
            headers.append('win %')
            table[-1].append((result['wins'] / result['games']) * 100)

        print(tabulate(table, headers=headers, floatfmt='.2f'))

@@ -1220,113 +1220,31 @@
     
-%0A        # We'll be adding more columns based on the opponent classes we encountered.%0A        headers = %5B
+headers = %5B'opponent', 
 'gam
@@ -1493,16 +1493,23 @@
 ble = %5B%5B
+'All', 
 game_cou
@@ -1703,24 +1703,13 @@
 Add 
-headers and data
+a row
  for
@@ -1714,32 +1714,33 @@
 or this opponent
+.
 %0A            hea
@@ -1736,31 +1736,29 @@
         
-headers
+table
 .append(
 opponent
@@ -1749,24 +1749,25 @@
 .append(
+%5B
 opponent
  + ' gam
@@ -1762,296 +1762,61 @@
 nent
- + ' games')%0A            table%5B-1%5D.append(result%5B'games'%5D)%0A            headers.append('wins')%0A            table%5B-1%5D.append(result%5B'wins'%5D)%0A            headers.append('losses')%0A            table%5B-1%5D.append(result%5B'losses'%5D)%0A            headers.append('win %25')%0A            table%5B-1%5D.append(
+, result%5B'games'%5D, result%5B'wins'%5D, result%5B'losses'%5D, 
 (res
@@ -1851,16 +1851,17 @@
 %5D) * 100
+%5D
 )%0A%0A     

Switch the deck analysis display to have a row for each opponent