import collections
import decimal
import query, crawl_utils, time, datetime
import loaddb
import sys
import logging
import json

from crawl_utils import clan_link, player_link, linked_text
import crawl_utils
import re

PseudoCol = collections.namedtuple("PseudoCol", ("html_display_name", "numeric_data", "transform_fn"))

BANNER_IMAGES = \
    { 'ashenzari': [ 'banner_ashenzari.png', 'The Explorer' ],
      'cheibriados': [ 'banner_cheibriados.png', 'Slow and Steady' ],
      'dithmenos': [ 'banner_dithmenos.png', 'The Politician' ],
      'fedhas': [ 'banner_fedhas.png', "Nature's Ally" ],
      'gozag': [ 'banner_gozag.png', "Avarice" ],
      'hepliaklqana': [ 'banner_hepliaklqana.png', 'The Inheritor' ],
      'ignis': [ 'banner_ignis.png', 'The Pious' ],
      'jiyva': [ 'banner_jiyva.png', 'Gelatinous Body' ],
      'kikubaaqudgha': [ 'banner_kikubaaqudgha.png', 'Lord of Darkness' ],
      'lugonu': [ 'banner_lugonu.png', 'Spiteful' ],
      'makhleb': [ 'banner_makhleb.png', 'Speed Demon' ],
      'nemelex': [ 'banner_nemelex.png', "Nemelex' Choice" ],
      'okawaru': [ 'banner_okawaru.png', 'The Conqueror' ],
      'qazlal': [ 'banner_qazlal.png', 'The Prophet' ],
      'ru': [ 'banner_ru.png', 'The Ascetic' ],
      'sif': [ 'banner_sif.png', 'The Lorekeeper' ],
      'the_shining_one': [ 'banner_the_shining_one.png', 'Vow of Courage' ],
      'uskayaw': [ 'banner_uskayaw.png', 'Graceful' ],
      'vehumet': [ 'banner_vehumet.png', 'Ruthless Efficiency' ],
      'xom': [ 'banner_xom.png', 'Descent into Madness' ],
      'yredelemnul': [ 'banner_yredelemnul.png', 'The Harvest' ],
      'zin': [ 'banner_zin.png', 'Angel of Justice' ],
      '1top_player': [ 'player.png', 'Top Player'],
      '2top_clan':   [ 'clan.png', 'Top Clan' ],
      'header': ['banner_header.png', '' ],
      'footer': ['banner_footer.png', '' ],
    }

# TODO: this seems redundant with the data in outline.py?
BANNER_TEXT = \
    { 'ashenzari':
        [ 'Enter a branch of the dungeon that contains a rune.',
          'Find 5 distinct runes over the course of the tourney.',
          'Find 17 distinct runes over the course of the tourney.',
        ],
      'cheibriados':
        [ 'Reach experience level 9 in two consecutive games.',
          'Achieve a two-win streak.',
          'Achieve a four-win streak with four distinct species and four distinct backgrounds.',
        ],
      'dithmenos':
        [ 'Steal a combo high score that was previously of at least 1,000 points.',
          'Steal a combo high score for a previously won combo.',
          'Steal a species or background high score that was previously of at least 10,000,000 points.',
        ],
      'fedhas':
        [ 'Enter the Crypt.',
          'Get the golden rune.',
          'Enter Tomb for the first time after picking up the Orb of Zot, and then get the golden rune.',
        ],
      'gozag':
        [ 'Find 1000 gold in a single game.',
          'Find the silver rune.',
          'Find the iron rune before entering Pandemonium or any branch of the dungeon containing any other rune.',
        ],
      'hepliaklqana':
        [ 'Enter the Lair of beasts while worshipping a god from a faded altar, having worshipped no other gods.',
          'Find a rune while worshipping a god from a faded altar, having worshipped no other gods.',
          'Win a game while worshipping a god from a faded altar, having worshipped no other gods.',
        ],
      'ignis':
        [ 'Become the champion of any god.',
          'Become the champion of five different gods over the course of the tournament.',
          'Become the champion of thirteen different gods over the course of the tournament.',
        ],
      'jiyva':
        [ 'Reach experience level 9 with at least 5 distinct species and at least 5 distinct backgrounds.',
          'Get a rune with at least 5 distinct species and at least 5 distinct backgrounds.',
          'Win with at least 5 distinct species and at least 5 distinct backgrounds.',
        ],
      'kikubaaqudgha':
        [ 'Reach the last level of the Orcish Mines without having entered the Lair.',
          'Reach the last level of the Depths without having entered the Lair.',
          'Win a game without having entered the Lair, the Orcish Mines, or the Vaults.',
        ],
      'lugonu':
        [ 'Become the champion of Ru',
          'After becoming the champion of Ru, abandon Ru and become the champion of a different god.',
          'Win a game in which you become the champion of Ru and then abandon Ru before entering any branches other than the Temple and the Lair.',
        ],
      'makhleb':
        [ 'Reach D:15 in 54 minutes as a non-formicid.',
          'Find a rune in 81 minutes.',
          'Win the game in 3 hours.',
        ],
      'nemelex':
        [ "Reach experience level 9 with a Nemelex' choice combo.",
          "Get a rune with a Nemelex' choice combo.",
          "Be one of the first 9 players to win a given Nemelex' choice combo.",
        ],
      'okawaru':
        [ 'Reach experience level 13.',
          'Win a game.',
          'Win a game in under 50000 turns.',
        ],
      'qazlal':
        [ 'Reach the Lair of Beasts with an Invocations title.',
          'Win a game with an Invocations title.',
          'Over the course of the tournament, win with three different Invocations titles.',
        ],
      'ru':
        [ "Reach the Ecumenical Temple without using any potions or scrolls.",
          "Reach the last level of the Lair of Beasts without using any potions or scrolls.",
          "Find a rune (non-slimy, non-abyssal) without using any potions or scrolls.",
        ],
      'sif':
        [ 'Reach the last level of the Lair as a non-formicid without raising any skill to 13.',
          'Win without raising any skill to 20.',
          'Win without raising any skill to 13.',
        ],
      'trog':
        [ 'Enter the Vaults with no runes.',
          'Pick up the silver rune before any other runes.',
          'Pick up the golden rune before any other runes.',
        ],
      'the_shining_one':
        [ 'Kill Sigmund before entering the Depths.',
          'Get four runes before entering the Depths.',
          'Get six runes before entering the Depths.',
        ],
      'uskayaw':
        [ 'Enter the Temple in under 3000 turns.',
          'Enter the third floor of the Elven Halls in under 9000 turns.',
          'Enter the final floor of Gehenna in under 27000 turns.',
        ],
      'vehumet':
        [ 'Reach the last level of the Lair as a non-formicid before reaching experience level 13.',
          'Find a rune before reaching experience level 17.',
          'Win the game before reaching experience level 22.',
        ],
      'xom':
        [ 'Enter the Abyss.',
          'Reach the 10th floor of a ziggurat.',
          'Leave a ziggurat from its lowest floor.',
        ],
      'yredelemnul':
        [ 'Kill 27 distinct uniques over the course of the tournament.',
          'Kill 54 distinct uniques over the course of the tournament.',
          'Kill 81 distinct uniques over the course of the tournament.',
        ],
      'zin':
        [ 'Enter either Pandemonium or any branch of Hell.',
          'Kill at least one unique pan lord and at least one unique hell lord over the course of the tournament.',
          'Kill all four unique pan lords, all four unique hell lords, and the Serpent of Hell (at least once) over the course of the tournament.',
        ],
      '1top_player':
        [ 'Individual with the most tournament points.',
          'Individual with the second-most tournament points.',
          'Individual with the third-most tournament points.',
        ],
      '2top_clan':
        [ 'Clan with the most tournament points.',
          'Clan with the second-most tournament points.',
          'Clan with the third-most tournament points.',
        ],
      'header': [ '' ],
      'footer': [ '' ],
    }

EXT_WIN_COLUMNS = \
    [ ('score', 'Score', True),
      ('race', 'Species'),
      ('class', 'Background'),
      ('god', 'God'),
      ('title', 'Title'),
      ('xl', 'XL'),
      ('turn', 'Turns'),
      ('duration', 'Duration'),
      ('runes', 'Runes'),
      ('end_time', 'Date')
    ]

STOCK_COLUMNS = \
    [ ('player', 'Player'),
      ('score', 'Score', True),
      ('charabbrev', 'Character'),
      ('place', 'Place'),
      ('verb_msg', 'Death'),
      ('turn', 'Turns'),
      ('duration', 'Duration'),
      ('god', 'God'),
      ('runes', 'Runes'),
      ('end_time', 'Time', True)
    ]

STOCK_WIN_COLUMNS = [col for col in STOCK_COLUMNS if col[0] not in ('place', 'verb_msg')]

EXT_COLUMNS = \
    [ ('score', 'Score', True),
      ('race', 'Species'),
      ('class', 'Background'),
      ('god', 'God'),
      ('title', 'Title'),
      ('place', 'Place'),
      ('verb_msg', 'Death'),
      ('xl', 'XL'),
      ('turn', 'Turns'),
      ('duration', 'Duration'),
      ('runes', 'Runes'),
      ('end_time', 'Date')
    ]

WHERE_COLUMNS = \
    [ ('race', 'Species'),
      ('cls', 'Background'),
      ('god', 'God'),
      ('title', 'Title'),
      ('place', 'Place'),
      ('xl', 'XL'),
      ('turn', 'Turns'),
      ('time', 'Time'),
      ('status', 'Status')
    ]

R_STR_DATE = re.compile(r'^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})')

def fixup_column(col, data, game):
  if col.find('time') != -1:
    return pretty_date(data)
  elif col.find('duration') != -1:
    return pretty_dur(data)
  elif col == 'place' and game.get('killertype') == 'winning':
    return ''
  elif col == 'score' and data == '':
    return 0
  return data

def pretty_dur(dur):
  if (not dur) and dur != 0:
    return ""
  try:
    secs = dur % 60
  except:
    print("FAIL on %s" % dur)
    raise
  dur /= 60
  mins = dur % 60
  dur /= 60
  hours = dur
  stime = "%d:%02d:%02d" % (hours, mins, secs)

  return stime

def is_stringlike(s):
  try:
    return isinstance(s, (str, unicode)) #py2
  except:
    return isinstance(s, (str, bytes)) #py3

def pretty_date(date):
  if not date:
    return ''

  if is_stringlike(date):
    m = R_STR_DATE.search(date)
    if not m:
      return date
    return "%s-%s-%s %s:%s:%s" % (m.group(1), m.group(2), m.group(3),
                                  m.group(4), m.group(5), m.group(6))

  return "%04d-%02d-%02d %02d:%02d:%02d" % (date.year, date.month, date.day,
                                            date.hour, date.minute,
                                            date.second)

def pretty_time(time):
  return "%04d-%02d-%02d %02d:%02d:%02d" % (time.tm_year, time.tm_mon,
                                            time.tm_mday,
                                            time.tm_hour, time.tm_min,
                                            time.tm_sec)

def how_old(date, bold_cutoff = 0): #cutoff in hours
  if not date:
    return None,None
  if type(date) == "string":
    delta = datetime.datetime.utcnow() - query.time_from_str(date)
  else:
    delta = datetime.datetime.utcnow() - date
  h = 24*delta.days + delta.seconds / 60 / 60
  m = (delta.seconds / 60) % 60
  s = delta.seconds % 60
  if h < 0:
    return "0:00:00", (0 < bold_cutoff)
  return ("%d:%02d:%02d" % (h, m, s)), (h < bold_cutoff)

def update_time():
  return '''

              Last updated %s UTC.

''' % pretty_time(time.gmtime())

def wrap_tuple(x):
  if isinstance(x, tuple):
    return x
  else:
    return (x,)

def is_player_header(header):
  return header.lower() in ['player', 'captain']

def is_clan_header(header):
  return header.lower() in ['clan', 'team', 'teamname']

def _is_numeric_table_value(value, header=""):
  if is_player_header(header) or is_clan_header(header):
    return False
  if isinstance(value, (int, float, decimal.Decimal)):
    return True
  if is_stringlike(value):
    if value.isdigit():
      return True
    try:
      float(value)
    except ValueError:
      return False
    return True
  return False

