import pdb
import copy
import threading
from itertools import product
import datetime
import logging

from . import setup_environment
from . import utils
from .features import class_map
from .features import officers_collate

log = logging.getLogger(__name__)

def populate_features_table(config, schema):
    """Calculate values for all features which are set to True (in the config file)
    for the appropriate run type (officer/dispatch)
    """
    engine = setup_environment.get_database()
    if config['unit'] == 'officer':
        populate_officer_features_table(config, schema, engine)

def populate_dispatch_features_table(config, table_name, engine):
    """Calculate all the feature values and store them in the features table in the database"""

    # Get a list of all the features that are set to true.
    feature_list = [feat for feat, is_set_true in config['dispatch_features'].items() if is_set_true]
    num_features = len(feature_list)

    # make sure we have at least 1 feature
    assert num_features > 0, 'List of features to build is empty'

    feature_threads = []

    # run the build_and_insert of a set of features
    def run_thread(feature_sublist, engine):

        db_conn = engine.connect()

        for feature_name in feature_sublist:
            log.debug('... building feature {}'.format(feature_name))

            feature_obj = class_map.lookup(feature_name,
                                           unit='dispatch',
                                           from_date=config['raw_data_from_date'],
                                           to_date=config['raw_data_to_date'],
                                           fake_today=datetime.datetime.today(),
                                           table_name=table_name)
            feature_obj.build_and_insert(db_conn)

        db_conn.close()

    def chunks(l, n):
        """Yield successive n-sized chunks from l."""
        for i in range(0, len(l), n):
            yield l[i:i + n]

    # build each feature and store it in its own table in features_prejoin
    # start a new thread for each set of 5 features
    for feature_sublist in chunks(feature_list, 5):
        t = threading.Thread(target=run_thread, args=(feature_sublist, engine,))
        feature_threads.append(t)
        t.start()

    # join each thread and wait for it to be done to make sure we're done building them all
    # before we move on to joining them
    for i, thread in enumerate(feature_threads):
        log.debug('Waiting for feature thread: {}/{})'.format(i, (num_features / 5)))
        thread.join()

    # join each single-feature to the main table one at a time
    for i, feature_name in enumerate(feature_list):
        log.debug("Adding feature {}/{} ({})".format(i, len(feature_list), feature_name))

        update_query = ("UPDATE features.{table_name} AS feature_table "
                        "SET {feature} = prejoin_table.{feature} "
                        "FROM features_prejoin.{feature} AS prejoin_table "
                        "WHERE feature_table.dispatch_id = prejoin_table.dispatch_id "
                        .format(table_name=table_name,
                                feature=feature_name))

        engine.execute(update_query)

def join_feature_table(engine, list_prefixes, schema, features_table_name):
    """
    This function joins the block tables into the features_table_name
    using the prefix of the aggregated tables specified in each class

    :param engine: engine to connect to db
    :param list list_prefixes: list of prefixes specified in each block class
    :param str schema: name of schema where collate table are stored
    :param str features_table_name: name of the table to create in the features schema
    """
    table_names = ['{}_aggregation'.format(prefix) for prefix in list_prefixes]

    # seperate the tables by block that have a date column or not
    table_names_no_date = [x for x in table_names if 'ND' in x]
    table_names_with_date = [x for x in table_names if x not in set(table_names_no_date)]

    query = ""
    if len(table_names) > 0:
        if table_names_with_date:
            query = """ select * from {}."{}" """.format(schema, table_names_with_date[0])
            table_names_with_date = table_names_with_date[1:]
        for table_name in table_names_with_date:
            query += """ full outer join {}."{}"  using (officer_id, as_of_date)""".format(schema, table_name)

        # check if in the first loop above a table was added
        if len(query) == 0:
            query = """ select * from {}."{}" """.format(schema, table_names_no_date[0])
            table_names_no_date = table_names_no_date[1:]

        for table_name in table_names_no_date:
            query += """ full outer join {}."{}"  using (officer_id)""".format(schema, table_name)

        drop_table_query = """DROP TABLE IF EXISTS features."{}";""".format(features_table_name)
        engine.execute(drop_table_query)

        create_table_query = """CREATE TABLE features."{0}" as ({1});""".format(features_table_name,
                                                                                query)
        engine.execute(create_table_query)

        create_as_of_date_index = """CREATE INDEX on features."{0}" (as_of_date);  """.format(features_table_name)
        engine.execute(create_as_of_date_index)

        create_officer_date_index = """CREATE INDEX on features."{0}" (as_of_date, officer_id);  """.format(
            features_table_name)
        engine.execute(create_officer_date_index)

def add_feature_indexes(engine, list_prefixes, schema):
    """
    This function add indexes to each feature table created to speed up the matrix creation

    :param engine: engine to connect to db
    :param list list_prefixes: list of prefixes specified in each block class
    :param str schema: name of schema where collate table are stored
    """

    table_names = ['{}_aggregation'.format(prefix) for prefix in list_prefixes]

    # seperate the tables by block that have a date column or not
    table_names_no_date = [x for x in table_names if 'ND' in x]
    table_names_with_date = [x for x in table_names if x not in set(table_names_no_date)]

    for table_name in table_names_with_date:
        create_as_of_date_index = """ALTER TABLE "{0}"."{1}" ADD PRIMARY KEY (as_of_date,officer_id);  """.format(schema,
                                                                                table_name)
        engine.execute(create_as_of_date_index)

    for table_name in table_names_no_date:
        create_officer_index = """ALTER TABLE  "{0}"."{1}" ADD PRIMARY KEY (officer_id);  """.format(schema, table_name)
        engine.execute(create_officer_index)

def populate_officer_features_table(config, schema, engine):
    """
     Calculate all the feature values and store them in the features table in the database
     using collate method that creates a table of feature for each block and stores them in a
     given schema.

     Args:
        config: Python dict read in from YAML config file containing
                user-supplied details of the experiments to be run
        schema: schama name for storing collate tables
     """
    temporal_info = config['temporal_info'].copy()
    # get the list of fake todays specified by the config file
    as_of_dates = utils.generate_feature_dates(temporal_info)
    log.debug(as_of_dates)

    list_prefixes = []
    # get a list of all features that are set to true.
    for block_name in config["officer_features"]:
        log.debug('block_name: {}'.format(block_name))
        block = config['feature_blocks'][block_name]
        feature_list = [key for key in block if block[key] == True]

        ## Need to find a way of calling the class given the block_name
        block_class = class_map.lookup_block(block_name,
                                             module=officers_collate,
                                             lookback_durations=temporal_info['timegated_feature_lookback_duration'],
                                             n_cpus=config['n_cpus'])

        # Build collate tables and returns table name
        block_class.build_collate(engine, as_of_dates, feature_list, schema)
        block_class.build_post_features(engine, feature_list, schema)
        list_prefixes.extend(block_class.prefix)

    # Join all tables into one
    log.debug(list_prefixes)
    add_feature_indexes(engine, list_prefixes, schema)

#    join_feature_table(engine, list_prefixes, schema, table_name)


"""import numpy as np
import cv2"""

"""cap = cv2.VideoCapture(0)

while (True):

    # ret is we are returning the variable simple.
    ret, img = cap.read()
    # img = recognize(img, clf, faceCascade)
    cv2.imshow("welcome to face recognization", img)

    if cv2.waitKey(0) & 0xFF == ord('q'):
        break

cv2.destroyWindows('img')
cv2.waitKey(1)
cap.release()"""

"""def return_camera_indices():
    index = -2
    arr = []
    i = 10
    while i > 0:
        cap = cv2.VideoCapture(index)
        if cap.read()[0]:
            arr.append(index)
            cap.release()
        index += 1
        i -= 1
    return arr

print(return_camera_indices())"""

"""import numpy as np
import cv2
cap = cv2.VideoCapture(0)

while (True):
    # Capture frame-by-frame
    ret, frame = cap.read()

    # Display the resulting frame
    cv2.imshow('frame', frame)

    if cv2.waitKey(0) & 0xFF == ord('q'):
        break

cv2.destroyWindows('frame')

# When everything done, release the capture
cap.release()"""

import numpy as np
import cv2

cap = cv2.VideoCapture(0)

while(True):
    # Capture frame-by-frame
    ret, frame = cap.read()

    # Display the resulting frame
    cv2.imshow('frame',frame)

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cv2.destroyWindow('frame')

# When everything done, release the capture
cap.release()


#!/usr/bin/env python3

from view.base_view import BaseView
from model.person import Person

class PersonView(BaseView):

	def create_person(self, role):
		self.clear()
		data = []

		print(34 * '#')

		title = 'CREATE NEW {0}:'.format(role.upper())
		print('# {0:^30} #'.format(title))
		print(34 * '#')
		print()
		print('Type the name:')
		data.append(input())
		print('Type the email:')
		data.append(input())
		print('Type the login:')
		data.append(input())
		print('Type the password:')
		data.append(input())

		return data

	def view_people(self, people, role):
		self.clear()
		print(80 * '#')
		title = '{0} LIST:'.format(role.upper())
		print('# {0:^76} #'.format(title))
		print(80 * '#')
		print('# {0:<76} #'.format(''))
		print('# {0:<7} | {1:<20} | {2:<20} | {3:<20} #'.format(
				'Id',
				'Name',
				'Email',
				'Login'
				))
		for person in people:
			print('# {0:07d} | {1:<20} | {2:<20} | {3:<20} #'.format(
				person.id,
				person.name,
				person.email,
				person.login
				))

		print('# {0:<76} #'.format(''))
		print(80 * '#')
		print('\n\nPress ENTER to return:')
		return input()


from langchain.llms import OpenAI

from info_gpt import constants

openai_model = OpenAI(temperature=constants.TEMPERATURE)

def debug_logs(text: str):
    """Endpoint to debug logs.

    Parameters
    ----------
    text : str
        The logs to debug.

    Returns
    -------
    str
        The debugged logs.
    """
    text = (
        "Debug the following logs which were generated during building a Docker image: \n"
        + text
    )
    return openai_model(text)


from abc import (
  ABCMeta,
  abstractmethod)
from collections import defaultdict
import itertools
import logging

from prediction_metrics_manager import (
  MetricsManager,
  )

class IterationPhaseSpecLearnOnly(object):
  """ This class represents the Learn-only phase of the Iteration Cycle in
  the TaskControl block of description.py

  :param nIters: (int) iterations to remain in this phase. An iteration
                 corresponds to a single :meth:`OPFTaskDriver.handleInputRecord`
                 call.
  """

  def __init__(self, nIters):
    assert nIters > 0, "nIter=%s" % nIters

    self.__nIters = nIters
    return

  def __repr__(self):
    s = "%s(nIters=%r)" % (self.__class__.__name__, self.__nIters)
    return s

  def _getImpl(self, model):
    """ Creates and returns the _IterationPhase-based instance corresponding
    to this phase specification

    model:          Model instance
    """
    impl = _IterationPhaseLearnOnly(model=model,
                                    nIters=self.__nIters)
    return impl

