content: #!/usr/local/bin/python
  # -*- coding: utf-8 -*-
  
  import calendar
  import os
  
  import pandas as pd
  
  
  # Правила подсчета очков:
  #
  # за участие в матче – 2 очка, если сыграно 10 минут и больше; 1 очко, если сыграно меньше 10 минут
  #
  # за победу – 3 очка (в гостях); 2 очка (дома)
  #
  # за поражение – минус 3 очка (дома); минуc 2 очка (в гостях)
  #
  # Принцип начисления очков следующий:
  #
  # количество очков + количество передач + количество перехватов + количество подборов +
  # количество блок-шотов + количество совершенных штрафных + количество совершенных двухочковых + количество совершенных трехочковых
  #
  #  - количество попыток штрафных бросков - количество попыток двухочковых – количество попыток трехочковых –
  # удвоенная цифра от количества потерь - количество фолов
  
  def convert_to_sec(time_str):
      if pd.isnull(time_str):
          return 0
      try:
          m, s = time_str.split(':')
          return int(m) * 60 + int(s)
      except Exception as inst:
          print(time_str)
          print(type(inst))  # the exception instance
          print(inst.args)  # arguments stored in .args
  
  
  def get_sec(row):
      time_str = row['minutes']
      return convert_to_sec(time_str)
  
  
  def getOrDefault(value):
      if pd.isnull(value):
          return 0
      return int(value)
  
  
  def extractYear(row):
      return row['date'].year
  
  
  def extractMonth(row):
      return row['date'].month
  
  
  def extractDay(row):
      return row['date'].day
  
  
  def concat1(row):
      return row['opponent'] + str(row['year'])
  
  
  def concat2(row):
      return row['team'] + str(row['year'])
  
  
  def concat3(row):
      return row['name'] + str(row['year'])
  
  
  def concat4(row):
      return row['opponent'] + str(row['month']) + str(row['year'])
  
  
  def concat5(row):
      return row['team'] + str(row['month']) + str(row['year'])
  
  
  def concat6(row):
      return row['name'] + str(row['month']) + str(row['year'])
  
  
  def getDayOfTheWeek(row):
      day = calendar.day_name[row['date'].weekday()]
      return day[:3]
  
  
  def convert_age(row):
      if pd.isnull(row['age']):
          return 0
      years, days = row['age'].split('-')
      return int(years) + 1.0 * int(days) / 365
  
  
  def split_result(x):
      try:
          sp = x.split('(')
          return sp[0].strip(), sp[1][:-1]
      except Exception as inst:
          print(x)
          print(type(inst))  # the exception instance
          print(inst.args)  # arguments stored in .args
  
  
  #   (FG + 0.5 * 3P) / FGA
  def calc_efg(row):
      try:
          fg = row['fg']
          fg3 = row['fg3']
          fga = row['fga']
          if fga == 0:
              return 0.0
          return (fg + 0.5 * fg3) / fga
      except Exception as inst:
          print(row)
          print(type(inst))  # the exception instance
          print(inst.args)  # arguments stored in .args
  
  
  def calc_fantasy(row):
      if pd.isnull(row['minutes']):
          return 0
      fantasy_points = 0
      if convert_to_sec(row['minutes']) >= 10 * 60:
          fantasy_points += 2
      else:
          fantasy_points += 1
      if 'W' in str(row['result']):
          if row['location'] == '@':
              fantasy_points += 3
          else:
              fantasy_points += 2
      else:
          if row['location'] == '@':
              fantasy_points -= 2
          else:
              fantasy_points -= 3
      fantasy_points += getOrDefault(row['pts'])
      fantasy_points += getOrDefault(row['ast'])
      fantasy_points += getOrDefault(row['stl'])
      fantasy_points += getOrDefault(row['trb'])
      fantasy_points += getOrDefault(row['blk'])
      fantasy_points += getOrDefault(row['ft'])
      fantasy_points += getOrDefault(row['fg'])
  
      fantasy_points -= getOrDefault(row['fta'])
      fantasy_points -= getOrDefault(row['fga'])
      fantasy_points -= 2 * getOrDefault(row['tov'])
      fantasy_points -= getOrDefault(row['pf'])
  
      return fantasy_points
  
  
  def enrich_player_df(df):
      df['fantasy_points'] = df.apply(lambda row: calc_fantasy(row), axis=1)
      df['year'] = df.apply(lambda row: extractYear(row), axis=1)
      df['month'] = df.apply(lambda row: extractMonth(row), axis=1)
      df['day'] = df.apply(lambda row: extractDay(row), axis=1)
      df['opponent2'] = df.apply(lambda row: concat1(row), axis=1)
      df['opponent3'] = df.apply(lambda row: concat4(row), axis=1)
      df['team3'] = df.apply(lambda row: concat5(row), axis=1)
      df['name3'] = df.apply(lambda row: concat6(row), axis=1)
      df['name2'] = df.apply(lambda row: concat3(row), axis=1)
      df['team2'] = df.apply(lambda row: concat2(row), axis=1)
      df['age1'] = df.apply(lambda row: convert_age(row), axis=1)
      df['seconds'] = df.apply(lambda row: get_sec(row), axis=1)
  
      for i in range(1, 6):
          df['mean_pts_' + str(i)] = df['pts'].rolling(i).mean().shift(1)
  
      df['efg'] = df.apply(lambda row: calc_efg(row), axis=1)
      df['mefg'] = df['efg'].expanding().mean().shift(1)
      df['day_of_the_week'] = df.apply(lambda row: getDayOfTheWeek(row), axis=1)
      df['mfp'] = df['fantasy_points'].expanding().mean().shift(1)
      df['medfp'] = df['fantasy_points'].expanding().median().shift(1)
      df['msec'] = df['seconds'].expanding().mean().shift(1)
      df['mpts'] = df['pts'].expanding().mean().shift(1)
      df['mast'] = df['ast'].expanding().mean().shift(1)
      df['mtrb'] = df['trb'].expanding().mean().shift(1)
      df['mstl'] = df['stl'].expanding().mean().shift(1)
      df['mpf'] = df['pf'].expanding().mean().shift(1)
      df['mtov'] = df['tov'].expanding().mean().shift(1)
      df['mblk'] = df['blk'].expanding().mean().shift(1)
      df['mfg'] = df['fg'].expanding().mean().shift(1)
      df['mfg3'] = df['fg3'].expanding().mean().shift(1)
      df['mft'] = df['ft'].expanding().mean().shift(1)
  
      df['mfg3_pct'] = df['fg3_pct'].expanding().mean().shift(1)
      df['mfg_pct'] = df['fg_pct'].expanding().mean().shift(1)
      df['mft_pct'] = df['ft_pct'].expanding().mean().shift(1)
  
      # number of games in last 5 days
      df['rest_days'] = df['date'].diff().apply(lambda x: x.days)
  
      for i in [1, 7, 10, 11, 12]:
          df['mean_rest_days_' + str(i)] = df['rest_days'].rolling(i).mean().shift(1)
  
      for i in [10, 21, 31, 38, 39]:
          df['mean_fantasy_' + str(i)] = df['fantasy_points'].rolling(i).mean().shift(1)
  
      for i in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]:
          df['mean_sec_' + str(i)] = df['seconds'].rolling(i).mean().shift(1)
  
      for i in [3, 4, 12, 16, 17, 28, 36]:
          df['skew_fantasy_' + str(i)] = df['fantasy_points'].rolling(i).skew().shift(1)
  
      return df
  
  
  def enrich_player_df_for_upcoming_games(df):
      df['fantasy_points'] = df.apply(lambda row: calc_fantasy(row), axis=1)
      df['year'] = df.apply(lambda row: extractYear(row), axis=1)
      df['month'] = df.apply(lambda row: extractMonth(row), axis=1)
      df['day'] = df.apply(lambda row: extractDay(row), axis=1)
      df['opponent2'] = df.apply(lambda row: concat1(row), axis=1)
      df['opponent3'] = df.apply(lambda row: concat4(row), axis=1)
      df['team3'] = df.apply(lambda row: concat5(row), axis=1)
      df['name3'] = df.apply(lambda row: concat6(row), axis=1)
      df['name2'] = df.apply(lambda row: concat3(row), axis=1)
      df['team2'] = df.apply(lambda row: concat2(row), axis=1)
      df['age1'] = df.apply(lambda row: convert_age(row), axis=1)
      df['seconds'] = df.apply(lambda row: get_sec(row), axis=1)
  
      for i in range(1, 6):
          df['mean_pts_' + str(i)] = df['pts'].rolling(i).mean().shift(1)
  
      df['efg'] = df.apply(lambda row: calc_efg(row), axis=1)
      df['mefg'] = df['efg'].expanding().mean().shift(1)
      df['day_of_the_week'] = df.apply(lambda row: getDayOfTheWeek(row), axis=1)
      df['mfp'] = df['fantasy_points'].expanding().mean().shift(1)
      df['medfp'] = df['fantasy_points'].expanding().median().shift(1)
      df['msec'] = df['seconds'].expanding().mean().shift(1)
      df['mpts'] = df['pts'].expanding().mean().shift(1)
      df['mast'] = df['ast'].expanding().mean().shift(1)
      df['mtrb'] = df['trb'].expanding().mean().shift(1)
      df['mstl'] = df['stl'].expanding().mean().shift(1)
      df['mpf'] = df['pf'].expanding().mean().shift(1)
      df['mtov'] = df['tov'].expanding().mean().shift(1)
      df['mblk'] = df['blk'].expanding().mean().shift(1)
      df['mfg'] = df['fg'].expanding().mean().shift(1)
      df['mfg3'] = df['fg3'].expanding().mean().shift(1)
      df['mft'] = df['ft'].expanding().mean().shift(1)
  
      df['mfg3_pct'] = df['fg3_pct'].expanding().mean().shift(1)
      df['mfg_pct'] = df['fg_pct'].expanding().mean().shift(1)
      df['mft_pct'] = df['ft_pct'].expanding().mean().shift(1)
  
      # number of games in last 5 days
      df['rest_days'] = df['date'].diff().apply(lambda x: x.days)
  
      for i in [1, 7, 10, 11, 12]:
          df['mean_rest_days_' + str(i)] = df['rest_days'].rolling(i).mean().shift(1)
  
      for i in [10, 21, 31, 38, 39]:
          df['mean_fantasy_' + str(i)] = df['fantasy_points'].rolling(i).mean().shift(1)
  
      for i in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]:
          df['mean_sec_' + str(i)] = df['seconds'].rolling(i).mean().shift(1)
  
      for i in [3, 4, 12, 16, 17, 28, 36]:
          df['skew_fantasy_' + str(i)] = df['fantasy_points'].rolling(i).skew().shift(1)
      return df
  
  
  dateparse = lambda x: pd.datetime.strptime(x, '%Y-%m-%d')
  
  
  def enrich_all_data():
      for root, dirs, files in os.walk("nba"):
          for file in files:
              if file.endswith(".csv"):
                  try:
                      path = os.path.join(root, file)
                      if path.find('fantasy') == -1 and path.find('2018.csv') != -1:
                          f = open(path)
                          print(path)
                          lines = f.readlines()
                          if len(lines) > 1:
                              df = pd.read_csv(path,
                                               parse_dates=['date'],
                                               date_parser=dateparse)
                          if not df.empty:
                              df.fillna(df.mean(), inplace=True)
                              df = enrich_player_df(df)
                              join = os.path.join(root, "fantasy")
                              if not os.path.exists(join):
                                  os.mkdir(join)
                              df.to_csv(os.path.join(root, "fantasy", file), index=False)
                  except Exception as inst:
                      print(file)
                      print(df.head())
                      print(type(inst))  # the exception instance
                      print(inst.args)  # arguments stored in .args
  