# DEPRECATED: Build a wrapper function around _table to replace this
def table_text(headers, data, count=True,
               place_column=-1, stub_text='No data', skip=False, bold=False,
               extra_wide_support=False, caption=None, datatables=False):
  """Create a HTML table of players.

  :param List[str] headers: Column headers
  :param List[List[str]] data: Column data
  :param bool count: Add a "count" column at the start
  :param int place_column: Use this column to determine ranking ties (-1 there are no ties)
  :param str stub_text: Text to show if the table has no data.
  :param bool skip: Use sparse rank numbers (eg two people at rank n means next rank is n+2)
  :param bool bold: Mark winning rows
  :param Optional[str] caption: Table description (for screen readers).

  """
  table_classes = set(("table",
    "table-hover",
    "table-striped",
    "table-dark",
  ))
  if extra_wide_support:
    table_classes.add("table-bordered")
  if datatables:
    table_classes.add("dcss-datatable-wide" if extra_wide_support else "dcss-datatable")
    table_classes.add("nowrap") # keep table rows on one line
  else:
    table_classes.add("table-sm")
    table_classes.add("w-auto")
  out = '''
\n
\n''' % (" ".join(table_classes))

  if caption is not None:
    out += '''
%s
\n''' % caption

  out += '''
\n
'''

  headers = [ wrap_tuple(x) for x in headers ]

  if count:
    out += '''#	'''
  for head in headers:
    out += '''%s	''' % head[0]
  out += "
\n
\n"

  if not data:
    ncols = len(headers) + (1 if count else 0)
    out += '''
%s
''' % (ncols, stub_text)

  # XXX: this is something to do with ranking?
  nplace = 0
  rplace = 0
  last_value = None

  for row in data:
    # TODO: not sure this is necessary with DataTables?
    if bold and row[-1]:
      # Invert colours
      out += '''
'''
    else:
      out += '''
'''

    rplace += 1
    if place_column == -1:
      nplace += 1
    elif last_value != row[place_column]:
      nplace += 1
      if skip:
        nplace = rplace
      last_value = row[place_column]

    if count:
      out += '''%s	''' % (
        "py-1 px-2" if datatables else "",
        nplace,
      )

    for c in range(len(headers)):
      call_classes = set()
      if datatables:
        # More compact display
        call_classes.update(["py-1", "px-2"])
      val = row[c]
      if isinstance(val, str):
        # TODO: is there a better sort value than something like this to use?
        sort_val = "9999999999" if val == "" or val == "-" else val
        val_embedded_str = sort_val.find('"')
        if val_embedded_str > -1:
          # pretty hacky: if there is an embedded '"', we take the contents of
          # that, in order to handle clan links. Better would be to construct the
          # clan link in this function (like player), but doing so is annoyingly
          # complicated. Could also extract the inner text.
          try:
            sort_val = sort_val[val_embedded_str:].split('"')[1]
          except:
            print(sort_val)
            raise
      else:
        sort_val = str(val)
      header = headers[c]

      numeric_col = _is_numeric_table_value(val, header[0])
      pseudo_numeric_col = val == '-'
      if numeric_col:
        val = '{:,}'.format(isinstance(val, str) and int(val) or val)
      if numeric_col or pseudo_numeric_col:
        call_classes.add("text-right")
        call_classes.add("text-monospace")
      if extra_wide_support and is_player_header(header[0]):
        call_classes.add('text-dark')

      if c == place_column:
        out += '''''' % " ".join(call_classes)
      else:
        out += '''''' % (
                  " ".join(call_classes),
                  sort_val)
      val = str(val)
      if is_player_header(header[0]):
        val = linked_text(val, player_link)
      out += val
      if c == place_column:
        out += '	'
      else:
        out += '	'
    out += "
\n"
  out += '
\n
'
  return out

# DEPRECATED: Build a wrapper function around _table to replace this
def games_table(games, first=None, excluding=None, columns=None,
                including=None,
                count=True, win=True,
                place_column=-1, skip=False,
                caption=None):
  """Create a HTML table of games.

  :param List[List[str]] games: Games to list
  :param bool first: ?
  :param Optional[List[str]] excluding: If set, a list of column names to exclude from columns
  :param Optional[List[Union[Tuple[str,str],Tuple[str,str,bool]]]] columns: If set, a list of colum descriptions. The format is (sql column name, html column name[, link col=False]). Defaults to STOCK_WIN_COLUMNS if win is True, otherwise STOCK_COLUMNS.
  :param Optional[List[Tuple[int,Union[Tuple[str,str],Tuple[str,str,bool]]]]] including: If set, a list of (pos, name) tuples of columns to include. pos is the position to insert at.
  :param bool count: Add a count column at the start.
  :param bool win: Select default columns if `columns` is None. See `columns` param for more info.
  :param Optional[str] caption: Table description (for screen readers).
  """
  if columns is None:
    columns = STOCK_WIN_COLUMNS if win else STOCK_COLUMNS

  # Copy columns.
  columns = list(columns)

  if excluding:
    columns = [c for c in columns if c[0] not in excluding]

  if including:
    for pos, col in including:
      columns.insert(pos, col)

  if first and not isinstance(first, tuple):
    first = (first, 1)

  if first and columns[0][0] != first[0]:
    firstc = [ c for c in columns if c[0] == first[0] ]
    columns = [ c for c in columns if c[0] != first[0] ]
    columns.insert( first[1], firstc[0] )

  table_classes = set(("table",
    "table-sm",
    "table-hover",
    "table-striped",
    "table-dark",
    "w-auto",
    ))

  out = '''
\n
\n''' % " ".join(table_classes)

  if caption is not None:
    out += '''
%s
\n''' % caption
  out += '''
\n
'''
  if count:
    out += '''#	'''
  for col in columns:
    out += '''%s	''' % col[1]
  out += "
\n
\n"

  if not games:
    ncols = len(columns) + (1 if count else 0)
    out += '''
No games
''' % ncols

  # XXX: this is something to do with ranking?
  nplace = 0
  rplace = 0
  last_value = None

  for game in games:
    row_class = "table-secondary" if game.get('killertype') == 'winning' else ""

    out += '''
''' % row_class

    rplace += 1
    if place_column == -1:
      nplace += 1
    elif last_value != game.get(columns[place_column][0]):
      nplace += 1
      if skip:
        nplace = rplace
      last_value = game.get(columns[place_column][0])

    if count:
      out += '''%s	''' % nplace

    for i, c in enumerate(columns):
      val = fixup_column(c[0], game.get(c[0]) or '', game)
      numeric_col = _is_numeric_table_value(val, c[0])
      pseudo_numeric_col = val == '-'
      if numeric_col:
        val = '{:,}'.format(isinstance(val, str) and int(val) or val)
      td_class = "text-right text-monospace" if (numeric_col or pseudo_numeric_col) else ""
      if i == place_column:
        out += '''''' % td_class
      else:
        out += '''''' % td_class

      # XXX: this should change
      need_link = len(c) >= 3 and c[2]
      if need_link:
        try:
          out += r'' % crawl_utils.morgue_link(game)
        except:
          sys.stderr.write("Error processing game: " + loaddb.xlog_str(game))
          raise
      elif is_player_header(c[1]):
        val = linked_text(val, player_link)
      out += str(val)
      if need_link:
        out += ''
      if i == place_column:
        out += '	'
      else:
        out += '	'
    out += "
\n"
  out += "
\n
\n"
  return out

def _table(columns, rows, row_classes_fn=None, brief=False):
  # type: (Sequence[ColumnDisplaySpec], Sequence[Sequence[Any]], Optional[Callable[[Any], str]]) -> str
  '''
  Display a HTML table.

  @param columns: Details about columns in display order.
  @param rows: Rows of data in display order.
  @param row_classes_fn: If set, a function which gets passed each row to
                         determine classes for its
.
  '''

  n_columns = len(columns)

  out = ''

  table_classes = set(("table",
    "table-hover",
    "table-striped",
    "table-dark",
    ))
  if brief:
    table_classes.add("dcss-datatable-compact")
  else:
    table_classes.add("dcss-datatable")
    table_classes.add("table-bordered")

  out += '
\n'
  out += '
\n'.format(classes=" ".join(table_classes))

  # Table column headers
  out += '
\n'
  out += '
'
  for column in columns:
    out += '{name}	'.format(name=column.html_display_name)
  out += '
\n'
  out += '
\n'

  for row in rows:
    if len(row) != n_columns:
      raise ValueError("Row length {n_row} != columns length {n_cols}. Row data: {row} Col data: {cols}".format(
        n_row=len(row),
        n_cols=n_columns,
        row=repr(row),
        cols=columns,
      ))

    out += '
'.format(
      row_classes="" if row_classes_fn is None else row_classes_fn(row)
    )

    for column, base_value in zip(columns, row):
      cell_classes = set([
        # compact rows
        "py-1",
        "px-2",
      ])
      if column.numeric_data:
        cell_classes.update(['text-right', 'text-monospace'])

      if callable(column.transform_fn):
        display_value = column.transform_fn(base_value)
      elif column.numeric_data:
        # Basic thousands separators for untransformed numeric data
        display_value = '{:,}'.format(base_value)
      else:
        try:
          display_value = unicode(base_value)
        except:
          display_value = base_value # already unicode in py3

      out += '{value}	'.format(
        cell_classes=" ".join(cell_classes),
        value = display_value,
      )
    out += '
\n'
  out += '
\n'
  out += '
\n'
  return out

def category_table(category, rows, row_classes_fn=None, brief=False):
  """
  Display a HTML table for a given category. We just need to add the
  Rank & Player/Captain columns.
  """
  cols = [col for col in category.columns if (not brief or col.include_in_compact_display)]
  # logging.info(
  #   "category_table %s %s brief:%s base_cols:%s row0:%s",
  #   category.type, category.name, brief, len(cols),
  #   rows[0] if len(rows) else "<empty>")
  if category.type == 'individual':
    cols.insert(0, PseudoCol(
      "Player",
      False,
      lambda player: crawl_utils.linked_text(key=player, link_fn=crawl_utils.player_link),
    ))
  else:
    def _pretty_clan_name(data):
      info = json.loads(data)
      name = info["name"]
      return '{name}'.format(
          url=crawl_utils.clan_link(name, info["captain"]), name=name,
      )
    cols.insert(0, PseudoCol("Team", False, _pretty_clan_name))
  cols.insert(0, PseudoCol("#", True, None))

  return _table(
    columns=cols,
    rows=rows,
    row_classes_fn=row_classes_fn,
    brief=brief,
  )

def full_games_table(games, **pars):
  if not pars.get('columns'):
    if 'win' in pars:
      win = pars['win']
    else:
      win = True
    pars['columns'] = win and EXT_WIN_COLUMNS or EXT_COLUMNS
  return games_table(games, **pars)

def ext_games_table(games, win=True, **pars):
  cols = win and EXT_WIN_COLUMNS or EXT_COLUMNS
  pars.setdefault('including', []).append((1, ('player', 'Player')))
  return games_table(games, columns=cols, count=False, **pars)

def combo_highscorers(c):
  hs = query.get_top_combo_highscorers(c)
  return table_text( [ 'Player', 'Combo scores' ],
                     hs, place_column=1, skip=True )

def deepest_xl1_games(c):
  games = query.get_deepest_xl1_games(c)
  return games_table(games, first = 'place', win=False)

def most_pacific_wins(c):
  games = query.most_pacific_wins(c)
  return games_table(games,
                     columns = STOCK_WIN_COLUMNS + [('kills', 'Kills')])

def hyperlink_games(games, field):
  hyperlinks = [ crawl_utils.morgue_link(g) for g in games ]
  text = [ '%s' % (link, g[field])
           for link, g in zip(hyperlinks, games) ]
  return ", ".join(text)

def youngest_rune_finds(c):
  runes = query.youngest_rune_finds(c)
  runes = [list(r) for r in runes]
  for r in runes:
    r[3] = pretty_date(r[3])
  return table_text([ 'Player', 'Rune', 'XL', 'Time' ], runes)

def most_deaths_to_uniques(c):
  rows = query.most_deaths_to_uniques(c)
  for r in rows:
    r.insert(1, len(r[1]))
    r[2] = ", ".join(r[2])
  return table_text([ 'Player', '#', 'Uniques', 'Time'], rows)