class IterationPhaseSpecInferOnly(object):
  """ This class represents the Infer-only phase of the Iteration Cycle in
  the TaskControl block of description.py

  :param nIters: (int) Number of iterations to remain in this phase. An
         iteration corresponds to a single
         :meth:`OPFTaskDriver.handleInputRecord` call.
  :param inferenceArgs: (dict) A dictionary of arguments required for inference.
         These depend on the
         :class:`~nupic.frameworks.opf.opf_utils.InferenceType` of the current
         model.
  """

  def __init__(self, nIters, inferenceArgs=None):
    assert nIters > 0, "nIters=%s" % nIters

    self.__nIters = nIters
    self.__inferenceArgs = inferenceArgs
    return

  def __repr__(self):
    s = "%s(nIters=%r)" % (self.__class__.__name__, self.__nIters)
    return s

  def _getImpl(self, model):
    """ Creates and returns the _IterationPhase-based instance corresponding
    to this phase specification

    model:          Model instance
    """
    impl = _IterationPhaseInferOnly(model=model,
                                    nIters=self.__nIters,
                                    inferenceArgs=self.__inferenceArgs)
    return impl

class IterationPhaseSpecLearnAndInfer(object):
  """ This class represents the Learn-and-Infer phase of the Iteration Cycle in
  the TaskControl block of description.py

  :param nIters: (int) Number of iterations to remain in this phase. An
         iteration corresponds to a single
         :meth:`OPFTaskDriver.handleInputRecord` call.
  :param inferenceArgs: (dict) A dictionary of arguments required for inference.
         These depend on the
         :class:`~nupic.frameworks.opf.opf_utils.InferenceType` of the current
         model.
  """

  def __init__(self, nIters, inferenceArgs=None):
    assert nIters > 0, "nIters=%s" % nIters

    self.__nIters = nIters
    self.__inferenceArgs = inferenceArgs
    return

  def __repr__(self):
    s = "%s(nIters=%r)" % (self.__class__.__name__, self.__nIters)
    return s

  def _getImpl(self, model):
    """ Creates and returns the _IterationPhase-based instance corresponding
    to this phase specification

    model:          Model instance
    """
    impl = _IterationPhaseLearnAndInfer(model=model,
                                        nIters=self.__nIters,
                                        inferenceArgs=self.__inferenceArgs)
    return impl

class OPFTaskDriver(object):
  """
  Task Phase Driver implementation

  Conceptually, the client injects input records, one at a time, into
  an OPFTaskDriver instance for execution according to the
  current IterationPhase as maintained by the OPFTaskDriver instance.

  :param taskControl: (dict) conforming to opfTaskControlSchema.json that
         defines the actions to be performed on the given model.

  :param model: (:class:`nupic.frameworks.opf.model.Model`) that this
         OPFTaskDriver instance will drive.
  """

  def __init__(self, taskControl, model):
    #validateOpfJsonValue(taskControl, "opfTaskControlSchema.json")

    self.__reprstr = ("%s(" + \
                      "taskControl=%r, " + \
                      "model=%r)") % \
                          (self.__class__.__name__,
                           taskControl,
                           model)

    # Init logging
    #
    self.logger = logging.getLogger(".".join(
      ['com.numenta', self.__class__.__module__, self.__class__.__name__]))

    self.logger.debug(("Instantiating %s; %r.") % \
                        (self.__class__.__name__,
                         self.__reprstr))

    # -----------------------------------------------------------------------
    # Save args of interest
    #
    self.__taskControl = taskControl
    self.__model = model

    # -----------------------------------------------------------------------
    # Create Metrics Manager.
    #
    self.__metricsMgr = None
    metrics = taskControl.get('metrics', None)
    self.__metricsMgr = MetricsManager(metricSpecs=metrics,
                                       inferenceType=model.getInferenceType(),
                                       fieldInfo=model.getFieldInfo())

    # -----------------------------------------------------------------------
    # Figure out which metrics should be logged
    #

    # The logged metrics won't within the current task
    self.__loggedMetricLabels = set([])

    loggedMetricPatterns =  taskControl.get('loggedMetrics', None)

    # -----------------------------------------------------------------------
    # Create our phase manager
    #
    self.__phaseManager = _PhaseManager(
      model=model,
      phaseSpecs=taskControl.get('iterationCycle', []))

    # -----------------------------------------------------------------------
    # Initialize the callbacks container
    #
    self.__userCallbacks = defaultdict(list, taskControl.get('callbacks', {}))

    return

  def __repr__(self):
    return self.__reprstr

  def replaceIterationCycle(self, phaseSpecs):
    """ Replaces the Iteration Cycle phases

    :param phaseSpecs: Iteration cycle description consisting of a sequence of
                  IterationPhaseSpecXXXXX elements that are performed in the
                  given order
    """

    # -----------------------------------------------------------------------
    # Replace our phase manager
    #
    self.__phaseManager = _PhaseManager(
      model=self.__model,
      phaseSpecs=phaseSpecs)

    return

  def setup(self):
    """ Performs initial setup activities, including 'setup' callbacks. This
    method MUST be called once before the first call to
    :meth:`handleInputRecord`.
    """
    # Execute task-setup callbacks
    for cb in self.__userCallbacks['setup']:
      cb(self.__model)

    return

  def finalize(self):
    """ Perform final activities, including 'finish' callbacks. This
    method MUST be called once after the last call to :meth:`handleInputRecord`.
    """
    # Execute task-finish callbacks
    for cb in self.__userCallbacks['finish']:
      cb(self.__model)

    return

  def handleInputRecord(self, inputRecord):
    """
    Processes the given record according to the current iteration cycle phase

    :param inputRecord: (object) record expected to be returned from
           :meth:`nupic.data.record_stream.RecordStreamIface.getNextRecord`.

    :returns: :class:`nupic.frameworks.opf.opf_utils.ModelResult`
    """
    assert inputRecord, "Invalid inputRecord: %r" % inputRecord

    results = self.__phaseManager.handleInputRecord(inputRecord)
    metrics = self.__metricsMgr.update(results)

    # Execute task-postIter callbacks
    for cb in self.__userCallbacks['postIter']:
      cb(self.__model)

    results.metrics = metrics

    # Return the input and predictions for this record
    return results

  def getMetrics(self):
    """ Gets the current metric values

    :returns: A dictionary of metric values. The key for each entry is the label
              for the metric spec, as generated by
              :meth:`nupic.frameworks.opf.metrics.MetricSpec.getLabel`. The
              value for each entry is a dictionary containing the value of the
              metric as returned by
              :meth:`nupic.frameworks.opf.metrics.MetricsIface.getMetric`.
    """
    return self.__metricsMgr.getMetrics()

  def getMetricLabels(self):
    """
    :returns: (list) labels for the metrics that are being calculated
    """
    return self.__metricsMgr.getMetricLabels()

class _PhaseManager(object):
  """ Manages iteration cycle phase drivers
  """
  def __init__(self, model, phaseSpecs):
    """
    model:   Model instance
    phaseSpecs:   Iteration period description consisting of a sequence of
                  IterationPhaseSpecXXXXX elements that are performed in the
                  given order
    """

    self.__model = model

    # Instantiate Iteration Phase drivers
    self.__phases = tuple(map(lambda x: x._getImpl(model=model),
                              phaseSpecs))

    # Init phase-management structures
    if self.__phases:
      self.__phaseCycler = itertools.cycle(self.__phases)
      self.__advancePhase()

    return

  def __repr__(self):
    return "%s(phases=%r)" % \
                (self.__class__.__name__,
                 self.__phases)

  def __advancePhase(self):
    """ Advance to the next iteration cycle phase
    """
    self.__currentPhase = self.__phaseCycler.next()
    self.__currentPhase.enterPhase()

    return

  def handleInputRecord(self, inputRecord):
    """ Processes the given record according to the current phase

    inputRecord:  record object formatted according to
                  nupic.data.FileSource.getNext() result format.

    Returns:      An opf_utils.ModelResult object with the inputs and inferences
                  after the current record is processed by the model
    """

    results = self.__model.run(inputRecord)

    shouldContinue = self.__currentPhase.advance()
    if not shouldContinue:
      self.__advancePhase()

    return results

###############################################################################
# Iteration cycle phase drivers
###############################################################################

class _IterationPhase(object):
  """ Interface for IterationPhaseXXXXX classes
  """

  __metaclass__ = ABCMeta

  def __init__(self, nIters):
    """
    nIters:       Number of iterations; MUST be greater than 0
    """

    assert nIters > 0, "nIters=%s" % nIters
    self.__nIters = nIters

    return

  @abstractmethod
  def enterPhase(self):
    """
    Performs initialization that is necessary upon entry to the phase. Must
    be called before handleInputRecord() at the beginning of each phase
    """

    self.__iter = iter(xrange(self.__nIters))

    # Prime the iterator
    self.__iter.next()

  def advance(self):
    """ Advances the iteration;

    Returns:      True if more iterations remain; False if this is the final
                  iteration.
    """
    hasMore = True
    try:
      self.__iter.next()
    except StopIteration:
      self.__iter = None
      hasMore = False

    return hasMore

class _IterationPhaseLearnOnly(_IterationPhase):
  """ This class implements the "learn-only" phase of the Iteration Cycle
  """
  def __init__(self, model, nIters):
    """
    model:        Model instance
    nIters:       Number of iterations; MUST be greater than 0
    """

    super(_IterationPhaseLearnOnly, self).__init__(nIters=nIters)

    self.__model = model
    return

  def enterPhase(self):
    """ [_IterationPhase method implementation]
    Performs initialization that is necessary upon entry to the phase. Must
    be called before handleInputRecord() at the beginning of each phase
    """
    super(_IterationPhaseLearnOnly, self).enterPhase()
    self.__model.enableLearning()
    self.__model.disableInference()
    return

class _IterationPhaseInferCommon(_IterationPhase):
  """ Basic class providing common implementation for
  _IterationPhaseInferOnly and _IterationPhaseLearnAndInfer classes
  """
  def __init__(self, model, nIters, inferenceArgs):
    """
    model:        Model instance
    nIters:       Number of iterations; MUST be greater than 0
    inferenceArgs:
                  A dictionary of arguments required for inference. These
                  depend on the InferenceType of the current model
    """

    super(_IterationPhaseInferCommon, self).__init__(nIters=nIters)
    self._model = model
    self._inferenceArgs = inferenceArgs
    return

  def enterPhase(self):
    """ [_IterationPhase method implementation]
    Performs initialization that is necessary upon entry to the phase. Must
    be called before handleInputRecord() at the beginning of each phase
    """
    super(_IterationPhaseInferCommon, self).enterPhase()
    self._model.enableInference(inferenceArgs=self._inferenceArgs)
    return

class _IterationPhaseInferOnly(_IterationPhaseInferCommon):
  """ This class implements the "infer-only" phase of the Iteration Cycle
  """

  def __init__(self, model, nIters, inferenceArgs):
    """
    model:        Model instance
    nIters:       Number of iterations; MUST be greater than 0
    inferenceArgs:
                  A dictionary of arguments required for inference. These
                  depend on the InferenceType of the current model
    """

    super(_IterationPhaseInferOnly, self).__init__(
      model=model,
      nIters=nIters,
      inferenceArgs=inferenceArgs)
    return

  def enterPhase(self):
    """ [_IterationPhase method implementation]
    Performs initialization that is necessary upon entry to the phase. Must
    be called before handleInputRecord() at the beginning of each phase
    """
    super(_IterationPhaseInferOnly, self).enterPhase()
    self._model.disableLearning()
    return

