'''
Created on Mar 19, 2014

@author: rcd
'''
import operator

# GIVEN
def readFileAsLines (filename):
    """
    given a string representing the name of a data file, 
      return a list of strings, each of which is a non-empty line 
    """
    f = open(filename)
    fileData = f.readlines()
    f.close()
    return [ line.strip() for line in fileData if len(line) > 1 ]


# GIVEN
def reverseName (name):
    """
    given a string representing a name in the order "first last",
      return a string, the name in the order "last, first" 
    """
    (first, last) = name.split()
    return last + ', ' + first


# GIVEN
def convertStats (statList):
    """
    given a list of strings representing int values,
      return a list of ints, the converted values of the strings
    """
    return [ int(s) for s in statList ]


# GIVEN
def printSorted (players, fieldNames, field):
    """
    print given player data sorted based on a given field first,
      name alphabetically second
    """
    toPrint = []
    # convert each player's dictionary of stats to a list for sorting
    for (k,v) in players.items():
        stats = [ k ]
        for column in fieldNames[1:]:
            stats.append(v[column])
        toPrint.append(stats)
    # print the header row for clarity
    print('\t'.join(fieldNames))
    # print each player and his stats in sorted order
    # CHANGE: added another parameter to itemgetter to sort by multiple fields
    for p in sorted(toPrint, key=operator.itemgetter(fieldNames.index(field), 0)):
        print('\t'.join([ str(x) for x in p ]))
    # print an extra newline as a separator
    print('\n')


# GIVEN
def printCalculation (players, func):
    """
    print given player data sorted based on result of the given function
    that takes a dictionary:
      key is a string, name of the stat from the header row
      value is an int, combined value of that stat from all years played 
    """
    # use stats dictionary for each player to compute composite value for sorting
    results = [ (k, func(v)) for (k, v) in players.items() ]
    for p in sorted(results, key=operator.itemgetter(1), reverse=True):
        print('\t'.join([ str(x) for x in p ]))
    # print an extra newline as a separator
    print('\n')
 


# DONE IN CLASS
def loadData (formattedLines):
    """
    given lines of basketball stats (with a header row), separated by tabs, 
      in the form:
        NAME G MP FG FGA 3P 3PA FT FTA ORB DRB AST STL BLK TOV PF
      return a dictionary whose
        keys are strings, player's name
        values are a dictionary whose
          key is a string, name of the stat from the header row
          value is an int, combined value of that stat from all years played 
    """
    # standard dictionary accumulation loop:
    playerStats = { }                         # initialize the result
    for player in formattedLines[1:]:         # loop over data (minus header row)
        data = player.split('\t')             # transform data from string
        key = reverseName(data[0])
        newStats = convertStats(data[1:])
        if key in playerStats:                # verify key is in dictionary
            currentStats = playerStats[key]   # combine old and new stats
            for idx in range(len(currentStats)):
                currentStats[idx] += newStats[idx]
            # OR as a list comprehension
            # playerStats[key] = [ sum(s) for s in zip(newStats, currentStats) ]
        else:
            playerStats[key] = newStats       # initialize value associated with key
    # transform dictionary data into structure to be used later
    # convert list of ints to dictionary to make it easier to refer to the stats later:
    #   key is a string, name of the stat from the header row
    #   value is an int, combined value of that stat from all years played 
    fieldNames = formattedLines[0].split('\t')
    for (k,v) in playerStats.items():
        playerStats[k] = dict(zip(fieldNames[1:], v))
    return playerStats


# DONE IN CLASS
def totalRebounds (stats):
    """
    return ORB + DRB (both offensive and defensive rebounds)
    """
    return stats['ORB'] + stats['DRB']


# TODO
def totalPoints (stats):
    """
    return FT + 3 * 3P + 2 * (FG - 3P) (number of 1, 2, and 3 points shots made)
    """
    return 0


# TODO
def minutesPerGame (stats):
    """
    return MP / G (total minutes played per all games played)
    """
    return 0



# read data line-by-line from the file,
playerData = readFileAsLines('duke_bball_stats.txt')
# keep headers as a useful way to refer to the data within the program
fieldNames = playerData[0].split('\t')
# load the data into a dictionary,
#   keys are strings, player's first and last name
#   values are a dictionary whose
#     key is a string, name of the stat from the header row
#     value is an int, combined value of that stat from all years played 
playerStats = loadData(playerData)
print(playerStats)

# use the dictionary to explore the data
print("All player stats, sorted by player's name")
printSorted(playerStats, fieldNames, 'NAME')
print("All player stats, sorted by player's minutes played")
printSorted(playerStats, fieldNames, 'MP')
# look at specific combinations of the statistics
print("Player's total rebounds, in sorted order")
printCalculation(playerStats, totalRebounds)
print("Player's total points scored, in sorted order")
printCalculation(playerStats, totalPoints)
print("Player's minutes per game, in sorted order")
printCalculation(playerStats, minutesPerGame)