def streak_table(streaks, active=False, place=False):
  # Replace the list of streak games with hyperlinks.
  result = []

  nplace = 0
  rplace = 0
  last_value = None
  for s in streaks:
    games = s['games']
    game_text = hyperlink_games(games, 'charabbrev')
    if active and s['is_active']:
      game_text += ", " + (s['next_char'] or "?")
    rplace += 1
    if last_value != s['length']:
      nplace = rplace
      last_value = s['length']
    row = [nplace, s['player'], s['length'], game_text]
    result.append(row)

  return _table([ PseudoCol('#', True, None),
                  PseudoCol('Player', False, lambda player: crawl_utils.linked_text(key=player, link_fn=crawl_utils.player_link)),
                  PseudoCol('Streak Length', True, None),
                  PseudoCol('Games', False, None), ],
                  result, brief=True)

def best_active_streaks(c):
  return streak_table(query.get_top_active_streaks(c), active=True)

def best_streaks(c):
  streaks = query.get_top_streaks(c)
  return streak_table(streaks, place=True)

def fixup_clan_rows(rows):
  rows = [ list(r) for r in rows ]
  for clan in rows:
    clan[0] = linked_text(clan[1], clan_link, clan[0])
  return rows

def best_clans(c):
  clans = fixup_clan_rows(query.get_top_clan_scores(c))
  return table_text( [ 'Clan', 'Captain', 'Points' ],
                     clans, place_column=2, skip=True )

def clan_unique_kills(c):
  ukills = fixup_clan_rows(query.get_top_clan_unique_kills(c))
  return table_text( [ 'Clan', 'Captain', 'Kills', 'Time' ],
                     ukills)

def clan_combo_highscores(c):
  return table_text( [ 'Clan', 'Captain', 'Scores' ],
                     fixup_clan_rows(query.get_top_clan_combos(c)),
                     place_column=2, skip=True )