class _IterationPhaseLearnAndInfer(_IterationPhaseInferCommon):
  """ This class implements the "learn-and-infer" phase of the Iteration Cycle
  """

  def __init__(self, model, nIters, inferenceArgs):
    """
    model:        Model instance
    nIters:       Number of iterations; MUST be greater than 0
    inferenceArgs:
                  A dictionary of arguments required for inference. These
                  depend on the InferenceType of the current model
    """

    super(_IterationPhaseLearnAndInfer, self).__init__(
      model=model,
      nIters=nIters,
      inferenceArgs=inferenceArgs)

    return

  def enterPhase(self):
    """ [_IterationPhase method implementation]
    Performs initialization that is necessary upon entry to the phase. Must
    be called before handleInputRecord() at the beginning of each phase
    """
    super(_IterationPhaseLearnAndInfer, self).enterPhase()
    self._model.enableLearning()
    return


from collections import deque
from copy import deepcopy

def get_data():
    with open('data.in', 'r') as f:
        L = [l.strip() for l in f]
    deck1 = deque(L[1:L.index('')])
    deck2 = deque(L[L.index('')+2:])
    #top card = at leftmost index
    return deck1, deck2

def calculate_score(d):
    score = [(n+1)*int(i) for n, i in enumerate(reversed(d))]
    return sum(score)

def play_p1(deck1, deck2, r):
    #print(f'round {r}')
    #print(f'player 1s deck {deck1}')
    #print(f'player 2s deck {deck2}')
    if len(deck2) == 0:
        #if deck 1 has won
        score = calculate_score(deck1)
        return score
    elif len(deck1) == 0:
        #deck 2 has won
        score = calculate_score(deck2)
        return score
    else:
        #if no one has won, conitnue playing
        d1c = deck1.popleft()
        d2c = deck2.popleft()
        #print(f'player 1 plays {d1c}')
        #print(f'player 2 plays {d2c}')
        if int(d1c) > int(d2c):
            #player 1 wins round
            #players card appended before opponents
            deck1.append(d1c)
            deck1.append(d2c)
            #print('player 1 wins')
        else:
            #player 2 wins round
            #print('player 2 wins')
            deck2.append(d2c)
            deck2.append(d1c)
        return play_p1(deck1, deck2, r+1)

#print(calculate_score(deck1))
def part_1():
    deck1, deck2 = get_data()
    return play_p1(deck1, deck2, 1)

#True if d1 wins
def play_p2(deck1, deck2):
    seen = set()
    while deck1 and deck2:
        D = (tuple(deck1), tuple(deck2))
        if D in seen:
            return calculate_score(deck1), True
        seen.add(D)
        #if no one has won, conitnue playing
        d1c = deck1.popleft()
        d2c = deck2.popleft()
        if len(deck1) >= int(d1c) and len(deck2) >= int(d2c):
            newd1 = deque(deck1[i] for i in range(int(d1c)))
            newd2 = deque(deck2[i] for i in range(int(d2c)))
            p1_wins = play_p2(deepcopy(newd1), deepcopy(newd2))[1]
        else:
            p1_wins = int(d1c) > int(d2c)
        if p1_wins:
            deck1.append(d1c)
            deck1.append(d2c)
        else:
            deck2.append(d2c)
            deck2.append(d1c)
    if deck1:
        return calculate_score(deck1), True
    else:
        return calculate_score(deck2), False

def part_2():
    deck1, deck2 = get_data()
    winner_score = play_p2(deck1, deck2)[0]
    return winner_score

print(part_1())
print(part_2())


import torch
import json
import numpy as np

from sklearn.cluster import KMeans
from scipy.stats import norm
import copy as cp
from sklearn.svm import SVC

from torch.quasirandom import SobolEngine
from mpl_toolkits.mplot3d import axes3d, Axes3D
from sklearn.gaussian_process import GaussianProcessRegressor
from sklearn.gaussian_process.kernels import ConstantKernel, Matern

import matplotlib.pyplot as plt
from matplotlib import cm

# from turbo_1.turbo_1 import Turbo1