def make_milestone_string(w, src, make_links=False):
  ago,new = how_old(w[0])
  if ago == None:
    return None
  if make_links:
    plink = crawl_utils.linked_text(w[1], crawl_utils.player_link)
  else:
    plink = w[1]
  if w[5] == None:
    god_phrase = ''
  else:
    god_phrase = ' of %s' % w[5]
  where_nice = (ago, plink) + w[2:5] + (god_phrase, ) + w[6:9] + (pretty_dur(w[9]),src)
  return ("%s ago: %s the %s (L%d %s%s) %s (%s, turn %d, dur %s, %s)
" % where_nice)

def whereis(c, *players):
  where_data = []
  for p in players:
    for src in ['cao','cbr2','cdo', 'cko', 'cpo', 'cue','cwz','cxc','lld']:
      where = query.whereis_player(c, p, src)
      if not where:
        continue
      mile_string = make_milestone_string(where, src)
      if not mile_string:
        continue
      where_data.append([where[0], mile_string])
  where_data.sort(key=lambda e: e[0], reverse=True)
  where_string = ""
  for w in where_data:
    where_string += w[1]
  return where_string

def whereis_table(c):
  where_data = []
  for w in query.whereis_all_players(c):
    where = w[1]
    if w[0] == 'csz':
      pretty_src = 'cszo'
    elif w[0] == 'cbr':
      pretty_src = 'cbr2'
    else:
      pretty_src = w[0]
    ago,new = how_old(where[0],1)
    if ago == None:
      continue
    if where[5] == None:
      god_phrase = ''
    else:
      god_phrase = ' of %s' % where[5]
    mile_data = [where[1], where[7], where[3], '%s%s' % (where[4], god_phrase), where[2], where[6], '%s ago' % ago, pretty_src.upper()]
    where_data.append([where[7], where[3], where[0], mile_data])
  where_data.sort(key=lambda e: (e[0],e[1],e[2]), reverse=True)

  where_list = []
  for w in where_data:
    where_list.append(w[3])
    if where_list[-1][1] == 0:
      where_list[-1][1] = ''
  return _table([
      PseudoCol("Player", False,
      lambda player: crawl_utils.linked_text(key=player,
          link_fn=crawl_utils.player_link)),
      PseudoCol("Runes", False, None),
      PseudoCol('Level', False, None),
      PseudoCol('Character', False, None),
      PseudoCol('Title', False, None),
      PseudoCol('Location', False, None),
      PseudoCol('Time', False, None),
      PseudoCol('Server', False, None) ], where_list)

def _strip_banner_suffix(banner):
  if ':' in banner:
    return banner[ : banner.index(':')]
  return banner

def banner_suffix(banner):
  if ':' in banner:
    return banner[banner.index(':') + 1 :]
  return ''

def banner_image(banner, prestige, full_name=False):
  p = prestige
  while p > 3:
    p = p/10
  i_string = ''
  for i in range(p):
    i_string = i_string + 'I'
  name_suffix = banner_suffix(banner)
  banner_subkey = _strip_banner_suffix(banner)
  img = BANNER_IMAGES.get(banner) or BANNER_IMAGES.get(banner_subkey)
  banner_text = BANNER_TEXT[banner_subkey][p-1]
  name = ''
  if img and img[1]:
    name = img[1] + " " + i_string
  if full_name and name_suffix:
    name = name + " (" + name_suffix + ")"
  if img and img[1]:
    name = name + ": " + banner_text
  if img and img[0]:
    filename = img[0][:-4]+("%d" % p)+img[0][-4:]
    return (crawl_utils.banner_link(filename), name)
  return img

def banner_img_for(b, nth):
  if nth:
    bid = " id=\"banner-%d\" " % nth
  else:
    bid = ""
  return '''

''' % (b[0], b[1], b[1], bid)

def banner_named(name, prestige):
  img = banner_image(name, prestige)
  if not img:
    return None
  return banner_img_for(img, 0)

def banner_images(banners):
  # First remove duplicates. We assume that higher prestige versions come first.
  seen_banners = set()
  deduped = []
  for b in banners:
    if not _strip_banner_suffix(b[0]) in seen_banners:
      deduped.append(b)
      seen_banners.add(_strip_banner_suffix(b[0]))
  images = [banner_image(x[0],x[1]) for x in deduped]
  images = [i for i in images if i and i[0]]
  return images

def banner_div(all_banners):
  res = ''
  banner_n = 1
  for b in all_banners:
    res += banner_img_for(b, banner_n)
    banner_n += 1
  return res

def _scored_win_text(g, text):
  if g['killertype'] == 'winning':
    text += '*'
  return text

def player_combo_scores(c, player):
  games = query.get_combo_scores(c, player=player)
  games = [ [ crawl_utils.linked_text(g, crawl_utils.morgue_link,
                                      _scored_win_text(g, g['charabbrev'])),
              g['score'] ]
            for g in games ]
  return games

def player_species_scores(c, player):
  games = query.game_hs_species(c, player)

  games = [
    [ crawl_utils.linked_text(g, crawl_utils.morgue_link,
                              _scored_win_text(g, g['charabbrev'][:2])),
      g['score'] ]
    for g in games ]
  return games

def player_class_scores(c, player):
  games = query.game_hs_classes(c, player)
  games = [
    [ crawl_utils.linked_text(g, crawl_utils.morgue_link,
                              _scored_win_text(g, g['charabbrev'][2:])),
      g['score'] ]
    for g in games ]
  return games

def clan_combo_scores(c, captain):
  games = [i[1] for i in query.get_clan_combo_scores(c, captain=captain)]
  games = [ [ crawl_utils.linked_text(g, crawl_utils.morgue_link,
                                      _scored_win_text(g, g['charabbrev'])),
              g['score'] ]
            for g in games ]
  return games

def player_scores_block(c, scores, title):
  asterisk = [ s for s in scores if '*' in s[0] ]
  score_table = (scores
                 and (", ".join([ "%s (%d)" % (s[0], s[1])
                                  for s in scores ]))
                 or "None")
  text = """
%(title)s

                %(score_table)s

         """ % {'title': title, 'score_table': score_table}
  if asterisk:
    text += "
* Winning Game
"
  return text

def english_join(items, final="and"):
  """Join a list of items with an oxford comma and joining word.

  eg [1,2,3] => "1, 2, and 3".
  """
  # type: (Sequence[str], str) -> str
  if not items:
    return ""
  if len(items) == 1:
    return items[0]
  elif len(items) == 2:
    return "%s %s %s" % (items[0], final, items[1])
  else:
    items[-1] = "%s %s" % (final, items[-1])
    return ", ".join(str(item) for item in items)

def category_column_title(cat):
    if cat.proportional:
        return "%s (max %d)" % (cat.name, cat.max)
    else:
        return cat.name


"""
API
"""
import time

from app.service.browser import Browser

b = Browser()
b.instance()
b.go_to_kalea(item_label='agua')
# Debatible
time.sleep(2.5)
b.kalea_expand_results()
# b.fetch()

b.quit()


from copy import deepcopy
import random

board = [["-", "-", "-"],
         ["-", "-", "-"],
         ["-", "-", "-"]]

def print_board(board):
    for row in board:
        for column in row:
            print(column, end=" ")
        print()

def clear_board(board):
    new_line = ["-", "-", "-"]
    for i in range(3):
        board[i] = list(new_line)

def get_remaining_cells(board):
    remaining_cells = []
    for row in range(board.__len__()):
        for column in range(board[row].__len__()):
            if board[row][column] != "X" and board[row][column] != "O":
                remaining_cells.append((row, column))
    return remaining_cells

def has_won(board, player):
    # Horizontal check
    for row in board:
        if row.count(player) == 3:
            return True
    # Vertical check
    for i in range(3):
        if board[0][i] == player and board[1][i] == player and board[2][i] == player:
            return True
    # Diagonal Check
    if board[1][1] == player:
        if (board[0][0] == player and board[2][2] == player) or (board[2][0] == player and board[0][2] == player):
            return True
    return False

def game_ended(board):
    return has_won(board, "X") or has_won(board, "O") or not get_remaining_cells(board)

def evaluate(board):
    if has_won(board, "X"):
        return 1
    elif has_won(board, "O"):
        return -1
    return 0

def minimax(board, is_x):
    if game_ended(board):
        return [evaluate(board), ()]
    best_cell = ""
    if is_x:
        evaluation = -1
        symbol = "X"
    else:
        evaluation = 1
        symbol = "O"

    for row, column in get_remaining_cells(board):
        temp_board = deepcopy(board)
        temp_board[row][column] = symbol
        number = minimax(temp_board, not is_x)[0]
        ran = random.randint(0, 1)
        if is_x and number >= evaluation:
            if evaluation == number and ran == 1:
                best_cell = (row, column)
            else:
                evaluation = number
                best_cell = (row, column)
        elif not is_x and number <= evaluation:
            if evaluation == number and ran == 1:
                best_cell = (row, column)
            else:
                evaluation = number
                best_cell = (row, column)
    return [evaluation, best_cell]

num1 = 1
num2 = 1

print(max(num1, num2))


# -*- coding:utf-8 -*-
from http.client import HTTPConnection
from xml.etree.ElementTree import fromstring

#http://openapi.seoul.go.kr:8088/4f6a6547456b6368333355736a714f/xml/MosquitoStatus/1/10/2020-03-02
f = open("C:\\Users\\sdedu\\Desktop\\test/exam_mosquito.txt", "a", encoding = "utf-8")
con = HTTPConnection("openapi.seoul.go.kr:8088")

for y in range(2020,2022):
    for m in range(1,13):
        for d in range(1,31):
            when = "%d-%02d-%02d" % (y, m, d)
            con.request("GET", "/4f6a6547456b6368333355736a714f/xml/MosquitoStatus/1/5/" + when)
            resBody = con.getresponse().read()
            mqData = fromstring(resBody)
            mqData = mqData.find("row")
            for i in mqData:
                if mqData != None:
                    print(mqData.find("MOSQUITO_DATE"))
                    print(mqData.find("MOSQUITO_VALUE_HOUSE"))
                    print(mqData.find("MOSQUITO_VALUE_PARK"))
                # f.write("%s," % mqData.find("MOSQUITO_DATE"))
                # f.write("%s," % mqData.find("MOSQUITO_VALUE_HOUSE"))
                # f.write("%s," % mqData.find("MOSQUITO_VALUE_PARK"))

            # print(mqData)

con.close()
f.close()


import time
from framework.problems.singleobjective.ackley import Ackley
from evolutionary_memetic.memetic_cognitive import MemeticCognitiveAlgorithm, Species
import matplotlib.pyplot as plt
from jmetal.algorithm.singleobjective import GeneticAlgorithm
from jmetal.operator import PolynomialMutation, SBXCrossover, BinaryTournamentSelection
from jmetal.util.termination_criterion import StoppingByEvaluations
from evolutionary_memetic.memetic import MemeticAlgorithm, MemeticLocalSearch

if __name__ == '__main__':
    problem = Ackley(number_of_variables=150)
    max_evaluations = 500000
    mutation = PolynomialMutation(probability=1.0 / problem.number_of_variables, distribution_index=20)
    local_search = MemeticLocalSearch(problem, mutation, StoppingByEvaluations(500))

    memetic_algo = MemeticCognitiveAlgorithm(
        problem=problem,
        population_size=5000,
        offspring_population_size=1000,
        mutation=mutation,
        crossover=SBXCrossover(probability=1.0, distribution_index=20),
        selection=BinaryTournamentSelection(),
        species1=Species(
            mutation=mutation,
            crossover=SBXCrossover(probability=1.0, distribution_index=20),
            selection=BinaryTournamentSelection(),
            local_search=local_search,
            termination_criterion=StoppingByEvaluations(max_evaluations=1000)
        ),
        species2=Species(
            mutation=mutation,
            crossover=SBXCrossover(probability=1.0, distribution_index=20),
            selection=BinaryTournamentSelection(),
            local_search=local_search,
            termination_criterion=StoppingByEvaluations(max_evaluations=1000)
        ),
        local_search=local_search,
        termination_criterion=StoppingByEvaluations(max_evaluations=max_evaluations)
    )

    genetic_algo = GeneticAlgorithm(
        problem=problem,
        population_size=5000,
        offspring_population_size=1000,
        mutation=mutation,
        crossover=SBXCrossover(probability=1.0, distribution_index=20),
        selection=BinaryTournamentSelection(),
        termination_criterion=StoppingByEvaluations(max_evaluations=max_evaluations)
    )

    memetic_algo.run()
    genetic_algo.run()

    memetic_result = memetic_algo.get_result()
    genetic_result = genetic_algo.get_result()

    print('Algorithm: ' + memetic_algo.get_name())
    print('Problem: ' + problem.get_name())
    print('Solution: ' + str([var for var in memetic_result.variables]))
    print('Fitness:  ' + str(memetic_result.objectives[0]))
    print('Computing time: ' + str(memetic_algo.total_computing_time))

    print('Algorithm: ' + genetic_algo.get_name())
    print('Problem: ' + problem.get_name())
    print('Solution: ' + str([var for var in genetic_result.variables]))
    print('Fitness:  ' + str(genetic_result.objectives[0]))
    print('Computing time: ' + str(genetic_algo.total_computing_time))

    for o in range(problem.number_of_objectives):
        plt.plot(range(len(genetic_algo.history)), [s.objectives[o] for s in genetic_algo.history])
    for o in range(problem.number_of_objectives):
        plt.plot(range(len(memetic_algo.history)), [s.objectives[o] for s in memetic_algo.history])

    legend = ["GENETIC", "COGNITIVE-MEMETIC"]

    plt.legend(legend)
    plt.title(f"{problem.get_name()} with {problem.number_of_variables} variables")
    plt.savefig(f"{problem.get_name()}_{problem.number_of_variables}_comparison_history_{time.time()}.jpg")
    plt.show()


import torch
import torch.nn as nn
import torch.optim as optim
import torchvision
import torchvision.datasets as datasets
import torchvision.transforms as transforms
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
from tqdm import tqdm

class Discriminator(nn.Module):
    def __init__(self, num_channels, features_d, num_classes, image_size):
        super().__init__()
        self.image_size = image_size
        self.discriminator = nn.Sequential(
            nn.Conv2d(num_channels + 1, features_d, kernel_size = 4, stride = 2, padding = 1),
            nn.LeakyReLU(0.2),
            self._block(features_d, features_d * 2, 4, 2, 1),
            self._block(features_d * 2, features_d * 4, 4, 2, 1),
            self._block(features_d * 4, features_d * 8, 4, 2, 1),
            nn.Conv2d(features_d * 8, 1, kernel_size = 4, stride = 2, padding = 0)
        )
        self.embed = nn.Embedding(num_classes, image_size * image_size)
    def _block(self, in_channels, out_channels, kernel_size, stride, padding):
        return nn.Sequential(
            nn.Conv2d(in_channels, out_channels, kernel_size, stride, padding, bias = False),
            nn.InstanceNorm2d(out_channels, affine = True),
            nn.LeakyReLU(0.2)
        )
    def forward(self, x, labels):
        embedding = self.embed(labels).view(labels.shape[0], 1, self.image_size, self.image_size)
        x = torch.cat([x, embedding], dim = 1)
        return self.discriminator(x)

class Generator(nn.Module):
    def __init__(self, latent_dim, num_channels, features_g, num_classes, image_size, embed_size):
        super().__init__()
        self.image_size = image_size
        self.generator = nn.Sequential(
            self._block(latent_dim + embed_size, features_g * 16, 4, 1, 0),
            self._block(features_g * 16, features_g * 8, 4, 2, 1),
            self._block(features_g * 8, features_g * 4, 4, 2, 1),
            self._block(features_g * 4, features_g * 2, 4, 2, 1),
            nn.ConvTranspose2d(features_g * 2, num_channels, kernel_size = 4, stride = 2, padding = 1),
            nn.Tanh()
        )
        self.embed = nn.Embedding(num_classes, embed_size)
    def _block(self, in_channels, out_channels, kernel_size, stride, padding):
        return nn.Sequential(
            nn.ConvTranspose2d(in_channels, out_channels, kernel_size, stride, padding, bias = False),
            nn.BatchNorm2d(out_channels),
            nn.ReLU()
        )
    def forward(self, x, labels):
        embedding = self.embed(labels).unsqueeze(2).unsqueeze(3)
        x = torch.cat([x, embedding], dim = 1)
        return self.generator(x)

def initialize_weights(model):
    for m in model.modules():
        if isinstance(m, (nn.Conv2d, nn.ConvTranspose2d, nn.BatchNorm2d)):
            nn.init.normal_(m.weight.data, 0.0, 0.02)

def gradient_penalty(discriminator, labels, real, fake, device = "cpu"):

    BATCH_SIZE, Channels, Height, Width = real.shape
    epsilon = torch.rand((BATCH_SIZE, 1, 1, 1)).repeat(1, Channels, Height, Width).to(device)
    interpolated_images = real * epsilon + fake * (1 - epsilon) # 10 percent of the real image and 90 percent of the fake images
    mixed_scores = discriminator(interpolated_images, labels)
    gradient = torch.autograd.grad(inputs = interpolated_images, outputs = mixed_scores, grad_outputs = torch.ones_like(mixed_scores), create_graph = True, retain_graph = True)[0]
    gradient = gradient.view(gradient.shape[0], -1)
    gradient_norm = gradient.norm(2, dim = 1)
    gradient_penalty = torch.mean((gradient_norm - 1) ** 2)
    return gradient_penalty

device = "cuda" if torch.cuda.is_available() else "cpu"

LR = 1e-4
BATCH_SIZE = 64
IMAGE_SIZE = 64
NUM_CHANNELS = 1
NUM_CLASSES = 10
GEN_EMBED = 100
LATENT_DIM = 100
EPOCHS = 100
FEATURES_D = 16
FEATURES_G = 16
DISC_ITERATIONS = 5
LAMBDA_GRADIENT_PEN = 10
BETAS = (0.0, 0.9)

transforms = transforms.Compose([
    transforms.ToTensor(),
    transforms.Resize(IMAGE_SIZE),
transforms.Normalize([0.5 for _ in range(NUM_CHANNELS)], [0.5 for _ in range(NUM_CHANNELS)])
])

dataset = datasets.MNIST(root = "dataset/", transform = transforms, download = True)
data_loader = DataLoader(dataset, batch_size = BATCH_SIZE, shuffle = True)
generator = Generator(LATENT_DIM, NUM_CHANNELS, FEATURES_G, NUM_CLASSES, IMAGE_SIZE, GEN_EMBED).to(device)
discriminator = Discriminator(NUM_CHANNELS, FEATURES_D, NUM_CLASSES, IMAGE_SIZE).to(device)
initialize_weights(generator)
initialize_weights(discriminator)

gen_optimizer = optim.Adam(generator.parameters(), lr = LR, betas = BETAS)
disc_optimizer = optim.Adam(discriminator.parameters(), lr = LR, betas = BETAS)

fixed_noise = torch.randn(32, LATENT_DIM, 1, 1).to(device)
def set_writers(first, second, step = 0):
    writer_real = SummaryWriter(f"logs/{first}")
    writer_fake = SummaryWriter(f"logs/{second}")
    step = step
    return writer_real, writer_fake, step

writer_real, writer_fake, step = set_writers("real", "fake", step = 0)

generator.train()
discriminator.train()

for epoch in range(EPOCHS):
    for batch_idx, (real, labels) in enumerate(data_loader):
        real = real.to(device)
        labels = labels.to(device)
        for _ in range(DISC_ITERATIONS):
            noise = torch.randn(BATCH_SIZE, LATENT_DIM, 1, 1).to(device)
            fake = generator(noise, labels)
            critic_real = discriminator(real, labels).reshape(-1)
            critic_fake = discriminator(fake, labels).reshape(-1)
            gp = gradient_penalty(discriminator, labels, real, fake, device = device)
            # loss_disc = -(torch.mean(critic_real) - torch.mean(critic_fake))
            loss_disc = (-(torch.mean(critic_real) - torch.mean(critic_fake)) + LAMBDA_GRADIENT_PEN * gp)
            loss_disc.backward(retain_graph = True)
            disc_optimizer.step()

        output = discriminator(fake, labels).reshape(-1)
        loss_gen = -torch.mean(output)
        generator.zero_grad()
        loss_gen.backward()
        gen_optimizer.step()

        if batch_idx % 100 == 0:
            print(f"Epoch [{epoch}/{EPOCHS}] Batch {batch_idx}/{len(data_loader)} Loss Discriminator: {loss_disc:.4f}, Loss Generator: {loss_gen:.4f}")

            with torch.no_grad():
                fake = generator(noise, labels)
                img_grid_real = torchvision.utils.make_grid(real[:64], normalize = True)
                img_grid_fake = torchvision.utils.make_grid(fake[:64], normalize = True)

                writer_real.add_image("Real", img_grid_real, global_step = step)
                writer_fake.add_image("Fake", img_grid_fake, global_step = step)

            step += 1
            generator.train()
            discriminator.train()


"""
Randomization Algorithm - Randomizing an array.

For i = 1 To N
    ' Pick an item for position i.
    j = Random number between i and N

    ' Swap items i and j.
    temp = value[i]
    value[i] = value[j]
    value[j] = temp

Next i

"""
# python
from random import randint

alist = [1,2,3,4,5,6]
result = []
n = len(alist)
for i in range(1, n):
    # Pick an item for position i.
    j = randint(i, n-1)

    # Swap items i and j.
    alist[i], alist[j] = alist[j], alist[i]

print(alist)


import time

import torch
import torch.nn as nn
import torch.optim as optim
import torchvision.models as models
import torchvision.transforms as transforms

import model
import utility

if __name__ == '__main__':
    BATCH_SIZE = 1
    INITIAL_LEARNING_RATE = 0.0001
    EPOCHS = 500
    adobe_train_path = "/Users/posoo/GitRepos/adobeset/train"

    '''
    define our device as the first visible cuda device if we have CUDA available
    '''
    device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
    print(device)

    """
    using pre-trained VGG-16 to output conv_4_3 feature
    """
    vgg16 = models.vgg16(pretrained=True)
    vgg16_conv_4_3 = nn.Sequential(*list(vgg16.children())[0][:23])

    """
    prepare training set
    """
    transform_to_Tensor = transforms.Compose([transforms.ToTensor()])
    train_dataset = utility.AdobeDataset(adobe_train_path, transform=transform_to_Tensor)
    print("DATASET SIZE: {}".format(len(train_dataset)))
    train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=BATCH_SIZE, shuffle=True)

    """
    initialize net models and optimizer
    """
    l1_loss = nn.L1Loss()
    l2_loss = nn.MSELoss()

    flow_computation = model.UNet(6, 4)
    flow_computation.to(device)
    arbitrary_time_flow_interpolation = model.UNet(20, 5)
    arbitrary_time_flow_interpolation.to(device)

    backward_warping = model.BackwardWarping(352, 352, device)

    learning_rate = INITIAL_LEARNING_RATE
    optimizer = optim.Adam(list(flow_computation.parameters()) +
                           list(arbitrary_time_flow_interpolation.parameters()),
                           lr=learning_rate)

    """
    start training
    """
    for epoch in range(EPOCHS):
        for i, (I_0, I_t, I_1, t) in enumerate(train_loader, 0):
            I_0 = I_0.to(device)
            I_t = I_t.to(device)
            I_1 = I_1.to(device)

            """
            zero the parameter gradients
            """
            optimizer.zero_grad()

            """
            calculate loss
            """
            flow_outputs = flow_computation(torch.cat((I_0, I_1), dim=1))
            F_0_1 = flow_outputs[:, :2, :, :]
            F_1_0 = flow_outputs[:, 2:, :, :]

            slomo_cp = model.SuperSlomo(arbitrary_time_flow_interpolation, backward_warping, I_0, I_1, device, F_0_1,
                                        F_1_0, True)
            g_t_0_hat, g_t_1_hat, I_t_hat, g_0_hat, g_1_hat = slomo_cp.forward(2, t)
            loss_reconstruction = l1_loss(I_t_hat, I_t)
            loss_perceptual = l2_loss(vgg16_conv_4_3(I_t_hat), vgg16_conv_4_3(I_t_hat))
            loss_warping = l1_loss(I_1, g_0_hat) + l1_loss(I_0, g_1_hat) + \
                           l1_loss(I_t, g_t_0_hat) + l1_loss(I_t, g_t_1_hat)

            loss_smooth = torch.mean(torch.abs(F_1_0[:, :, :, :-1] - F_1_0[:, :, :, 1:])) + \
                          torch.mean(torch.abs(F_1_0[:, :, :-1, :] - F_1_0[:, :, 1:, :])) + \
                          torch.mean(torch.abs(F_0_1[:, :, :, :-1] - F_0_1[:, :, :, 1:])) + \
                          torch.mean(torch.abs(F_0_1[:, :, :-1, :] - F_0_1[:, :, 1:, :]))
            loss_total = 0.8 * loss_reconstruction + 0.005 * loss_perceptual + 0.4 * loss_warping + 1 * loss_smooth

            """
            BP update
            """
            loss_total.backward()
            optimizer.step()

            """
            print every 200 iterations
            """
            if i % 200 == 0:
                print("EPOCHS: {}/{} - {}, lr: {}, lp: {}, lw: {}, ls: {}, ltotal:{}".format(epoch, EPOCHS, i,
                                                                                loss_reconstruction,
                                                                                loss_perceptual,
                                                                                loss_warping,
                                                                                loss_smooth,
                                                                                loss_total))

            """
            Learning Rate decreased by a factor of 10 every 200 epochs
            """
            if epoch % 200 == 199:
                learning_rate = learning_rate / 10
                optimizer = optim.Adam(list(flow_computation.parameters()) +
                                       list(arbitrary_time_flow_interpolation.parameters()),
                                       lr=learning_rate)

            """
            Save checkpoint per 50 epochs
            """
            if epoch % 50 == 49:
                checkpoint_dict = {
                    "epoch": epoch,
                    "learning_rate": learning_rate,
                    "loss_total": loss_total,
                    "loss_reconstruction": loss_reconstruction,
                    "loss_perceptual": loss_perceptual,
                    "loss_warping": loss_warping,
                    "loss_smooth": loss_smooth,
                    "flow_computation_state": flow_computation.state_dict(),
                    "arbitrary_time_interpolation_state": arbitrary_time_flow_interpolation.state_dict()
                }
                torch.save(checkpoint_dict, "superslomo-{}.ckpt".format(int(time.time())))