# the input will be samples!
class Classifier():
    def __init__(self, samples, dims, kernel_type, gamma_type = "auto"):
        self.training_counter = 0
        assert dims >= 1
        assert type(samples)  ==  type([])
        self.dims    =   dims

        #create a gaussian process regressor
        noise        =   0.1
        m52          =   ConstantKernel(1.0) * Matern(length_scale=1.0, nu=2.5)
        self.gpr     =   GaussianProcessRegressor(kernel=m52, alpha=noise**2) #default to CPU
        self.kmean   =   KMeans(n_clusters=2)
        #learned boundary
        self.svm     =   SVC(kernel = kernel_type, gamma=gamma_type)
        #data structures to store
        self.samples = []
        self.X       = np.array([])
        self.fX      = np.array([])

        #good region is labeled as zero
        #bad  region is labeled as one
        self.good_label_mean  = -1
        self.bad_label_mean   = -1

        self.update_samples(samples)

    def is_splittable_svm(self):
        plabel = self.learn_clusters()
        self.learn_boundary(plabel)
        svm_label = self.svm.predict( self.X )
        if len( np.unique(svm_label) ) == 1:
            return False
        else:
            return True

    def get_max(self):
        return np.max(self.fX)

    def plot_samples_and_boundary(self, func, name):
        assert func.dims == 2

        plabels   = self.svm.predict( self.X )
        good_counts = len( self.X[np.where( plabels == 0 )] )
        bad_counts  = len( self.X[np.where( plabels == 1 )] )
        good_mean = np.mean( self.fX[ np.where( plabels == 0 ) ] )
        bad_mean  = np.mean( self.fX[ np.where( plabels == 1 ) ] )

        if np.isnan(good_mean) == False and np.isnan(bad_mean) == False:
            assert good_mean > bad_mean

        lb = func.lb
        ub = func.ub
        x = np.linspace(lb[0], ub[0], 100)
        y = np.linspace(lb[1], ub[1], 100)
        xv, yv = np.meshgrid(x, y)
        true_y = []
        for row in range(0, xv.shape[0]):
            for col in range(0, xv.shape[1]):
                x = xv[row][col]
                y = yv[row][col]
                true_y.append( func( np.array( [x, y] ) ) )
        true_y = np.array( true_y )
        pred_labels = self.svm.predict( np.c_[xv.ravel(), yv.ravel()] )
        pred_labels = pred_labels.reshape( xv.shape )

        fig, ax = plt.subplots()
        ax.contour(xv, yv, true_y.reshape(xv.shape), cmap=cm.coolwarm)
        ax.contourf(xv, yv, pred_labels, alpha=0.4)

        ax.scatter(self.X[ np.where(plabels == 0) , 0 ], self.X[ np.where(plabels == 0) , 1 ], marker='x', label="good-"+str(np.round(good_mean, 2))+"-"+str(good_counts) )
        ax.scatter(self.X[ np.where(plabels == 1) , 0 ], self.X[ np.where(plabels == 1) , 1 ], marker='x', label="bad-"+str(np.round(bad_mean, 2))+"-"+str(bad_counts)    )
        ax.legend(loc="best")
        ax.set_xlabel('x1')
        ax.set_ylabel('x2')
        ax.set_xlim([-10, 10])
        ax.set_ylim([-10, 10])
        plt.savefig(name)
        plt.close()

    def get_mean(self):
        return np.mean(self.fX)

    def update_samples(self, latest_samples):
        assert type(latest_samples) == type([])
        X  = []
        fX  = []
        for sample in latest_samples:
            X.append(  sample[0] )
            fX.append( sample[1] )

        self.X          = np.asarray(X, dtype=np.float32).reshape(-1, self.dims)
        self.fX         = np.asarray(fX,  dtype=np.float32).reshape(-1)
        self.samples    = latest_samples

    def train_gpr(self, samples):
        X  = []
        fX  = []
        for sample in samples:
            X.append(  sample[0] )
            fX.append( sample[1] )
        X  = np.asarray(X).reshape(-1, self.dims)
        fX = np.asarray(fX).reshape(-1)

        # print("training GPR with ", len(X), " data X")
        self.gpr.fit(X, fX)

    ###########################
    # BO sampling with EI
    ###########################

    def expected_improvement(self, X, xi=0.0001, use_ei = True):
        ''' Computes the EI at points X based on existing samples X_sample and Y_sample using a Gaussian process surrogate model.
        Args: X: Points at which EI shall be computed (m x d). X_sample: Sample locations (n x d).
        Y_sample: Sample values (n x 1). gpr: A GaussianProcessRegressor fitted to samples.
        xi: Exploitation-exploration trade-off parameter.
        Returns: Expected improvements at points X. '''
        X_sample = self.X
        Y_sample = self.fX.reshape((-1, 1))

        gpr = self.gpr

        mu, sigma = gpr.predict(X, return_std=True)

        if not use_ei:
            return mu
        else:
            #calculate EI
            mu_sample = gpr.predict(X_sample)
            sigma = sigma.reshape(-1, 1)
            mu_sample_opt = np.max(mu_sample)
            with np.errstate(divide='warn'):
                imp = mu - mu_sample_opt - xi
                imp = imp.reshape((-1, 1))
                Z = imp / sigma
                ei = imp * norm.cdf(Z) + sigma * norm.pdf(Z)
                ei[sigma == 0.0] = 0.0
            return ei

    def plot_boundary(self, X):
        if X.shape[1] > 2:
            return
        fig, ax = plt.subplots()
        ax.scatter( X[ :, 0 ], X[ :, 1 ] , marker='.')
        ax.scatter(self.X[ : , 0 ], self.X[ : , 1 ], marker='x')
        ax.set_xlim([-10, 10])
        ax.set_ylim([-10, 10])
        plt.savefig("boundary.pdf")
        plt.close()

    def get_sample_ratio_in_region( self, cands, path ):
        total = len(cands)
        for node in path:
            boundary = node[0].classifier.svm
            if len(cands) == 0:
                return 0, np.array([])
            assert len(cands) > 0
            cands = cands[ boundary.predict( cands ) == node[1] ]
            # node[1] store the direction to go
        ratio = len(cands) / total
        assert len(cands) <= total
        return ratio, cands

    def propose_rand_samples_probe(self, nums_samples, path, lb, ub):

        seed   = np.random.randint(int(1e6))
        sobol  = SobolEngine(dimension = self.dims, scramble=True, seed=seed)

        center = np.mean(self.X, axis = 0)
        #check if the center located in the region
        ratio, tmp = self.get_sample_ratio_in_region( np.reshape(center, (1, len(center) ) ), path )
        if ratio == 0:
            print("==>center not in the region, using random samples")
            return self.propose_rand_samples(nums_samples, lb, ub)
        # it is possible that the selected region has no points,
        # so we need check here

        axes    = len( center )

        final_L = []
        for axis in range(0, axes):
            L       = np.zeros( center.shape )
            L[axis] = 0.01
            ratio   = 1

            while ratio >= 0.9:
                L[axis] = L[axis]*2
                if L[axis] >= (ub[axis] - lb[axis]):
                    break
                lb_     = np.clip( center - L/2, lb, ub )
                ub_     = np.clip( center + L/2, lb, ub )
                cands_  = sobol.draw(10000).to(dtype=torch.float64).cpu().detach().numpy()
                cands_  = (ub_ - lb_)*cands_ + lb_
                ratio, tmp = self.get_sample_ratio_in_region(cands_, path )
            final_L.append( L[axis] )

        final_L   = np.array( final_L )
        lb_       = np.clip( center - final_L/2, lb, ub )
        ub_       = np.clip( center + final_L/2, lb, ub )
        print("center:", center)
        print("final lb:", lb_)
        print("final ub:", ub_)

        count         = 0
        cands         = np.array([])
        while len(cands) < 10000:
            count    += 10000
            cands     = sobol.draw(count).to(dtype=torch.float64).cpu().detach().numpy()

            cands     = (ub_ - lb_)*cands + lb_
            ratio, cands = self.get_sample_ratio_in_region(cands, path)
            samples_count = len( cands )

        #extract candidates

        return cands

    def propose_rand_samples_sobol(self, nums_samples, path, lb, ub):

        #rejected sampling
        selected_cands = np.zeros((1, self.dims))
        seed   = np.random.randint(int(1e6))
        sobol  = SobolEngine(dimension = self.dims, scramble=True, seed=seed)

        # scale the samples to the entire search space
        # ----------------------------------- #
        # while len(selected_cands) <= nums_samples:
        #     cands  = sobol.draw(100000).to(dtype=torch.float64).cpu().detach().numpy()
        #     cands  = (ub - lb)*cands + lb
        #     for node in path:
        #         boundary = node[0].classifier.svm
        #         if len(cands) == 0:
        #             return []
        #         cands = cands[ boundary.predict(cands) == node[1] ] # node[1] store the direction to go
        #     selected_cands = np.append( selected_cands, cands, axis= 0)
        #     print("total sampled:", len(selected_cands) )
        # return cands
        # ----------------------------------- #
        #shrink the cands region

        ratio_check, centers = self.get_sample_ratio_in_region(self.X, path)
        # no current samples located in the region
        # should not happen
        # print("ratio check:", ratio_check, len(self.X) )
        # assert ratio_check > 0
        if ratio_check == 0 or len(centers) == 0:
            return self.propose_rand_samples( nums_samples, lb, ub )

        lb_    = None
        ub_    = None

        final_cands = []
        for center in centers:
            center = self.X[ np.random.randint( len(self.X) ) ]
            cands  = sobol.draw(2000).to(dtype=torch.float64).cpu().detach().numpy()
            ratio  = 1
            L      = 0.0001
            Blimit = np.max(ub - lb)

            while ratio == 1 and L < Blimit:
                lb_    = np.clip( center - L/2, lb, ub )
                ub_    = np.clip( center + L/2, lb, ub )
                cands_ = cp.deepcopy( cands )
                cands_ = (ub_ - lb_)*cands_ + lb_
                ratio, cands_ = self.get_sample_ratio_in_region(cands_, path)
                if ratio < 1:
                    final_cands.extend( cands_.tolist() )
                L = L*2
        final_cands      = np.array( final_cands )
        if len(final_cands) > nums_samples:
            final_cands_idx  = np.random.choice( len(final_cands), nums_samples )
            return final_cands[final_cands_idx]
        else:
            if len(final_cands) == 0:
                return self.propose_rand_samples( nums_samples, lb, ub )
            else:
                return final_cands

    def propose_samples_bo( self, nums_samples = 10, path = None, lb = None, ub = None, samples = None):
        ''' Proposes the next sampling point by optimizing the acquisition function.
        Args: acquisition: Acquisition function. X_sample: Sample locations (n x d).
        Y_sample: Sample values (n x 1). gpr: A GaussianProcessRegressor fitted to samples.
        Returns: Location of the acquisition function maximum. '''
        assert path is not None and len(path) >= 0
        assert lb is not None and ub is not None
        assert samples is not None and len(samples) > 0

        self.train_gpr( samples ) # learn in unit cube

        dim  = self.dims
        nums_rand_samples = 10000
        if len(path) == 0:
            return self.propose_rand_samples(nums_samples, lb, ub)

        X    = self.propose_rand_samples_sobol(nums_rand_samples, path, lb, ub)
        # print("samples in the region:", len(X) )
        # self.plot_boundary(X)
        if len(X) == 0:
            return self.propose_rand_samples(nums_samples, lb, ub)

        X_ei = self.expected_improvement(X, xi=0.001, use_ei = True)
        row, col = X.shape

        X_ei = X_ei.reshape(len(X))
        n = nums_samples
        if X_ei.shape[0] < n:
            n = X_ei.shape[0]
        indices = np.argsort(X_ei)[-n:]
        proposed_X = X[indices]
        return proposed_X

    ###########################
    # sampling with turbo
    ###########################
    # version 1: select a partition, perform one-time turbo search

    # def propose_samples_turbo(self, num_samples, path, func):
    #     #throw a uniform sampling in the selected partition
    #     X_init = self.propose_rand_samples_sobol(30, path, func.lb, func.ub)
    #     #get samples around the selected partition
    #     print("sampled ", len(X_init), " for the initialization")
    #     turbo1 = Turbo1(
    #         f  = func,              # Handle to objective function
    #         lb = func.lb,           # Numpy array specifying lower bounds
    #         ub = func.ub,           # Numpy array specifying upper bounds
    #         n_init = 30,            # Number of initial bounds from an Latin hypercube design
    #         max_evals  = num_samples, # Maximum number of evaluations
    #         batch_size = 1,         # How large batch size TuRBO uses
    #         verbose=True,           # Print information from each batch
    #         use_ard=True,           # Set to true if you want to use ARD for the GP kernel
    #         max_cholesky_size=2000, # When we switch from Cholesky to Lanczos
    #         n_training_steps=50,    # Number of steps of ADAM to learn the hypers
    #         min_cuda=1024,          #  Run on the CPU for small datasets
    #         device="cpu",           # "cpu" or "cuda"
    #         dtype="float32",        # float64 or float32
    #         X_init = X_init,
    #     )
    #
    #     proposed_X, fX = turbo1.optimize( )
    #     fX = fX*-1
    #
    #     return proposed_X, fX

    ###########################
    # random sampling
    ###########################

    def propose_rand_samples(self, nums_samples, lb, ub):
        x = np.random.uniform(lb, ub, size = (nums_samples, self.dims) )
        return x

    def propose_samples_rand( self, nums_samples = 10):
        return self.propose_rand_samples(nums_samples, self.lb, self.ub)

    ###########################
    # learning boundary
    ###########################

    def get_cluster_mean(self, plabel):
        assert plabel.shape[0] == self.fX.shape[0]

        zero_label_fX = []
        one_label_fX  = []

        for idx in range(0, len(plabel)):
            if plabel[idx] == 0:
                zero_label_fX.append( self.fX[idx]  )
            elif plabel[idx] == 1:
                one_label_fX.append( self.fX[idx] )
            else:
                print("kmean should only predict two clusters, Classifiers.py:line73")
                os._exit(1)

        good_label_mean = np.mean( np.array(zero_label_fX) )
        bad_label_mean  = np.mean( np.array(one_label_fX) )
        return good_label_mean, bad_label_mean

    def learn_boundary(self, plabel):
        assert len(plabel) == len(self.X)
        self.svm.fit(self.X, plabel)

    def learn_clusters(self):
        assert len(self.samples) >= 2, "samples must > 0"
        assert self.X.shape[0], "points must > 0"
        assert self.fX.shape[0], "fX must > 0"
        assert self.X.shape[0] == self.fX.shape[0]

        tmp = np.concatenate( (self.X, self.fX.reshape([-1, 1]) ), axis = 1 )
        assert tmp.shape[0] == self.fX.shape[0]

        self.kmean  = self.kmean.fit(tmp)
        plabel      = self.kmean.predict( tmp )

        # the 0-1 labels in kmean can be different from the actual
        # flip the label is not consistent
        # 0: good cluster, 1: bad cluster

        self.good_label_mean , self.bad_label_mean = self.get_cluster_mean(plabel)

        if self.bad_label_mean > self.good_label_mean:
            for idx in range(0, len(plabel)):
                if plabel[idx] == 0:
                    plabel[idx] = 1
                else:
                    plabel[idx] = 0

        self.good_label_mean , self.bad_label_mean = self.get_cluster_mean(plabel)

        return plabel

    def split_data(self):
        good_samples = []
        bad_samples  = []
        train_good_samples = []
        train_bad_samples  = []
        if len( self.samples ) == 0:
            return good_samples, bad_samples

        plabel = self.learn_clusters( )
        self.learn_boundary( plabel )

        for idx in range(0, len(plabel)):
            if plabel[idx] == 0:
                #ensure the consistency
                assert self.samples[idx][-1] - self.fX[idx] <= 1
                good_samples.append( self.samples[idx] )
                train_good_samples.append( self.X[idx] )
            else:
                bad_samples.append( self.samples[idx] )
                train_bad_samples.append( self.X[idx] )

        train_good_samples = np.array(train_good_samples)
        train_bad_samples  = np.array(train_bad_samples)

        assert len(good_samples) + len(bad_samples) == len(self.samples)

        return  good_samples, bad_samples


# split
# java의 StringTokenizer에서 자동으로 list 저장까지 해주는 함수

items = 'zero one two three'
items.split()

print(items)

langs = 'python,jquery,javascript,pascal'
a,b,c,d = langs.split(",")

print(d)

example = "cs50.gachon.edu"
subdomain, domain, tld = example.split(".")
print(domain)

#join


"""
    Memo the Number!
Kanate Boonsiri     63090500404
Bavornthat Dangtang 63090500412
Katepiss Sriburapa  63090500419
Thitipong Thongkam  63090500424
"""

import sys
from random import *
from PyQt5.QtCore import QTimer
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *

# Creat HowToPlayScreen
class Widget2(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)

        self.widget_layout2 = QGridLayout()
        self.setGeometry(0, 0, 0, 0)

        self.PlayGame = QPushButton('Play')
        self.PlayGame.setFixedSize(140, 40)

        def play_button_clicked():
            # Closing HowToPlay Screen
            widget.close()
            widget2.show()

        self.PlayGame.clicked.connect(play_button_clicked)

        pixmap = QPixmap('Data\HowToPlay.jpg')
        print('size = ', pixmap.size())
        width = pixmap.size().width()
        height = pixmap.size().height()

        self.HowtoPlayImage = QLabel()
        self.HowtoPlayImage.setPixmap(pixmap)
        self.HowtoPlayImage.setGeometry(0, 0, 0, 0)
        self.HowtoPlayImage.resize(width, height)
        self.widget_layout2.addWidget(self.HowtoPlayImage, 0, 0)
        self.widget_layout2.addWidget(self.PlayGame, 0, 1)
        self.setLayout(self.widget_layout2)

        self.setWindowTitle('Memo the Number!')  # Window name
        self.setWindowIcon(QIcon('Data\Dogge.jpg'))  # Icon used by the window.