from typing import List

class Solution:
    def validTree(self, n: int, edges: List[List[int]]) -> bool:
        if not n:
            return True

        adjcencyList = {i: [] for i in range(n)}

        # it is an undirected graph
        for n1, n2 in edges:
            adjcencyList[n1].append(n2)
            adjcencyList[n2].append(n1)

        visited = set()

        def dfs(i, prev):
            if i in visited:
                return False

            visited.add(i)

            for j in adjcencyList[i]:
                if j == prev:
                    continue
                if not dfs(j, i):
                    return False

            return True

        return dfs(0,-1) and n == len(visited)

if __name__ == "__main__":
    s = Solution()
    n = 5
    edges = [[0,1],[0,2],[0,3],[1,4]]
    s.validTree(n, edges)


from turtle import right
import matplotlib.pyplot as plt
import math
# how to

def sd(l):
    N = len(l)

    mu = mean(l)
    sum = 0
    for xi in l:
        sum += (xi-mu)**2
    var = sum/N
    return math.sqrt(var)

def mode(l):
    s = set(l)
    if len(s) == len(l):
        return False
    ss = list(s)
    print(ss)
    freq = [data.count(i) for i in ss]
    print(freq)
    maxIndx = freq.index(max(freq))
    return ss[maxIndx]

def median(l):
    l.sort()
    n = len(l)
    if n % 2 != 0:
        return l[int(n/2)]
    else:
        return (l[int((n/2)-1)]+l[int(n/2)])/2

def mean(l):
    sum = 0
    for i in l:
        sum = sum + i
    return sum/len(l)

data = [10, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 17, 20, 20]
y = [0 for i in data]
m = mean(data)
print(m)
sigma = sd(data)
print(sigma)
plt.xlim(left=0, right=0)
plt.scatter(data, y, marker='x', color='g')
plt.scatter([m], [0], marker='o', color='b', s=100)
plt.errorbar(m, 0.1, xerr=sigma, fmt='o')

k = 1
for i in data:
    plt.errorbar(i+(m-i)/2, k, xerr=(m-i)/2, fmt='o')
    k += .1
plt.xlim(0,20)
plt.boxplot(data,vert=False)
plt.boxplot(data,horizt=False)

y2018=[1,2,3,6,6,9,9,9,9,9,9,9,7,8,9,7,8,7,4,1,2,3,6,5,8,9,4,2,8]
y2019=[9,6,3,2,5,8,7,4,1,2,3,6,5,4,7,8,9,9,6,3,1,5,7,8,2,7,8,1,2]
plt.xlim(0,20)
plt.boxplot([y2018,y2019],vert=False)

# Histogram=(hist) =>draw diagrams for data by using arrays by repeat values in list or arrays

data=[10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,9,7,8,1,5,7,48,15,6]
# to give you range or limits for number on horizental line 0->20
plt.xlim(0,20)
# xticks => to make every plot above number to generate list from 0 to 20
plt.xticks([i for i in range(21)])
plt.yticks([i for i in range(31)])
plt.grid()
# align=> it take 3 values left or right or mid
# rwidth =relative width=> default value it equal to 1
# bins =>to generate list from0 to 21
# cumulative => it take boolean value it use to repeat data and organize it on diagram
plt.hist([y2018,y2019],color='skyblue',rwidth=0.5,align='left',bins=[i for i in range(22)],cumulative=True)


from typing import Optional, Any, Union, List, Tuple, Callable

from src.items.items import Item
import dearpygui.dearpygui as dpg

class Tooltip(Item):
    def __init__(self,
                 parent: Union[int, str],
                 *,
                 label: str = None,
                 user_data: Any = None,
                 use_internal_label: bool = True,
                 tag: Union[int, str] = 0,
                 show: bool = True,
                 **kwargs
                 ):
        self.identifier = dpg.add_tooltip(
            parent=parent,
            label=label,
            user_data=user_data,
            use_internal_label=use_internal_label,
            tag=tag,
            show=show,
            **kwargs
        )


# 1 cross-stitch
import torch
import torch.nn as nn
import torch.nn.functional as F
from model_part import *
class HNet(nn.Module):
    def __init__(self):
        super(HNet, self).__init__()
        # 1 input image channel, 2 output channels, 5x5 square convolution
        # kernel
        self.conv1 = double_conv(3,64)
        self.conv2 = double_conv(64,192)
        self.conv3 = double_conv(192,384)
        ##################
        self.conv4_a = double_conv1(384, 256)
        self.fc_a = outfully(4096,4,1024)
        self.conv4_b = double_conv1(384, 256)
        self.fc_b = outfully(4096,2,1024)

        self.cross_stich1 = cross_stich(8192, 8192);  #####
        ########################################
    def forward(self, x):
        # Max pooling over a (2, 2) window
        x = F.max_pool2d(self.conv1(x), 2);
        x = F.max_pool2d(self.conv2(x), 2);
        x = F.max_pool2d(self.conv3(x), 2);

        x1 = self.conv4_a(x)
        x2 = self.conv4_b(x)
        x1, x2 = self.cross_stich1(x1, x2);
        x1 = self.fc_a(x1)
        x2 = self.fc_b(x2)

        output1 = F.log_softmax(x1, dim=1)
        output2 = F.log_softmax(x2, dim=1)

        return output1, output2


import numpy as np
import random
import matplotlib.pyplot as plt
import math

simlen = 10000
x = [2,3,4,5,6,7,8,9,10]
count = [0,0,0,0,0,0,0,0,0]
for j in range(2,11):
  for i in range(simlen):
    random_matrix_array = np.random.randint(0,2,size=(j,j))
    det = np.linalg.det(random_matrix_array)
    if det > 0:
      count[j-2] = count[j-2] + 1

theoretical = [0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5]
theoreticalValue = 0.5;
for k in range(2,11):
  theoreticalValue = theoreticalValue * (1 - math.pow(2,-k));
  theoretical[k-2] = theoretical[k-2] * theoreticalValue

simulated = [0,0,0,0,0,0,0,0,0]
for i in range(0,9):
  simulated[i] = count[i] / simlen

#x = np.array([1, 1])
#y = np.array([P_X1_Y0, analysis_ans])
y1 = np.array(simulated)
y2 = np.array(theoretical)

print(theoretical)
print(simulated)
#plt.stem(unique,psim, markerfmt='o', use_line_collection=True, label='Simulation')
plt.ylim(0, 1)
#plt.xlim(2,10)
plt.stem(x,y1, markerfmt='o', use_line_collection=True, label = 'Simulation')
plt.stem(x,y2, markerfmt='o', use_line_collection=True, label = 'Theoretical')
plt.ylabel('$Pr($det $M > 0)$')
plt.xlabel('$n$')
plt.legend()
plt.grid()


#!/usr/bin/env python3
"""program that performs semantic search on a corpus of documents"""
import tensorflow_hub as hub
import os
import numpy as np

def semantic_search(corpus_path, sentence):
    """function that performs semantic search on a corpus of documents"""
    articles = [sentence]
    for filename in os.listdir(corpus_path):
        if not filename.endswith('.md'):
            continue
        with open(corpus_path + '/' + filename, 'r', encoding='utf-8') as file:
            articles.append(file.read())
    embed = hub.load("https://tfhub.dev/google/universal-"
                     + "sentence-encoder-large/5")
    embeddings = embed(articles)
    corr = np.inner(embeddings, embeddings)
    closest = np.argmax(corr[0, 1:])
    print(closest)
    return (articles[closest + 1])


casa = float(input("Qual o valor da casa? R$"))
salário = float(input("Qual o salário do comprador? R$"))
anos = int(input("Em quantos anos irá pagar? "))
prestação = casa / (anos * 12)
mínimo = (salário / 100) * 30
print("para pagar uma casa de R${:.2f} em {} anos a prestação será de R${:.2f}".format(casa, anos, prestação))
if prestação <= mínimo:
    print("\033[32mEmpréstimo pode ser CONCEDIDO!\033[m")
else:
    print("\033[31mEmprestimo não pode ser CONCEDIDO!\033[m")


import os

from vgazer.command     import RunCommand
from vgazer.exceptions  import CommandError
from vgazer.exceptions  import InstallError
from vgazer.platform    import GetInstallPrefix
from vgazer.platform    import GetTriplet
from vgazer.store.temp  import StoreTemp
from vgazer.working_dir import WorkingDir