class Widget(QWidget):

    def __init__(self, parent=None):
        QWidget.__init__(self, parent)

        # Set Color for Button
        Color_Defult = QPalette()
        Color_Red = QPalette()
        Color_Defult.setColor(QPalette.Button, QColor(255, 0, 0, 255))
        Color_Red.setColor(QPalette.Button, QColor(255, 0, 0, 0))

        self.setAutoFillBackground(True)
        self.widget_layout = QGridLayout()
        self.setGeometry(400, 200, 350, 200)

        # Creat Button
        self.Button1 = QPushButton()
        self.Button2 = QPushButton()
        self.Button3 = QPushButton()
        self.Button4 = QPushButton()
        self.Button5 = QPushButton()
        self.Button6 = QPushButton()
        self.Button7 = QPushButton()
        self.Button8 = QPushButton()
        self.Button9 = QPushButton()
        self.ButtonStart = QPushButton('Start')

        # Set Size for Button
        self.Button1.setFixedSize(50, 50)
        self.Button2.setFixedSize(50, 50)
        self.Button3.setFixedSize(50, 50)
        self.Button4.setFixedSize(50, 50)
        self.Button5.setFixedSize(50, 50)
        self.Button6.setFixedSize(50, 50)
        self.Button7.setFixedSize(50, 50)
        self.Button8.setFixedSize(50, 50)
        self.Button9.setFixedSize(50, 50)
        self.ButtonStart.setFixedSize(140, 40)

        # Set Color for Button
        self.Button1.setAutoFillBackground(True)
        self.Button2.setAutoFillBackground(True)
        self.Button3.setAutoFillBackground(True)
        self.Button4.setAutoFillBackground(True)
        self.Button5.setAutoFillBackground(True)
        self.Button6.setAutoFillBackground(True)
        self.Button7.setAutoFillBackground(True)
        self.Button8.setAutoFillBackground(True)
        self.Button9.setAutoFillBackground(True)
        self.ButtonStart.setAutoFillBackground(True)

        # Creat Label
        self.line_edit = QLabel()
        self.line_edit2 = QLabel()
        font = self.line_edit.font()
        font.setPointSize(16)
        self.line_edit.setFont(font)

        font2 = self.line_edit2.font()
        font2.setPointSize(16)
        self.line_edit2.setFont(font2)

        # When the buttons get clicked
        self.ButtonStart.clicked.connect(self.Start_clicked)
        self.Button1.clicked.connect(self.radio1_clicked)
        self.Button2.clicked.connect(self.radio2_clicked)
        self.Button3.clicked.connect(self.radio3_clicked)
        self.Button4.clicked.connect(self.radio4_clicked)
        self.Button5.clicked.connect(self.radio5_clicked)
        self.Button6.clicked.connect(self.radio6_clicked)
        self.Button7.clicked.connect(self.radio7_clicked)
        self.Button8.clicked.connect(self.radio8_clicked)
        self.Button9.clicked.connect(self.radio9_clicked)

        # Add Button to Widget
        self.widget_layout.addWidget(self.Button1, 0, 0)
        self.widget_layout.addWidget(self.Button2, 0, 1)
        self.widget_layout.addWidget(self.Button3, 0, 2)
        self.widget_layout.addWidget(self.Button4, 1, 0)
        self.widget_layout.addWidget(self.Button5, 1, 1)
        self.widget_layout.addWidget(self.Button6, 1, 2)
        self.widget_layout.addWidget(self.Button7, 2, 0)
        self.widget_layout.addWidget(self.Button8, 2, 1)
        self.widget_layout.addWidget(self.Button9, 2, 2)
        self.widget_layout.addWidget(self.ButtonStart, 4, 3)
        self.widget_layout.addWidget(self.line_edit, 5, 3)
        self.widget_layout.addWidget(self.line_edit2, 6, 3)
        self.setLayout(self.widget_layout)

        self.setWindowTitle('Memo the Number!')  # Window name
        self.setWindowIcon(QIcon('Data\Dogge.jpg'))  # Icon used by the window.

        self.TimeCount = 0
        self.Running = 0
        self.InputCount = 0
        self.InputCount2 = 0
        self.InputReady = 0
        self.InputListCheck = 0
        self.CheckWin = 0
        self.MaxScore = 0
        self.CurrentScore = 0
        self.GameOver = 0
        self.RandomNumber = 0
        self.InputClicked = 0
        self.Started = 1
        self.timer = QTimer()
        self.timer.timeout.connect(self.update_time)
        self.timer.start(1000)
        self.ListAns = []
        self.ListInput = []
        self.line_edit.setText("Max score = {0}".format(self.MaxScore))
        self.RandomNumber = randrange(1, 10)
        self.ListAns.append(self.RandomNumber)
        self.RandomNumber = randrange(1, 10)
        self.ListAns.append(self.RandomNumber)

    def Start_clicked(self):
        if self.Started == 1:
            if self.GameOver == 1:
                self.CurrentScore = 0
                self.GameOver = 0
            self.timer.start()
            self.Started = 0
            self.ButtonStart.setText("Wait..")
            self.TimeCount = 0
            self.Running = 1
            self.RandomNumber = randrange(1, 10)
            self.ListAns.append(self.RandomNumber)
        else:
            self.ButtonStart.setText("WAIT!")

    def radio1_clicked(self):
        if self.InputReady == 1:
            if self.InputClicked == 0:
                self.timer.start()
                self.TimeCount = 1.5
                self.InputClicked = 1
                Color_Red = QPalette()
                self.setAutoFillBackground(True)
                self.setPalette(Color_Red)
                Color_Red.setColor(QPalette.Button, QColor(255, 0, 0, 255))
                self.Button1.setPalette(Color_Red)
                self.ListInput.append(1)
                self.InputCount += 1
                self.InputCount2 += 1
                self.line_edit2.setText('{0} / {1}'.format(self.InputCount2, len(self.ListAns)))

    def radio2_clicked(self):
        if self.InputReady == 1:
            if self.InputClicked == 0:
                self.timer.start()
                self.TimeCount = 1.5
                self.InputClicked = 1
                Color_Red = QPalette()
                self.setAutoFillBackground(True)
                self.setPalette(Color_Red)
                Color_Red.setColor(QPalette.Button, QColor(255, 0, 0, 255))
                self.Button2.setPalette(Color_Red)
                self.ListInput.append(2)
                self.InputCount += 1
                self.InputCount2 += 1
                self.line_edit2.setText('{0} / {1}'.format(self.InputCount2, len(self.ListAns)))

    def radio3_clicked(self):
        if self.InputReady == 1:
            if self.InputClicked == 0:
                self.timer.start()
                self.TimeCount = 1.5
                self.InputClicked = 1
                Color_Red = QPalette()
                self.setAutoFillBackground(True)
                self.setPalette(Color_Red)
                Color_Red.setColor(QPalette.Button, QColor(255, 0, 0, 255))
                self.Button3.setPalette(Color_Red)
                self.ListInput.append(3)
                self.InputCount += 1
                self.InputCount2 += 1
                self.line_edit2.setText('{0} / {1}'.format(self.InputCount2, len(self.ListAns)))

    def radio4_clicked(self):
        if self.InputReady == 1:
            if self.InputClicked == 0:
                self.timer.start()
                self.TimeCount = 1.5
                self.InputClicked = 1
                Color_Red = QPalette()
                self.setAutoFillBackground(True)
                self.setPalette(Color_Red)
                Color_Red.setColor(QPalette.Button, QColor(255, 0, 0, 255))
                self.Button4.setPalette(Color_Red)
                self.ListInput.append(4)
                self.InputCount += 1
                self.InputCount2 += 1
                self.line_edit2.setText('{0} / {1}'.format(self.InputCount2, len(self.ListAns)))

    def radio5_clicked(self):
        if self.InputReady == 1:
            if self.InputClicked == 0:
                self.timer.start()
                self.TimeCount = 1.5
                self.InputClicked = 1
                Color_Red = QPalette()
                self.setAutoFillBackground(True)
                self.setPalette(Color_Red)
                Color_Red.setColor(QPalette.Button, QColor(255, 0, 0, 255))
                self.Button5.setPalette(Color_Red)
                self.ListInput.append(5)
                self.InputCount += 1
                self.InputCount2 += 1
                self.line_edit2.setText('{0} / {1}'.format(self.InputCount2, len(self.ListAns)))

    def radio6_clicked(self):
        if self.InputReady == 1:
            if self.InputClicked == 0:
                self.timer.start()
                self.TimeCount = 1.5
                self.InputClicked = 1
                Color_Red = QPalette()
                self.setAutoFillBackground(True)
                self.setPalette(Color_Red)
                Color_Red.setColor(QPalette.Button, QColor(255, 0, 0, 255))
                self.Button6.setPalette(Color_Red)
                self.ListInput.append(6)
                self.InputCount += 1
                self.InputCount2 += 1
                self.line_edit2.setText('{0} / {1}'.format(self.InputCount2, len(self.ListAns)))

    def radio7_clicked(self):
        if self.InputReady == 1:
            if self.InputClicked == 0:
                self.timer.start()
                self.TimeCount = 1.5
                self.InputClicked = 1
                Color_Red = QPalette()
                self.setAutoFillBackground(True)
                self.setPalette(Color_Red)
                Color_Red.setColor(QPalette.Button, QColor(255, 0, 0, 255))
                self.Button7.setPalette(Color_Red)
                self.ListInput.append(7)
                self.InputCount += 1
                self.InputCount2 += 1
                self.line_edit2.setText('{0} / {1}'.format(self.InputCount2, len(self.ListAns)))

    def radio8_clicked(self):
        if self.InputReady == 1:
            if self.InputClicked == 0:
                self.timer.start()
                self.TimeCount = 1.5
                self.InputClicked = 1
                Color_Red = QPalette()
                self.setAutoFillBackground(True)
                self.setPalette(Color_Red)
                Color_Red.setColor(QPalette.Button, QColor(255, 0, 0, 255))
                self.Button8.setPalette(Color_Red)
                self.ListInput.append(8)
                self.InputCount += 1
                self.InputCount2 += 1
                self.line_edit2.setText('{0} / {1}'.format(self.InputCount2, len(self.ListAns)))

    def radio9_clicked(self):
        if self.InputReady == 1:
            if self.InputClicked == 0:
                self.timer.start()
                self.TimeCount = 1.5
                self.InputClicked = 1
                Color_Red = QPalette()
                self.setAutoFillBackground(True)
                self.setPalette(Color_Red)
                Color_Red.setColor(QPalette.Button, QColor(255, 0, 0, 255))
                self.Button9.setPalette(Color_Red)
                self.ListInput.append(9)
                self.InputCount += 1
                self.InputCount2 += 1
                self.line_edit2.setText('{0} / {1}'.format(self.InputCount2, len(self.ListAns)))

    def update_time(self):
        Color_Red = QPalette()
        Color_Default = QPalette()
        Color_Purple = QPalette()
        self.setAutoFillBackground(True)
        self.setPalette(Color_Red)
        self.setPalette(Color_Default)
        self.setPalette(Color_Purple)
        Color_Red.setColor(QPalette.Button, QColor(255, 0, 0, 255))
        Color_Default.setColor(QPalette.Button, QColor(255, 0, 0, 0))
        Color_Purple.setColor(QPalette.Button, QColor(65, 21, 186))

        if self.InputReady == 1:
            self.CheckWin = 1
            if len(self.ListAns) == len(self.ListInput):
                for i in range(len(self.ListAns)):
                    if self.ListAns[i] != self.ListInput[i]:
                        self.CheckWin = 0
                if self.CheckWin == 0:
                    self.ButtonStart.setText("Wrong, Try again?")
                    self.GameOver = 1
                    self.ListAns = []
                    self.RandomNumber = randrange(1, 10)
                    self.ListAns.append(self.RandomNumber)
                    self.RandomNumber = randrange(1, 10)
                    self.ListAns.append(self.RandomNumber)
                if self.CheckWin == 1:
                    self.ButtonStart.setText("Continue")
                    self.CurrentScore += 1
                self.Started = 1
                self.ButtonStart.setPalette(Color_Default)
                self.Running = 0
                self.InputCount = 0
                self.InputReady = 0
                self.InputListCheck = 0
                self.ListInput = []
                self.InputCount2 = 0
                self.line_edit2.setText("Your score = {0}".format(self.CurrentScore))
                if self.CurrentScore > self.MaxScore:
                    self.MaxScore = self.CurrentScore
                self.line_edit.setText("Max score = {0}".format(self.MaxScore))

        if self.Running == 1:
            self.Started = 0
            self.ButtonStart.setPalette(Color_Purple)
            self.line_edit.setText("Max score = {0}".format(self.MaxScore))
            self.line_edit2.setText("Remember!")
            if int(self.TimeCount) == len(self.ListAns):
                self.Running = 0
                self.Button1.setPalette(Color_Default)
                self.Button2.setPalette(Color_Default)
                self.Button3.setPalette(Color_Default)
                self.Button4.setPalette(Color_Default)
                self.Button5.setPalette(Color_Default)
                self.Button6.setPalette(Color_Default)
                self.Button7.setPalette(Color_Default)
                self.Button8.setPalette(Color_Default)
                self.Button9.setPalette(Color_Default)
                self.timer.stop()
                self.InputReady = 1
                self.line_edit2.setText('► Your turn!')

        if self.Running == 1:
            if (self.TimeCount * 10) % 2 == 0:
                self.InputListCheck = int(self.TimeCount)
                print(self.InputListCheck, self.ListAns[self.InputListCheck])
                if self.ListAns[self.InputListCheck] == 1:
                    self.Button1.setPalette(Color_Red)
                elif self.ListAns[self.InputListCheck] == 2:
                    self.Button2.setPalette(Color_Red)
                elif self.ListAns[self.InputListCheck] == 3:
                    self.Button3.setPalette(Color_Red)
                elif self.ListAns[self.InputListCheck] == 4:
                    self.Button4.setPalette(Color_Red)
                elif self.ListAns[self.InputListCheck] == 5:
                    self.Button5.setPalette(Color_Red)
                elif self.ListAns[self.InputListCheck] == 6:
                    self.Button6.setPalette(Color_Red)
                elif self.ListAns[self.InputListCheck] == 7:
                    self.Button7.setPalette(Color_Red)
                elif self.ListAns[self.InputListCheck] == 8:
                    self.Button8.setPalette(Color_Red)
                elif self.ListAns[self.InputListCheck] == 9:
                    self.Button9.setPalette(Color_Red)
            else:
                self.Button1.setPalette(Color_Default)
                self.Button2.setPalette(Color_Default)
                self.Button3.setPalette(Color_Default)
                self.Button4.setPalette(Color_Default)
                self.Button5.setPalette(Color_Default)
                self.Button6.setPalette(Color_Default)
                self.Button7.setPalette(Color_Default)
                self.Button8.setPalette(Color_Default)
                self.Button9.setPalette(Color_Default)

        self.TimeCount += 0.5
        if self.TimeCount == 2.0:
            if self.InputClicked == 1:
                self.InputClicked = 0
                self.Button1.setPalette(Color_Default)
                self.Button2.setPalette(Color_Default)
                self.Button3.setPalette(Color_Default)
                self.Button4.setPalette(Color_Default)
                self.Button5.setPalette(Color_Default)
                self.Button6.setPalette(Color_Default)
                self.Button7.setPalette(Color_Default)
                self.Button8.setPalette(Color_Default)
                self.Button9.setPalette(Color_Default)
                self.timer.stop()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    widget = Widget2()
    widget.show()
    widget2 = Widget()
    sys.exit(app.exec_())