def Install(auth, software, platform, platformData, mirrors, verbose):
    installPrefix = GetInstallPrefix(platformData)
    targetTriplet = GetTriplet(platformData["target"])

    storeTemp = StoreTemp()
    storeTemp.ResolveEmptySubdirectory(software)
    tempPath = storeTemp.GetSubdirectoryPath(software)

    try:
        with WorkingDir(tempPath):
            RunCommand(
             ["git", "clone", "https://github.com/AltSysrq/libbsd-minimal.git"],
             verbose)
        clonedDir = os.path.join(tempPath, "libbsd-minimal")
        with WorkingDir(clonedDir):
            RunCommand(["libtoolize"], verbose)
            RunCommand(["aclocal"], verbose)
            RunCommand(["autoheader"], verbose)
            RunCommand(["automake", "--add-missing"], verbose)
            RunCommand(["autoreconf"], verbose)
            RunCommand(
             ["./configure", "--host=" + targetTriplet,
              "--prefix=" + installPrefix, "--disable-shared",
              "CFLAGS=-D__THROW= -include features.h"
              ],
             verbose)
            RunCommand(
             ["sed", "-i",
              "s"
              "|#define\t__P(protos)\tprotos"
              "|#ifndef __P\\n#define __P(protos) protos\\n#endif"
              "|g",
              "include/bsd/sys/freebsd-cdefs.h"],
             verbose)
            RunCommand(
             ["sed", "-i",
              "s"
              "/#define\t__CONCAT(x,y)\t__CONCAT1(x,y)"
              "/#ifndef __CONCAT\\n#define __CONCAT(x,y) __CONCAT1(x,y)\\n#endif"
              "/g",
              "include/bsd/sys/freebsd-cdefs.h"],
             verbose)
            RunCommand(
             ["sed", "-i",
              "s"
              "/#define\t__always_inline\t__attribute__((__always_inline__))"
              "/#ifndef __always_inline\\n#define __always_inline __attribute__((__always_inline__))\\n#endif"
              "/g",
              "include/bsd/sys/freebsd-cdefs.h"],
             verbose)
            RunCommand(
             ["sed", "-i",
              "s"
              "/#define __nonnull(x)\t__attribute__((__nonnull__(x)))"
              "/#ifndef __nonnull\\n#define __nonnull(x) __attribute__((__nonnull__ x))\\n#endif"
              "/g",
              "include/bsd/sys/freebsd-cdefs.h"],
             verbose)
            RunCommand(
             [
              "make", "-j{cores_count}".format(cores_count=os.cpu_count()),
              "V=1"
             ],
             verbose
            )
            RunCommand(["make", "install"], verbose)
    except CommandError:
        print("VGAZER: Unable to install", software)
        raise InstallError(software + " not installed")

    print("VGAZER:", software, "installed")


from typing import List, Dict, Set
from datetime import date, datetime, timedelta
from uuid import uuid4
from math import ceil, floor

from flask import abort

from repositories import post_repository, attachment_repository, employee_repository, subunit_repository, Post, db
from models.post_model import PostStatus, PostType
from models.employee_model import EmployeeType
from . import attachment_service, any_non_nones, default_page_size
from .employee_service import prepare_employee

def prepare_post(post: Post, refresh: bool = True) -> dict:
    if not post:
        return {}
    if refresh:
        db.session.refresh(post)
    result = post.get_dict()
    result['post_type'] = PostType(post.type).name
    result['status'] = PostStatus(post.status).name
    result['size'] = calculate_post_size(post)
    result['attachments'] = [attachment_service.prepare_attachment(attachment) for attachment in post.attachments]
    result['author'] = prepare_employee(post.creator)
    result['approved_by'] = prepare_employee(post.approver) if post.approver else None
    return result

def prepare_posts_list(posts: List[Post]) -> List[dict]:
    return [prepare_post(post, refresh=False) for post in posts]

def calculate_post_size(post: Post) -> int:
    size = len(post.body.encode())
    size += len(post.title.encode())
    size += sum(attachment_repository.get_attachment_size(attachment.id) for attachment in post.attachments)
    return size

def archive_pages_count():
    return ceil(post_repository.count_archived_posts() / default_page_size)

def feed_pages_count(posts_type: PostType, subunit_id: str = None):
    return ceil(post_repository.get_posts_count(posts_type, {PostStatus.posted}, subunit_id) / default_page_size)

def moderation_pages_count(posts_type: PostType = None, posts_statuses: Set[PostStatus] = None, subunit_id: str = None):
    return ceil(post_repository.get_posts_count(posts_type, posts_statuses, subunit_id) / default_page_size)

def get_post(post_id: str) -> dict:
    post = post_repository.get_post_by_id(post_id)
    if not post:
        abort(404, "Post not found")
    return prepare_post(post, refresh=False)

def create_post(creator_id: str, title: str, body: str, post_type: str, attachments: List[str] = None, **kwargs) -> dict:
    if attachments and not attachment_repository.ensure_attachments_exist(attachments):
        abort(404, "Attachment not found")
    post = Post()
    post.author = creator_id
    post.type = PostType[post_type].value
    post.title = title
    post.body = body
    post.id = str(uuid4())
    creator = employee_repository.get_employee_by_id(creator_id)
    if not creator or creator.user_type == EmployeeType.user.value:
        post.status = PostStatus.under_consideration.value
    else:
        post.status = PostStatus.posted.value
        post.published_on = datetime.utcnow() + timedelta(seconds=1)
        post.approved_by = creator_id
    post_repository.add_or_edit_post(post)
    if attachments:
        attachment_repository.add_attachments_to_post(post.id, attachments)
    return get_post(post.id)

def edit_post(
        editor_id: str, post_id: str, title: str = None, body: str = None,
        post_type: str = None, attachments: List[str] = None, **kwargs
) -> dict:
    if not any_non_nones((title, body, post_type, attachments)):
        abort(422, "All fields are null")
    post = post_repository.get_post_by_id(post_id)
    if not post:
        abort(404, "Post not found")
    if post.author != editor_id:
        editor = employee_repository.get_employee_by_id(editor_id)
        if not editor or editor.user_type != EmployeeType.admin.value:
            abort(403, "Non-admins can not edit posts of other users")
    if post_type:
        try:
            post_type = PostType[post_type].value
        except KeyError:
            abort(400, "Incorrect post type")
    for existing, new in (('title', title), ('body', body), ('type', post_type)):
        setattr(post, existing, new or getattr(post, existing))
    post_repository.add_or_edit_post(post)
    if attachments is not None:
        current_attachments = [attachment.id for attachment in post.attachments]
        if current_attachments:
            attachment_repository.add_attachments_to_post(None, current_attachments)
        attachment_repository.add_attachments_to_post(post.id, attachments)
    return get_post(post.id)

def set_post_status(setter_id: str, post_id: str, status: PostStatus) -> dict:
    post = post_repository.get_post_by_id(post_id)
    if not post:
        abort(404, "Post not found")
    editor = employee_repository.get_employee_by_id(setter_id)
    if not editor or editor.user_type == EmployeeType.user.value:
        abort(403, "Non-(admins/moderators) can not change post statuses")
    if post.status != status.value:
        if status == PostStatus.archived:
            post.archived_on = datetime.utcnow()
        if status == PostStatus.posted:
            post.published_on = datetime.utcnow()
            post.approved_by = setter_id
        if post.status == PostStatus.archived.value:
            post.archived_on = datetime.utcnow() + timedelta(hours=4380)
        post.status = status.value
    return prepare_post(post_repository.add_or_edit_post(post))

def delete_post(deleter_id: str, post_id: str) -> None:
    post = post_repository.get_post_by_id(post_id)
    if not post:
        abort(404, "Post not found")
    if post.author != deleter_id:
        editor = employee_repository.get_employee_by_id(deleter_id)
        if not editor or editor.user_type == EmployeeType.user.value:
            abort(403, "Non-(admins/moderators) can not delete posts of other users")
    return post_repository.delete_post(post)

def get_all_employee_posts(employee_id: str) -> List[dict]:
    if not employee_repository.get_employee_by_id(employee_id):
        abort(404, "Employee not found")
    return prepare_posts_list(post_repository.get_posts_of_employee(employee_id))

def get_biggest_post(day: date, include_archived: bool) -> dict:
    posts_of_day = prepare_posts_list(post_repository.get_posts_by_date(day, include_archived))
    if not posts_of_day:
        abort(404, "Post not found")
    return max(posts_of_day, key=lambda post: post["size"])

def get_statistics(
        start_year: int, start_month: int, end_year: int, end_month: int, subunit_ids: List[str] = None
) -> Dict[str, Dict[str, Dict[str, int]]]:
    def calculate_iso_month(day: date) -> str:
        return str.join('-', day.isoformat().split('-')[:-1])

    end_month += 1
    if end_month > 12:
        end_year += 1
        end_month = 1
    try:
        start_date = date(start_year, start_month, 1)
        end_date = date(end_year, end_month, 1)
    except ValueError:
        return abort(422, 'Invalid date given')
    months_count = (end_month - start_month) + (end_year - start_year) * 12
    if months_count <= 0:
        abort(422, "End is earlier than start")
    months_full = []
    for month in range(months_count):
        current_month = ((start_month - 1 + month) % 12) + 1
        current_year = (start_year + floor((start_month - 1 + month) / 12))
        months_full.append(date(current_year, current_month, 1))
    months = [calculate_iso_month(month) for month in months_full]
    all_posts = post_repository.get_posts_by_period(start_date, end_date, subunit_ids)
    all_subunits = subunit_repository.get_subunits(subunit_ids)
    posts_by_months = {
        subunit.name: {
            month: 0 for month in months
        } for subunit in all_subunits
    }
    for post in all_posts:
        month = calculate_iso_month(post.published_on.date())
        posts_by_months[post.creator.subunit_ref.name][month] += 1
    return posts_by_months

def get_feed(post_type: PostType, page: int, subunit_id: str = None) -> Dict[str, int or dict]:
    if (not subunit_id) and (post_type in (PostType.subunit_announcement, PostType.subunit_news)):
        abort(422, "You must specify subunit for this post type")
    pages_count = feed_pages_count(post_type, subunit_id)
    if page <= pages_count:
        posts = prepare_posts_list(
            post_repository.get_posts(page, default_page_size, post_type, {PostStatus.posted}, subunit_id)
        )
    else:
        posts = []
    return {
        "posts": posts,
        "pages_count": pages_count
    }

def get_archived_posts(page: int) -> Dict[str, str or dict]:
    pages_count = archive_pages_count()
    if page <= pages_count:
        posts = prepare_posts_list(post_repository.get_archived_posts(page, default_page_size))
    else:
        posts = []
    return {
        "posts": posts,
        "pages_count": pages_count
    }

def get_all_posts(employee_id: str, page: int, posts_statuses: Set[PostStatus], reverse: bool = True) -> Dict[str, int or dict]:
    moderator = employee_repository.get_employee_by_id(employee_id)
    if not moderator or moderator.user_type == EmployeeType.user.value:
        abort(403, "You're not allowed to see this data")
    pages_count = moderation_pages_count(posts_statuses=posts_statuses)
    if page <= pages_count:
        posts = prepare_posts_list(post_repository.get_posts(
            page, default_page_size, post_statuses=posts_statuses, oldest_first=reverse
        ))
    else:
        posts = []
    return {
        "posts": posts,
        "pages_count": pages_count
    }


# from requests import request
from flask import Flask, render_template, request, send_file
from apriori import main as mainApriori
from metricas import main as mainMetricas
from cluster import main as mainCluster
# from pronostico import main as mainPronostico
from arboles import main as mainArboles
from bosques import main as mainBosques
from glob import glob
from io import BytesIO
from zipfile import ZipFile
import os

app = Flask(__name__)

@app.route('/')
def index():
  return render_template('index.html')

@app.route('/presentacion')
def presentacion():
  return render_template('algoritmos/presentacion.html')

# @app.route('/apriori', methods=['GET','POST'])
# def apriori():
#   if request.method == "GET":
#     return render_template('algoritmos/apriori_settings.html')
#   if request.method == "POST":
#     f = request.files['dataset']
#     f.save(secure_filename(f.filename))
#     soporte = float(request.form['soporte'])
#     confi = float(request.form['confi'])
#     lifto = float(request.form['lifto'])
#     Resultados = mainApriori(soporte,confi,lifto)
#     return render_template('algoritmos/apriori.html', resultados=Resultados)

@app.route('/apriori', methods=['GET','POST'])
def apriori():
  if request.method == "GET":
    return render_template('algoritmos/apriori_settings.html')
  if request.method == "POST":
    # f = request.files['dataset']
    # f.save(secure_filename(f.filename))
    soporte = float(request.form['soporte'])
    confi = float(request.form['confi'])
    lifto = float(request.form['lifto'])
    Resultados = mainApriori(soporte,confi,lifto)
    return render_template('algoritmos/apriori.html', resultados=Resultados)

@app.route('/aprioriDownload')
def downloadApriori():
  target = './static/images/apriori/'

  stream = BytesIO()
  with ZipFile(stream, 'w') as zf:
      for file in glob(os.path.join(target, '*.pdf')):
          zf.write(file, os.path.basename(file))
  stream.seek(0)

  return send_file(
      stream,
      as_attachment=True,
      download_name='apriori.zip'
  )

@app.route('/metricas', methods=['GET','POST'])
def metricas():
  if request.method == "GET":
    return render_template('algoritmos/metricas.html')
  if request.method == "POST":
    obj1 = request.form['objeto1']
    if obj1 == '':
      obj1 = 0
    else:
      obj1 = int(obj1)
    obj2 = request.form['objeto2']
    if obj2 == '':
      obj2 = 1
    else:
      obj2 = int(obj2)
    dM = mainMetricas(obj1,obj2)
    distanceM = [{'distanceM': dM}]
    return render_template('algoritmos/metricasShow.html', distanceM=distanceM)

@app.route('/metricasDownload')
def downloadMetricas():
  target = './static/images/metricas/'

  stream = BytesIO()
  with ZipFile(stream, 'w') as zf:
      for file in glob(os.path.join(target, '*.pdf')):
          zf.write(file, os.path.basename(file))
  stream.seek(0)

  return send_file(
      stream,
      as_attachment=True,
      download_name='metricas.zip'
  )

@app.route('/cluster')
def cluster():
  top10, CentroidesH, CentroidesP, elbow = mainCluster()
  return render_template('algoritmos/cluster.html', top10=top10, CentroidesH=CentroidesH, CentroidesP=CentroidesP, elbow=elbow)

@app.route('/clusterDownload')
def downloadCluster():
  target = './static/images/cluster/'

  stream = BytesIO()
  with ZipFile(stream, 'w') as zf:
      for file in glob(os.path.join(target, '*.pdf')):
          zf.write(file, os.path.basename(file))
  stream.seek(0)

  return send_file(
      stream,
      as_attachment=True,
      download_name='cluster.zip'
  )

@app.route('/arboles')
def arboles():
  acc_score, Matriz_Clasificacion1, criterio, reporte_clasif, ImportanciaMod1 = mainArboles(False)
  return render_template('algoritmos/arboles.html', acc_score=acc_score, Matriz_Clasificacion1=Matriz_Clasificacion1, criterio=criterio, reporte_clasif=reporte_clasif, ImportanciaMod1=ImportanciaMod1)

@app.route('/arbolesDownload')
def downloadArboles():
  target = './static/images/arboles/'

  stream = BytesIO()
  with ZipFile(stream, 'w') as zf:
      for file in glob(os.path.join(target, '*.pdf')):
          zf.write(file, os.path.basename(file))
  stream.seek(0)

  return send_file(
      stream,
      as_attachment=True,
      download_name='arboles.zip'
  )

@app.route('/bosques')
def bosques():
  acc_score, Matriz_Clasificacion2, criterio, reporte_clasif, ImportanciaMod = mainBosques()
  return render_template('algoritmos/bosques.html', acc_score=acc_score, Matriz_Clasificacion2=Matriz_Clasificacion2, criterio=criterio, reporte_clasif=reporte_clasif, ImportanciaMod2=ImportanciaMod)

@app.route('/bosquesDownload')
def downloadBosques():
  target = './static/images/bosques/'

  stream = BytesIO()
  with ZipFile(stream, 'w') as zf:
      for file in glob(os.path.join(target, '*.pdf')):
          zf.write(file, os.path.basename(file))
  stream.seek(0)

  return send_file(
      stream,
      as_attachment=True,
      download_name='bosques.zip'
  )


from pynput.keyboard import Key, Listener, Controller
from PIL import Image
import pyautogui, os, time

print('Hello, I am Python bot and I will try to play Tetris game on NES emulator :)')
print('Press q to start, set focus on the emulator window, and start the game :)')

scriptPath = os.path.dirname(__file__)

#keys:
keyRotate='z'
keyLeft='n'
keyRight='m'
keyPutDown='j'

keyboard = Controller()

widthOfWell = 80
heightOfWell = 160

screenshotImg = 'screenshot.png'

def determineCoordinatesOfBricksWell():
	coordinatesOfBottomFrame = pyautogui.locateOnScreen(scriptPath + '/' + 'bottom-of-well.png', region=(0, 0, 250, 270))
	if coordinatesOfBottomFrame != None:
		print('Bottom of well detected')
		wellLeft = coordinatesOfBottomFrame[0] + 3
		wellTop = coordinatesOfBottomFrame[1] - 3 - heightOfWell
		return (wellLeft, wellTop, widthOfWell, heightOfWell)
	return None

def takeScreenshot(screenshotRegion):
	image = pyautogui.screenshot(screenshotImg, region=screenshotRegion)

def getPixel(x, y):
	imageObject = Image.open(scriptPath + '/' + screenshotImg).convert('RGB')
	r, g, b = imageObject.getpixel((x, y))
	if r != 0 or g != 0 or b != 0:
		return 1
	else:
		return 0

def scanScreenshot():
	posX = 4
	posY = 4
	stepX = 8
	stepY = 8
	wellMatrix = [[0]*10]*20
	matrixX = 0
	matrixY = 0
	while posY < heightOfWell and matrixY <= 19 :
		while posX < widthOfWell:
			result = getPixel(posX, posY)
			posX+=stepX
			wellMatrix[matrixY][matrixX]=result
			matrixX+=1
		posY+=stepY
		posX=4
		matrixX=0
		matrixY+=1
	return wellMatrix

def playGame():
	print('initialized....')
	try:
		coordinatesOfBricksWell = determineCoordinatesOfBricksWell()
		takeScreenshot(coordinatesOfBricksWell)
		wellMatrix = scanScreenshot()
		print(wellMatrix)
		while 1==1 :
			return None
	except Exception as e:
		print(e)

def on_press(key):
    if str(key)=="'q'":
        playGame()
    if key == Key.esc:
        return False

with Listener(on_press=on_press) as listener:
    listener.join()


# https://leetcode.com/problems/sort-an-array/
from typing import List
import random
from random import randint

def swap(nums, a, b):
    nums[a], nums[b] = nums[b], nums[a]