num = int(input("Enter Number: "))

while True:

  if num%3==0:
     print("Fizz")

  elif num%5==0:
     print('Buzz')

  elif (num%3==0,num%5==0):
      print('Fizz Buzz')

  choice = input("Let's do Continew? (yes/no): ")

  if choice == "no":
    print('Thank You')
    break

  else:
   print('Invelid Input')


contacts = {
    "John": {
        "number": "1234567890",
        "address": "123 main st",
    },
    "Jack": {
        "number": "4567890123",
        "address": "456 main st",
    },
}

print(contacts)

for name, d in contacts.items():
    print(f"{name}'s phone number is {d['number']}.")


from django.core.mail import send_mail
from django.template.loader import render_to_string

from rest_framework.reverse import reverse

from alfheimproject.settings import CONFIG, SECRETS

def send_account_verification(sender, instance, **kwargs):
    html_msg = render_to_string('email_verification.html', {
        'server_name': CONFIG['server']['conf']['server_name'],
        'username': instance.user.username,
        'email': instance.user.email,
        'staff_email': SECRETS['smtp']['email_host_user'],
        'creation_date': instance.created_date,
        'verify_url': '{domain}{url}?token={token}'.format(
            domain=CONFIG['server']['conf']['server_domain'],
            url=reverse('activate_master_account'),
            token=instance.token
        )
    })
    send_mail(
        subject=CONFIG['emails']['default_subject'].format(server_name=CONFIG['server']['conf']['server_name']),
        message=CONFIG['emails']['default_message'].format(server_name=CONFIG['server']['conf']['server_name'],
                                                           user=instance.user.username),
        from_email=SECRETS['smtp']['email_host_user'],
        recipient_list=[instance.user.email],
        html_message=html_msg
    )


from google.cloud import vision

# import os
# credential_path = "C:\Users\augus\OneDrive\Desktop\python\vision-ai-test\nifty-stage-313710-6d11794f516f.json"
# os.environ['GOOGLE_APPLICATION_CREDENTIALS'] = credential_path

# print("user >", end="")
# input()
# print("AI >ん？")
# print("user >", end="")
# input()
# print("AI >ええで。画像URLくれ：", end="")
img_path = input()
# print("user >", end="")
# input()
# print("AI >可愛い。")
# print("user >", end="")
# input()
# print("AI >へいへい。")
# print("")

# print("解析したい画像のナンバーを00-99で入力してください：", end="")
# input = input()

# img_path = "./images/img_" + input + ".jpg"
# print(img_path)

with open(img_path, 'rb') as image_file:
	content = image_file.read()

# visionAPIが扱えるデータ形式
image = vision.Image(content=content)
# print(image)

# インスタンスを生成
annotator_client = vision.ImageAnnotatorClient()

response_data = annotator_client.label_detection(image=image)

labels = response_data.label_annotations

print('--------RESULT--------')
for label in labels:
	print(label.description, ':', round(label.score * 100, 2), '%')
print('----------------------')


from django.db import models
from django.utils.timezone import now

# admin, buyer, seller, buyer_treehugger, seller_treehugger.
class UserCategory(models.Model):
    category_id = models.AutoField(primary_key=True)
    category_name = models.CharField(max_length=32, unique=True)

# active, unverified, suspended, tobedeleted
class UserStatus(models.Model):
    status_id = models.AutoField(primary_key=True)
    status = models.CharField(max_length=32, unique=True)

# registered/pending
class RegistrationStatus(models.Model):
    status_id = models.AutoField(primary_key=True)
    status = models.CharField(max_length=32, unique=True)

class Users(models.Model):
    user_id = models.AutoField(primary_key=True)
    user_status = models.ForeignKey(UserStatus, on_delete=models.CASCADE)
    email_address = models.EmailField(max_length=254, unique=True)
    name = models.CharField(max_length=128)
    member_since = models.DateTimeField(default=now)

    registration_status = models.ForeignKey(RegistrationStatus, on_delete=models.CASCADE)

class UserProfile(models.Model):
    user_id = models.ForeignKey(Users, on_delete=models.CASCADE)
    about_me = models.CharField(max_length=512)
    address = models.CharField(max_length=126)
    city = models.CharField(max_length=64)
    state = models.CharField(max_length=64)
    country = models.CharField(max_length=64, default="India")
    postal_code = models.CharField(max_length=18)
    latitude = models.FloatField(max_length=32, default="12.9716")
    longitude = models.FloatField(max_length=32, default="77.5946")
    phone_primary = models.CharField(max_length=32, unique=True)
    phone_verified = models.BooleanField(default=False)
    email_verified = models.BooleanField(default=False)

# List of categories the web portal is supporting.
class ProductCategory(models.Model):
    category_id = models.AutoField(primary_key=True)
    category_name = models.CharField(max_length=64, unique=True)

# a product has an id, and it belongs to a category.
class Product(models.Model):
    product_id = models.AutoField(primary_key=True)
    product_name = models.CharField(max_length=64, unique=True)
    product_category = models.ForeignKey(ProductCategory, on_delete=models.CASCADE)
    product_default_image = models.CharField(max_length=124)

# each product has a measuring unit, a base measuring unit and a multiplier.
# measuring unit = multiplier * base measuring unit
class MeasuringUnit(models.Model):
    measuring_unit_id = models.AutoField(primary_key=True)
    measuring_unit = models.CharField(max_length=32, unique=True)

# list of sellers, with the list of products they sell.
class Seller(models.Model):
    seller = models.ForeignKey(Users, on_delete=models.CASCADE)
    sells = models.ForeignKey(Product, on_delete=models.CASCADE)

    class Meta:
        unique_together = ("seller", "sells")

# list of buyers, with the list of products they buy.
class Buyer(models.Model):
    buyer_id = models.ForeignKey(Users, on_delete=models.CASCADE)
    buys = models.ForeignKey(Product, on_delete=models.CASCADE)

    class Meta:
        unique_together = ("buyer_id", "buys")

# inventory item has a status: draft, active, suspended, unavailable.
class InventoryItemStatus(models.Model):
    status_id = models.AutoField(primary_key=True)
    status = models.CharField(max_length=16, unique=True)

# a list of all advertised products.
# TODO: item_picture must accept a picture, upload it to web server.
class Inventory(models.Model):
    inventory_item_id = models.BigAutoField(primary_key=True)
    listing_title = models.CharField(max_length=64)
    item_price = models.CharField(max_length=16)
    inventory_item_status = models.ForeignKey(InventoryItemStatus, on_delete=models.CASCADE)
    product = models.ForeignKey(Product, on_delete=models.CASCADE)
    inventory_product_quantity = models.FloatField()
    seller = models.ForeignKey(Seller, on_delete=models.CASCADE)
    product_measuring_unit = models.ForeignKey(MeasuringUnit, on_delete=models.PROTECT)
    inventory_item_create_datetime = models.DateTimeField(default=now)
    inventory_item_update_datetime = models.DateTimeField(auto_now=True)
    inventory_available_from_datetime = models.DateTimeField(default=now)
    item_picture = models.CharField(max_length=124)
    product_category = models.ForeignKey(ProductCategory, on_delete=models.CASCADE)

# each inventory item can have its own address. Default is sellers address.
class InventoryItemAddress(models.Model):
    item_id = models.OneToOneField(Inventory, on_delete=models.CASCADE)
    address = models.CharField(max_length=126)
    city = models.CharField(max_length=64)
    state = models.CharField(max_length=64)
    country = models.CharField(max_length=64, default="India")
    postal_code = models.CharField(max_length=18)
    latitude = models.FloatField(max_length=18)
    longitude = models.FloatField(max_length=18)

class Vehicle(models.Model):
    vehicle_id = models.AutoField(primary_key=True)
    vehicle_name = models.CharField(max_length=40, unique=True)

# transporters have an id, their transportation capacity, and what they're willing to transport.
# TODO:
# transporting capacity must be a positive floating point value. Impose the restriction in the model definition

class Transporter(models.Model):
    transporter_id = models.ForeignKey(Users, on_delete=models.CASCADE)
    capacity = models.DecimalField(max_digits=9, decimal_places=0)
    measuring_unit = models.ForeignKey(MeasuringUnit, on_delete=models.CASCADE)
    vehicle = models.ForeignKey(Vehicle, on_delete=models.CASCADE)

    class Meta:
        unique_together = ("transporter_id", "vehicle")


from pathlib import Path
from prefect.task_runners import SequentialTaskRunner
from prefect_dbt_flow import dbt_flow
from prefect_dbt_flow.dbt import DbtProfile, DbtProject

my_dbt_flow = dbt_flow(
    project=DbtProject(
        name="sample_project",
        project_dir=Path() / "prefect_demo",
        profiles_dir=Path.home() / ".dbt",
    ),
    profile=DbtProfile(
        target="prod",
    ),
    flow_kwargs={
        "task_runner": SequentialTaskRunner(),
    },
)

if __name__ == "__main__":
    my_dbt_flow()


# -*- coding: utf-8 -*-
import heapq
import heapq_max
'''
The goal of this problem is to implement a variant of the 2-SUM algorithm (covered in the Week 6 lecture on hash table applications).
The file contains 1 million integers, both positive and negative (there might be some repetitions!).This is your array of integers, with the ith row of the file
specifying the ith entry of the array.
Your task is to compute the number of target values t in the interval [-10000,10000] (inclusive) such that there are distinct numbers x,y in the input file that
satisfy x+y=t. (NOTE: ensuring distinctness requires a one-line addition to the algorithm from lecture.)
Write your numeric answer (an integer between 0 and 20001) in the space provided.
OPTIONAL CHALLENGE: If this problem is too easy for you, try implementing your own hash table for it. For example, you could compare performance under the chaining
and open addressing approaches to resolving collisions.
# our two sum function which will return
# all pairs in the list that sum up to S
def twoSum(arr, S):
'''
'''
The goal of this problem is to implement the "Median Maintenance" algorithm (covered in the Week 5 lecture on heap applications). The text file contains a list of the integers from 1 to
10000 in unsorted order; you should treat this as a stream of numbers, arriving one by one. Letting xi denote the ith number of the file, the kth median mk is defined as the median of the
numbers x1,…,xk. (So, if k is odd, then mk is ((k+1)/2)th smallest number among x1,…,xk; if k is even, then mk is the (k/2)th smallest number among x1,…,xk.)
In the box below you should type the sum of these 10000 medians, modulo 10000 (i.e., only the last 4 digits). That is, you should compute (m1+m2+m3+⋯+m10000)mod10000.
OPTIONAL EXERCISE: Compare the performance achieved by heap-based and search-tree-based implementations of the algorithm.
'''

def twoSum(numbers):
    answerCounter = 0
    searchRange = set(range(-10000, 10001))
    for i in searchRange:
        if any(i - x in numbers and 2 * x != i for x in numbers):
            answerCounter += 1
            print("found")
    return answerCounter

def medianMaintenance(numbers):
    medians = []
    minHeap = []
    maxHeap = []
    minimum = min(numbers[0], numbers[1])
    maximum = max(numbers[0], numbers[1])
    heapq_max.heappush_max(minHeap, minimum)
    heapq.heappush(maxHeap, maximum)
    medians.append(maximum)
    medians.append(minimum)
    for number in numbers[2:]:
        if number < maxHeap[0]:
            heapq_max.heappush_max(minHeap, number)
        else:
            heapq.heappush(maxHeap, number)
        while abs(len(minHeap) - len(maxHeap)) >= 2:
            if len(minHeap) > len(maxHeap):
                item = heapq_max.heappop_max(minHeap)
                heapq.heappush(maxHeap, item)
            elif len(minHeap) < len(maxHeap):
                item = heapq.heappop(maxHeap)
                heapq_max.heappush_max(minHeap, item)
        if (len(minHeap) + len(maxHeap)) % 2 != 0:
            if len(minHeap) > len(maxHeap):
                medians.append(minHeap[0])
            else:
                medians.append(maxHeap[0])
        else:
            medians.append(minHeap[0])
    print(sum(medians) % 10000)

if __name__ == '__main__':
    def generateListTwoSum():
        with open('algo1-programming_prob-2sum.txt') as file:
            return set([int(line) for line in file])

    def generateListMedian():
        with open('Median.txt') as file:
            return [int(line) for line in file]

    numbers = generateListMedian()
    medianMaintenance(numbers)
    # print(twoSum(numbers))


#Tạo  class chứa thông tin của học sinh sau đó có thể thêm học sinh vào và gọi ra.
class Student:
	def __init__(self, name, age, math_score, literature_score):
		self.name = name
		self.age = age
		self.math_score = math_score
		self.literature_score = literature_score
		self.teacher = "DungLai"

	def average_score(self):
		ave_score = (self.math_score + self.literature_score)/2
		return ave_score

	def print_info(self):
		ave = str(self.average_score()) #gọi hàm trong hàm của 1 class
		print("Student name: "  + self.name + " " + str(self.age) + " years old " + " study with " + self.teacher + " have average score: " + ave)

#create
students = []
s1 = Student("Man", 21, 6, 8)
s2 = Student("Women", 22, 8, 9)
s3 = Student("Kid", 23, 4, 7)
#insert
s2.teacher = "Jean"
#add three student 1 2 3 into list student
students.append(s1)
students.append(s2)
students.append(s3)

for i in range(len(students)):
	students[i].print_info()


from fastapi import APIRouter,HTTPException
from pydantic import BaseModel

#El prefix funciona para definir el prefijo de la ruta que se está trabajando y refactorizar el código. El tag sirve para clasificar la ruta en la documentación SwaggerUI#
routes = APIRouter(prefix= "/users",
                   tags=["users"])

class User(BaseModel): #Esto es un BaseModel#
    name: str
    surname:str
    nickname:str

users_list = [
    User(name ="Cesar",surname="Villanueva",nickname="Lordchief"),
    User(name ="Tanjiro",surname="Kamado",nickname="FireDancer"),
    User(name ="Nezuko",surname="Kamado",nickname="GoodDemon"),
    User(name ="Zenitsu",surname="Agatsuma",nickname="BoostRain"),
    User(name ="Inosuke",surname="Hashibira",nickname="LordAnimal")
]

@routes.get("/")
async def usersForAPI():
    return users_list

@routes.get("/{name}") #Pasar parámetro por medio de una ruta #
async def user(name: str):
    usuario = filter(lambda user: user.name == name, users_list)
    try:
        return list(usuario)[0]
    except:
        return {"MessageError": "No se encontró el usuario"}

@routes.post("/", status_code=200)
async def user(user: User):

    if type(users_validate(user.name)) == User :
        raise HTTPException(409,{"Message": "El usuario ya existe"}) # Usamos el raise que para que suba la excepción al status code de la ruta#
    else:
        users_list.append(user)
        return {"Message": "El usuario se creó correctamente"}

@routes.put("/update")
async def changeInfoUser(user: User):
    found = False
    for index, saved_user in enumerate(users_list):
        if saved_user.name == user.name:
            users_list[index] = user
            found = True
            return {"Message": "Usuario actualizado con éxito"}
    if not found:
        return {"Message": "No se ha actualizado el usuario"}

@routes.delete("/delete/{name}")
async def deleteUser(name: str):
    found = False
    for index, user_saved in enumerate(users_list):
        if user_saved.name == name:
            del users_list[index]
            found = True
            return {"Message": "Usuario eliminado con éxito"}
    if not found:
         return {"Message": "No se ha eliminado el usuario"}

def users_validate(name: str):
    usuario = filter(lambda user: user.name == name, users_list)
    try:
        return list(usuario)[0]
    except:
        return {"MessageError": "No se encontró el usuario"}


#!/usr/bin/python3

import re

from argparse import ArgumentParser
from shutil import copy2 as copy_file
from os import remove as delete_file

LAYER_REGEX = re.compile(r"G[0|1] .*Z([\d,\.]+).* ; move to next layer \((.+)\)")  # noqa: E501

def get_filename_from_commannd_line():
    parser = ArgumentParser(description="Adds a layer count to a G-Code file.")
    parser.add_argument("filename", type=str, help="path to the gcode file")

    args = parser.parse_args()
    return args.filename

def count_layers(path):
    layers_found = 0
    with open(path, 'r') as f:
        for line in f:
            if LAYER_REGEX.match(line):
                layers_found += 1
    return layers_found

if __name__ == '__main__':
    filename = get_filename_from_commannd_line()
    backupname = f"{filename}.bak"

    # Count the layers
    layercount = count_layers(filename)

    # Create a backup
    copy_file(filename, backupname)

    # Process file
    with open(backupname, "r") as src:
        with open(filename, "w") as dest:
            for line in src:
                match = LAYER_REGEX.match(line)
                if match:
                    z_height = float(match.group(1))
                    z_layer = int(match.group(2)) + 1
                    percent = round(z_layer / layercount * 100, 1)
                    dest.write(f"M117 {z_layer}/{layercount} ({percent}%) {z_height}mm\n")  # noqa: E501
                dest.write(line)

    # Delete backup
    delete_file(backupname)


from flask import *
from flask_login import login_user, logout_user, login_required, login_fresh, current_user
from .models import *
from .tableutil import *
from .main import getLang, getStrings
from werkzeug.security import check_password_hash
import os
import httpx
import subprocess

ota = Blueprint('ota', __name__)

@ota.route("/update", methods=["GET"])
@login_required
def update():
    if current_user.role == "admin":
        lang = getLang().lower()
        strings = getStrings(lang)
        r = httpx.get("https://api.github.com/repos/MeetPlan/MeetPlan/releases")
        print(r.json()[0])
        return render_template("ota.html", release=r.json()[0], strings=strings, role=current_user.role, name=current_user.first_name)
    else:
        abort(403)