class Solution:
    def bubble_down(self, nums, n, p):
        l = p
        c = p * 2

        if c < n and nums[c] > nums[l]:
            l = c

        if c + 1 < n and nums[c + 1] > nums[l]:
            l = c + 1

        if l != p:
            nums[l], nums[p] = nums[p], nums[l]
            self.bubble_down(nums, n, l)

    def bubble_sort(self, nums):
        n = len(nums)
        sorted_nums = nums[:]

        for i in reversed(range(n // 2 + 1)):
            self.bubble_down(sorted_nums, n, i)

        while n > 1:
            sorted_nums[0], sorted_nums[n - 1] = \
                sorted_nums[n - 1], sorted_nums[0]
            n -= 1
            self.bubble_down(sorted_nums, n, 0)

        return sorted_nums

    def partition(self, nums, l, r, pivot_idx):
        pivot_val = nums[pivot_idx]
        swap(nums, r, pivot_idx)
        store_idx = l

        for i in range(l, r):
            if nums[i] < pivot_val:
                swap(nums, i, store_idx)
                store_idx += 1

        swap(nums, store_idx, r)
        return store_idx

    def hoare_partition(self, nums, l, r):
        pivot_val = nums[l]
        i = l - 1
        j = r + 1
        while True:
            while True:
                i += 1
                if nums[i] >= pivot_val:
                    break

            while True:
                j -= 1
                if nums[j] <= pivot_val:
                    break

            if i >= j:
                return j

            swap(nums, i, j)

    def quick_sort_main(self, nums, l, r):
        if l >= r:
            return nums
        pivot_idx = self.hoare_partition(nums, l, r)
        self.quick_sort_main(nums, l, pivot_idx)
        self.quick_sort_main(nums, pivot_idx + 1, r)
        return nums

    def quick_sort(self, nums):
        sorted_nums = nums[:]
        return self.quick_sort_main(sorted_nums, 0, len(nums) - 1)

    def merge_sort_main(self, nums, l, r):
        if l >= r:
            return nums
        m = (l + r) // 2

        self.merge_sort_main(nums, l, m)
        self.merge_sort_main(nums, m + 1, r)

        i, j, k = l, m + 1, 0
        tmp = nums[l:r+1]

        while i <= m and j <= r:
            if nums[i] < nums[j]:
                tmp[k] = nums[i]
                i += 1
            else:
                tmp[k] = nums[j]
                j += 1
            k += 1

        while i <= m:
            tmp[k] = nums[i]
            k += 1
            i += 1

        while j <= r:
            tmp[k] = nums[j]
            k += 1
            j += 1
        nums[l:r+1] = tmp
        return nums

    def merge_sort(self, nums):
        sorted_nums = nums[:]
        return self.merge_sort_main(sorted_nums, 0, len(nums) - 1)

    def sortArray(self, nums: List[int]) -> List[int]:
        return self.quick_sort(nums)

solution = Solution()

def check(input, expected):
    output = solution.sortArray(input)
    assert output == expected

random.seed(5)

a = [randint(1, 100) for _ in range(randint(5, 18))]
b = [randint(1, 100) for _ in range(randint(5, 18))]
c = [randint(1, 100) for _ in range(randint(5, 18))]
d = [randint(1, 100) for _ in range(randint(5, 18))]

check(a, sorted(a))
check(b, sorted(b))
check(c, sorted(c))
check(d, sorted(d))

check([0], [0])
check([5, 2, 6], [2, 5, 6])
check([5, 2, 3, 1], [1, 2, 3, 5])
check([5, 1, 1, 2, 0, 0], [0, 0, 1, 1, 2, 5])


# # -*- coding = utf-8 -*-
# # @Time : 2020/12/15 21:22
# # @Author :董礼
# # @File :app.py.py
# # @Software :PyCharm
#
# # 引入包
from flask import Flask,render_template,request,jsonify
# render_template作用是模板引擎渲染
import sqlite3
# 引入数据库
app = Flask(__name__)
#
@app.route("/")    #后盾接口
def index():
# 模块6
    datalist = []
    conn = sqlite3.connect("新冠疫情.db")
    c = conn.cursor()
    print("数据库连接成功")
    sql = '''
        select city from city
        '''
    cursor = c.execute(sql)
    for data in cursor:
        if eval(data[0]):
            datalist.append(eval(data[0]))
    conn.commit()
    print("数据库关闭")
    conn.close()
    # 查找世界确诊人数
    conn = sqlite3.connect("新冠疫情.db")
    c = conn.cursor()
    sql = '''
            select continentName,confirmed,dead,crued from continentForDate
        '''
    cursor = c.execute(sql)
    continentData = []
    for item in cursor:
        if item[0] != '热门':
            continentData.append(item)
        else:
            otherData = item
    conn.commit()
    print("数据库关闭")
    conn.close()
    # 中国疫情人数
    conn = sqlite3.connect("新冠疫情.db")
    c = conn.cursor()
    sql = '''
                select confirmed from chinaTrend
            '''
    cursor = c.execute(sql)
    for item in cursor:
        ChinaNum = item[0]
    conn.commit()
    print("数据库关闭")
    conn.close()
    continentNameData = []
    continentConfiredData = []
    for item in continentData:
        if item[0] != '其他':
            continentNameData.append(item[0])
            continentConfiredData.append(item[1])
    conn = sqlite3.connect("新冠疫情.db")
    c = conn.cursor()
    print("数据库连接成功")
    sql = '''
        select continentName,confirmed,dead,crued from continentForDate
    '''
    cursor = c.execute(sql)
    continentList = []
    for item in cursor:
        temp = {}
        temp['value'] = item[1]
        temp['name'] = item[0]
        continentList.append(temp)
    conn.commit()
    conn.close()
    # 在这里设置地图的数据
    conn = sqlite3.connect("新冠疫情.db")
    c = conn.cursor()
    sql = '''
        select provinceName,confirmed from province
    '''
    cursor = c.execute(sql)
    provinceData = []
    for item in cursor:
        temp = {}
        temp['name']=item[0]
        temp['value']= item[1]
        provinceData.append(temp)
    return render_template("index.html",number=otherData,datalist = datalist,
                           ChinaNum=ChinaNum,
                           continentNameData=continentNameData,
                           continentConfiredData=continentConfiredData,
                           continentList=continentList,
                           provinceData=provinceData)
# 查找城市
@app.route("/city",methods = ["get",'post'])
def city():
    Province = request.args['ProVince']
    conn = sqlite3.connect("新冠疫情.db")
    c = conn.cursor()
    print('数据库连接成功')
    sql = '''
        select provinceName,city from city
    '''
    cursor = c.execute(sql)
    cityName = []
    cityConfirmed = []
    for data in cursor:
        length = len(Province)
        if Province[length-1:] == "省":
            if data[0] == Province[0:length-1]:
                provinceName1= data[0]
                cityAllInfo = []
                citys = eval(data[1])
                for city in citys:
                    cityInfo = {}
                    cityInfo['city'] = city[0]
                    cityInfo['确诊'] = city[1]
                    cityInfo['死亡'] = city[2]
                    cityInfo['治愈'] = city[3]
                    cityAllInfo.append(cityInfo)
        elif data[0] == Province:
            provinceName1 = data[0]
            cityAllInfo = []
            citys = eval(data[1])
            for city in citys:
                cityInfo = {}
                cityInfo['city']= city[0]
                cityInfo['确诊'] = city[1]
                cityInfo['死亡'] = city[2]
                cityInfo['治愈'] = city[3]
                cityAllInfo.append(cityInfo)
    conn.commit()
    conn.close()
    return render_template("city.html",provinceName1= provinceName1 ,cityAllInfo = cityAllInfo)

@app.route("/country",methods = ["post","get"])
def country():
    conn = sqlite3.connect("新冠疫情.db")
    c = conn.cursor()
    print("数据库已打开")
    sql = '''
           select date,confirmed,dead from foreignTrend
       '''
    cursor = c.execute(sql)
    n = 2
    deadForForeign = []
    confirmedForForeign = []
    for row in cursor:
        if eval(row[0]) == n + 0.15:
            deadForForeign.append(row[2])
            confirmedForForeign.append(row[1])
            n += 1
    # print(deadForForeign)
    # print(confirmedForForeign)
    return render_template('country.html',deadForForeign=deadForForeign,confirmedForForeign=confirmedForForeign)

@app.route("/foreign",methods= ['post','get'])
def foreign():
    requestCountry = request.args['foreign']
    dataItem = ['日本','美国','韩国','意大利']
    for item in dataItem:
        if requestCountry == item:
            conn = sqlite3.connect("新冠疫情.db")
            c = conn.cursor()
            print("数据库已打开")
            sql = '''
                      select country,city from ImportantCountryForOther
                  '''
            cursor = c.execute(sql)
            for item in cursor:
                if requestCountry == item[0]:
                    cityName = []
                    cityConfirmed = []
                    cityDead = []
                    for it in eval(item[1]):
                        cityName.append(it[0])
                        cityConfirmed.append(it[1])
                        cityDead.append(it[2])
            conn.commit()
            conn.close()
            return render_template("foreign.html",requestCountry=requestCountry,cityName=cityName,cityConfirmed=cityConfirmed,cityDead=cityDead)
    conn = sqlite3.connect("新冠疫情.db")
    c = conn.cursor()
    print("数据库已打开")
    sql = '''
               select countryName,confirmed,dead,crued from otherCountry
           '''
    cursor = c.execute(sql)
    for item in cursor:
        number = []
        if requestCountry == item[0]:
            number.append(item[1])
            number.append(item[2])
            number.append(item[3])
            return render_template("test.html",number = number,requestCountry = requestCountry)

if __name__ == "__main__":
    app.run(debug = True)


from  Dev.DAL.objects.DB import *
class StockItemDAL(db.Entity):
    category = Required(str)
    desc = Optional(str)
    # purchasePolicy = []
    # discountPolicy = []
    name = Required(str)
    count = Required(int)
    price = Required(float)
    shopname = Required(str)
    stock = Required("StockDAL")
    bidItem = Set("BidDAL")


from django.shortcuts import render, get_object_or_404
from .models import CTF

def ctfs_home(request):
    queryset = CTF.objects.all().order_by('-timestamp')
    context = {
        "ctfs": queryset,
    }
    return render(request, "ctfs-main.html", context)

def ctf_detail(request, id):
    ctf = get_object_or_404(CTF, id=id)
    queryset = ctf.writeup_set.all()

    context = {
        "writeups": queryset,
        "ctf": ctf
    }
    return render(request, "ctf.html", context)


import json
import generales as gral

def obtenerDatos():
    try:
        file = open("archivo-estudiantes.json","r")
        datos = json.load(file) # retorna una lista
        file.close()
    except FileNotFoundError:
        datos = []
    return datos

def alta(listado):
    nombre = input("Nombre: ")
    edad = gral.inputEntero(leyenda="Edad: ")
    curso = input("Curso: ")

    # Generar mi estructura de estudiante
    estudiante = {
        "nombre":nombre, # "Fernando"
        "edad":edad, # 44
        "legajo":gral.proximoLegajo(listado), # 23001
        "curso":curso.lower(), # "react"
        "notas": [] # [6,9,9,9,10,5]
    }

    listado.append(estudiante)
    file = open("archivo-estudiantes.json","w")
    json.dump(listado,file, indent=2)
    file.close()

def modificar(listado):
    legajoBuscar=gral.inputEntero("Legajo a buscar: ")
    for persona in listado:
        if persona["legajo"] == legajoBuscar:
            print(persona)

            print("Ingrese el dato o enter para continuar")
            nombre = input(f"Nombre({persona['nombre']}): ")
            if nombre == "":
                nombre=persona["nombre"]
            edad = input(f"Edad({persona['edad']}) ")
            if edad == "": # "45" == ""
                edad = persona["edad"]
            else:
                edad = int(edad) # int("45")
            curso = input("Curso: ")
            if curso == "":
                curso = persona["curso"]

            persona["nombre"] = nombre
            persona["curso"] = curso.lower()
            persona["edad"] = edad

            file = open("archivo-estudiantes.json","w")
            json.dump(listado,file, indent=2)
            file.close()
            break
    else:
        print(f"persona no encontrada con legajo {legajoBuscar}")

def agregarNotas(listado):
    cursoBuscar=input("Curso a agregar notas: ")
    for est in listado:
        if est["curso"].lower() == cursoBuscar.lower():
            nota=gral.inputEntero(f"Nota para {est['nombre']}: ")
            est["notas"].append(nota) # [].append()
    file = open("archivo-estudiantes.json","w")
    json.dump(listado,file, indent=2)
    file.close()


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Mon Nov 26 19:30:05 2018

@author: travisbarton
"""

import pandas as pd
from tkinter import *
import numpy as npa

test = pd.DataFrame(columns = ["id", 'sent', "O1", "O2", "O3", "O4"])

for i in range(5):
    test.loc[i,:] = [i,"this is test "+ str(i), .2, .5, .1, .1]

levels = [["Baby"], ["Dinos"], ["bad"], ["Spoons"]]

def Window_maker(sent, choices):
    root = Tk()
    topFrame = Frame(root)
    topFrame.pack()
    botFrame = Frame(root)
    botFrame.pack()

    label = Label(topFrame, text =sent)
    label.pack()

    button1 = Button(botFrame, text = choices[0])
    button1.pack()
    button2 = Button(botFrame, text = choices[1])
    button2.pack()
    root.mainloop()

def get_params(data):
    index = data.argsort()[-2:]
    return(index)

for i in range(test.shape[0]):
    index = get_params(test.iloc[i, 2:])
    choices = [levels[x] for x in index.values]
    Window_maker(test.iloc[i,1], choices)


class Solution:
    def permute(self, nums: List[int]) -> List[List[int]]:
        n = len(nums)
        ans = []

        def backtracking(curList, bitmask):
            nonlocal ans
            if bitmask + 1 == (1 << n):
                ans.append(curList.copy())
                return

            for i in range(n):
                if bitmask & (1 << i) != 0:
                    continue

                backtracking(curList + [nums[i]], bitmask | (1 << i))

        backtracking([], 0)
        return ans


from diffusers import StableDiffusionPipeline
from diffusers import StableDiffusionImg2ImgPipeline
from diffusers import StableDiffusionControlNetPipeline, ControlNetModel
from diffusers import DiffusionPipeline
import torch
import os
import uuid
import cv2
from PIL import Image
import numpy as np

class Text2Image:
    """
    Text2Image is a text prior generation model, which use clip embedding associate with text and image
    """

    def __init__(self, device):

        self.device = device
        self.torch_dtype = torch.float16 if ("cuda" or "mps") in device else torch.float32
        # self.pipline = StableDiffusionPipeline.from_pretrained("../../models--runwayml--stable-diffusion-v1-5/snapshots/39593d5650112b4cc580433f6b0435385882d819", trust_remote_code=True)
        self.pipline = StableDiffusionPipeline.from_pretrained(
            "runwayml/stable-diffusion-v1-5",
            trust_remote_code=True)
        self.pipline.to(device)
        # self.prompt = 'a high-quality, detailed, and professional image'
        # self.prompt = f"Complex 3 D rendering " \
        #               f"semi robot, in outer space, cyberpunk, robot parts, 150 mm, beautiful studio soft light, " \
        #               f"fine face, vibrant details, luxury cyberpunk, surrealism, anatomy, facial muscles, cables, " \
        #               f"microchips, electronic boards, current, elegance, beautiful background, octane rendering, H. R. Gig style, " \
        #               f"8k, wallpaper, best quality, masterpiece, illustration, an extremely exquisite and beautiful, extremely detailed, CG, unified, wallpaper, " \
        #               f"(realistic, photo realistic: 1.37), stunning, fine details, masterpiece, best quality, " \
        #               f"official art, extremely detailed CG unified, 8k wallpaper, robot, silver dummy,"

        self.prompt = f"monograph, full body, cyberpunk, pure linework, Parts assembly diagram," \
                      f" diagramatic sketch, Leonardo da Vinci sketch,  notation and Auxiliary line," \
                      f" gitantic scale,design spread sheet"

    def inference(self, text):

        prompt = text + "," + self.prompt
        image_name = f"{str(uuid.uuid4())[:8]}.png"
        image_filename = os.path.join('../image', image_name)

        image = self.pipline(prompt, num_inference_steps = 20).images[0]
        image.save(image_filename)
        print(
            f"\nProcessed Text2Image, Input Text: {text}, Output Image: {image_filename}")
        return image

if __name__ == "__main__":

    prompt = "美少女"
    model = Text2Image("mps")
    img = model.inference(prompt)


import os
import librosa
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
from sklearn.metrics import classification_report, accuracy_score
from flask import Flask, render_template, request
import pickle

app = Flask(__name__)

# Set the path to the GTZAN dataset
dataset_path = 'genres'

# Define the list of music genres
genres = ['blues', 'classical', 'country', 'disco', 'hiphop',
          'jazz', 'metal', 'pop', 'reggae', 'rock']

# Initialize empty lists to store the features and labels
features = []
labels = []

# Extract features from audio files
for genre in genres:
    genre_path = os.path.join(dataset_path, genre)
    for filename in os.listdir(genre_path):
        audio_path = os.path.join(genre_path, filename)
        print(audio_path)
        y, sr = librosa.load(audio_path, sr=None, duration=30)  # Load audio file (30 seconds)
        mfcc = librosa.feature.mfcc(y=y, sr=sr, n_mfcc=13)  # Extract MFCC features
        features.append(np.mean(mfcc, axis=1))  # Compute mean of MFCC coefficients
        labels.append(genre)

# Convert features and labels to numpy arrays
X = np.array(features)
y = np.array(labels)

# Split the dataset into training and testing sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# Scale the features
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)

# Train an SVM classifier
svm = SVC()
svm.fit(X_train, y_train)

model_scaler_dict = {
    'model': svm,
    'scaler': scaler,
}
with open('music_genre_classifier.pkl', 'wb') as file:
  pickle.dump(model_scaler_dict, file)