@ota.route("/update", methods=["POST"])
@login_required
def updatePost():
    if current_user.role == "admin":
        lang = getLang().lower()
        strings = getStrings(lang)
        process = subprocess.Popen(["git", "pull"], stdout=subprocess.PIPE)
        output = process.communicate()[0].decode()
        print(output)
        if ('up to date' in output):
            print("UP TO DATE")
            flash(strings["UP_TO_DATE"])
            return redirect(url_for("ota.update"))
        elif ("Updating" in output):
            flash(strings["UPDATE_SUCCESSFUL"])
            return redirect(url_for("ota.update"))
        #return render_template("ota.html", release=r.json()[0], strings=strings)
    else:
        abort(403)


from .base import GnuRecipe
from .graphviz import GraphVizRecipe

class DotRecipe(GnuRecipe):
    def __init__(self, *args, **kwargs):
        super(DotRecipe, self).__init__(*args, **kwargs)
        self.name = 'dot'
        graphviz = GraphVizRecipe(settings=self)
        self.sha256 = graphviz.sha256
        self.version = graphviz.version
        self.url = graphviz.url
        self.depends = ['fontconfig', # for fonts
                        'libgd'  # for png
                       ]
        self.documentation = 'graphviz without all the dependencies for' \
                             ' building documentation'
        self.configure_args += ['--without-x',
                                '--disable-swig',
                                '--without-glut',
                                '--with-libgd=no']
    def post_install(self):
        super(DotRecipe, self).post_install()
        self.run_exe(['dot', '-c'], self.directory, self.environment)


import os

import numpy as np
from PIL import Image
from sklearn.preprocessing import LabelBinarizer
from torch.utils import data
from torchvision.transforms import transforms

class BaseDataset(data.Dataset):
    def __init__(self, path, dataset, mode='train', seed=7548):
        np.random.seed(seed)

        self.path = os.path.join(path, dataset, 'NormIm')
        self.mode = mode

        self.enc = None

        with open(os.path.join(path, dataset, mode + '.txt'), 'r') as f:
            self.img_list = [
                tuple(line.strip().split(' ')) for line in f.readlines()
            ]
            label_list = sorted(list(set([item[1] for item in self.img_list])))

        if mode == 'train':
            np.random.shuffle(self.img_list)
        self.label_list = sorted(label_list)

        self.enc = LabelBinarizer()
        self.enc.fit(self.label_list)

        self.transform = transforms.Compose([
            transforms.Resize((64, 512)),
            transforms.ToTensor(),
        ])

    def __len__(self):
        return len(self.img_list)

    @property
    def class_num(self):
        return len(self.label_list)

    def __getitem__(self, item):
        img_name, label = self.img_list[item]
        img = Image.open(os.path.join(
            self.path, img_name)).convert("L")
        img = self.transform(img)
        label_vec = self.enc.transform([label])
        return img, label, label_vec, img_name


import pickle
import cv2
import os

#os.mkdir('tests')

test = 'Biking/v_Biking_g08_c06'
#video input
cap = cv2.VideoCapture('train/'+test+'.avi')

with open('pyannot.pkl','rb') as f:
    x = pickle.load(f)

anno = x[test]['annotations'][0]
boxes = anno['boxes']

sf = anno['sf']
ef = anno['ef']

print('starting frame %d, ending frame %d'%(sf,ef))

c = 0
while(cap.isOpened()):
    ret, frame = cap.read()

    if c>=ef:
       break
    elif c<sf:
       c+=1
       continue
    else:
       box = boxes[c]
       im_box = cv2.rectangle(frame, (box[0],box[1]),(box[0]+box[2],box[1]+box[3]), (255,0,0), 2)
       cv2.imwrite('tests/im_{}_f-{}.jpg'.format(c,sf+c),im_box)
       c+=1

Learning Spatio-Temporal Classification and Localization/bbox_test_from_vid.py


import sys
import time
import traceback
import urllib.parse
from contextlib import contextmanager
from enum import auto, Enum
from io import BytesIO
from typing import (
    Callable,
    ContextManager,
    Dict,
    FrozenSet,
    Iterable,
    Iterator,
    Mapping,
    NamedTuple,
    Optional,
    Union,
)

import requests
from antlir.common import get_logger, retryable
from antlir.rpm.common import DecorateContextEntry, RpmShard
from antlir.rpm.db_connection import DBConnectionContext
from antlir.rpm.open_url import open_url
from antlir.rpm.repo_db import RepoDBContext, StorageTable
from antlir.rpm.repo_objects import Checksum, Repodata, RepoMetadata, Rpm
from antlir.rpm.repo_snapshot import FileIntegrityError, HTTPError, MaybeStorageID
from antlir.rpm.storage import Storage
from antlir.rpm.yum_dnf_conf import YumDnfConfRepo

# We'll download data in 512KB chunks. This needs to be reasonably large to
# avoid small-buffer overheads, but not too large, since we use `zlib` for
# incremental decompression in `parse_repodata.py`, and its API has a
# complexity bug that makes it slow for large INPUT_CHUNK/OUTPUT_CHUNK.
BUFFER_BYTES = 2**19
DB_MAX_RETRY_S = [2**i for i in range(8)]  # 255 sec == 4m15s
log = get_logger()

class LogOp(Enum):
    RPM_DOWNLOAD = auto()
    DETECT_MUTABLE_RPMS = auto()
    REPO_DB_WRITE = auto()
    RPM_QUERY = auto()
    REPO_DOWNLOAD = auto()

    def __str__(self) -> str:
        return str(self.name)

def _is_retryable_mysql_err(e: Exception) -> bool:  # pragma: no cover
    # Want to catch MySQLdb.OperationalError, which indicates a potentially
    # transient error, but don't want to import MySQLdb here, as it isn't a
    # dependency of this module otherwise. This approach is tested in
    # rpm/facebook/tests/test_fb_rpm_downloader.py
    return (
        type(e).__module__ == "MySQLdb._exceptions"
        and type(e).__qualname__ == "OperationalError"
    )

def retryable_db_ctx(
    db_conn: DBConnectionContext,
) -> ContextManager[RepoDBContext]:
    return DecorateContextEntry(
        RepoDBContext(db_conn, db_conn.SQL_DIALECT),
        retryable(
            "DB connection error",
            DB_MAX_RETRY_S,
            is_exception_retryable=_is_retryable_mysql_err,
        ),
    )

# Lightweight configuration used by various parts of the download
class DownloadConfig(NamedTuple):
    db_cfg: Dict[str, str]
    storage_cfg: Dict[str, str]
    rpm_shard: RpmShard
    threads: int

    def new_db_conn(
        self, *, readonly: bool, force_master: bool = True
    ) -> DBConnectionContext:
        assert "readonly" not in self.db_cfg, "readonly is picked by the caller"
        assert "force_master" not in self.db_cfg, "force_master is picked by the caller"
        # pyre-fixme [9]: Technically could be any `Pluggable`, but we use it as
        # a DBConnectionContext
        conn_ctx: DBConnectionContext = DBConnectionContext.from_json(
            {**self.db_cfg, "readonly": readonly, "force_master": force_master}
        )
        return conn_ctx

    def new_db_ctx(self, **kwargs) -> ContextManager[RepoDBContext]:
        return retryable_db_ctx(self.new_db_conn(**kwargs))

    def new_storage(self):
        return Storage.from_json(self.storage_cfg)

# Gets incrementally populated throughout repo downloading; used to carry info
# through the concurrent downloads until the final repo snapshot is built
class DownloadResult(NamedTuple):
    repo: YumDnfConfRepo
    repo_universe: str
    repomd: RepoMetadata
    # Below 3 params are populated incrementally after the initial 3
    storage_id_to_repodata: Optional[Mapping[MaybeStorageID, Repodata]] = None
    storage_id_to_rpm: Optional[Mapping[MaybeStorageID, Rpm]] = None
    rpms: Optional[FrozenSet[Rpm]] = None

def verify_chunk_stream(
    chunks: Iterable[bytes],
    checksums: Iterable[Checksum],
    size: int,
    location: str,
):
    actual_size = 0
    hashers = [ck.hasher() for ck in checksums]
    for chunk in chunks:
        actual_size += len(chunk)
        for hasher in hashers:
            hasher.update(chunk)
        yield chunk
    if actual_size != size:
        raise FileIntegrityError(
            location=location,
            failed_check="size",
            expected=size,
            actual=actual_size,
        )
    for hash, ck in zip(hashers, checksums):
        if hash.hexdigest() != ck.hexdigest:
            raise FileIntegrityError(
                location=location,
                failed_check=ck.algorithm,
                expected=ck.hexdigest,
                actual=hash.hexdigest(),
            )

def _log_if_storage_ids_differ(obj, storage_id, db_storage_id) -> None:
    if db_storage_id != storage_id:
        log.warning(f"Another writer already committed {obj} at {db_storage_id}")

def log_size(what_str: str, total_bytes: float) -> None:
    log.info(f"{what_str} {total_bytes/10**9:,.4f} GB")

@contextmanager
def timeit(callback: Callable):
    """`callback` should be a function that accepts kwargs `duration_s` and `error`,
    which will be called when the context manager exits.
    """
    start_t = time.time()
    try:
        yield
    finally:
        duration = time.time() - start_t
        callback(
            duration_s=duration,
            error=traceback.format_exc() if any(sys.exc_info()) else None,
        )

@contextmanager
def download_resource(repo_url: str, relative_url: str) -> Iterator[BytesIO]:
    if not repo_url.endswith("/"):
        repo_url += "/"  # `urljoin` needs a trailing / to work right
    assert not relative_url.startswith("/")
    try:
        with open_url(urllib.parse.urljoin(repo_url, relative_url)) as input:
            yield input
    except requests.exceptions.HTTPError as ex:
        # E.g. we can see 404 errors if packages were deleted
        # without updating the repodata.
        #
        # Future: If we see lots of transient error status codes
        # in practice, we could retry automatically before
        # waiting for the next snapshot, but the complexity is
        # not worth it for now.
        raise HTTPError(location=relative_url, http_status=ex.response.status_code)

# Note that we use this function serially from the master thread after
# performing the downloads. This is because it's possible for SQLite to run
# into locking issues with many concurrent writers. Additionally, these writes
# are a minor portion of our overall execution time and thus we see negligible
# perf gains by parallelizing them.
def maybe_write_id(
    repo_obj: Union[Repodata, Rpm],
    storage_id: str,
    table: StorageTable,
    db_conn: DBConnectionContext,
) -> str:
    """Used to write a storage_id to repo_db after a download."""
    with retryable_db_ctx(db_conn) as repo_db_ctx:
        db_storage_id = repo_db_ctx.maybe_store(table, repo_obj, storage_id)
        repo_db_ctx.commit()
    _log_if_storage_ids_differ(repo_obj, storage_id, db_storage_id)
    return db_storage_id


def prefixToPostfix(prefixes):
    operators = ['+','-','/','*']
    res = []
    for prefix in prefixes:
        p = list(prefix)
        r = []
        l = len(p)
        for i in range(l-1,-1,-1):
            if p[i] in operators:
                operand1 = r[-1]
                r.pop()
                operand2 = r[-1]
                r.pop()
                r.append(operand1 + operand2 + p[i])
            else:
                r.append(p[i])
        res.append(r)
    return res

print(prefixToPostfix(['*34','+1*23','+12']))