import logging
from math import log

import numpy as np
from sklearn.model_selection import RepeatedStratifiedKFold
from enum import Enum
from src.model.aggregation import AggregationType

class SplitType(Enum):
    Random = 1
    Bootstrap = 2
    Model = 3

class Sampler:

    def __init__(self, data, n_splits=10, sample_complexity=100, seed=None, k=10):
        """
            Parameters
            ----------
            n_splits : Integer
                Number of Devices to distribute the data onto, i.e., the number of Splits to be generated

            See Also
            --------

            Notes
            -----
            This Class manages the data splits and is usually called when calling the train method in any PGM Object.
            You can create your own Split Object and pass it to the PGM Object. Otherwise, a default Split Object with a random split
            using 10 devices will be created. You may adjust the default split at any time by calling the respective methods.

            Examples
            --------
            from src.conf.modes.splits import Splits

            my_split = Splits(devices = 100)
            my_split.set_mode(Splits.corr)
            my_split.create_split()

        """

        self.random_state = np.random.RandomState(seed)
        self.data = data
        self.seed = seed

        if self.n_splits is None:
            self.n_splits = n_splits

        self.k_fold = k

        if self.mode is None:
            self.mode = SplitType.Random

        self.sample_complexity = sample_complexity
        self.split_idx = None

        self.data_dim = data.train.shape[1]

        self.options = {AggregationType.Mean: self.dummy,
                        AggregationType.WeightedAverage: self.dummy,
                        AggregationType.TukeyDepth: self.dummy,
                        AggregationType.WassersteinBarycenter: self.dummy
                        }

    def dummy(self):
        return None

    def set_mode(self, mode=SplitType.Random):
        """
                Set Split Mode according to existing Enum Members of src.conf.modes.Splits
        """
        self.mode = mode

    def create_split(self, shape, data=None):
        """
            Parameters
            ----------
            shape : Tuple(Integer, Integer)
                Tuple-Object representing the size of the data set usually (rows, cols)

            data : :class:`pandas.DataFrame`
                Either a DataFrame or Numpy Array containing the training data. The data parameter is necessary if a mode is chosen, that
                depends on the data to generate a proper split.

            Notes
            -----
                Creates a Split as collection of numpy arrays, which can be used to index an existing data frame of given shape and size.
            """
        if data is not None:
            try:
                shape = data.shape
            except AttributeError:
                logging.error(
                    "Unable to create split, data was not provided in a valid format. Please use either Pandas Dataframes or Numpy Arrays")

        if self.mode == SplitType.Random:
            self._random(shape)
        elif self.mode == SplitType.Bootstrap:
            if data is None:
                logging.info("Falling back to random split. Data needs to be provided for a data-based Split")
                self._random(shape)
            else:
                self._bootstrap(data)
        else:
            logging.info("Invalid or Unknown Split Type. Falling back to random split")
            self._random(shape)

    def split(self):
        yield from self.split_idx

    def stratified_split(self):
        return self.rskf.split(self.dataset, self.labels)

    def _random(self, shape):
        split = np.arange(shape[0])
        self.random_state.shuffle(split)
        self.split_idx = np.array_split(split, self.n_splits)

    def _stratified(self):
        self.labels = self.data.data[self.data.label_column]
        self.dataset = self.data.data.drop(self.data.label_column, axis=1)
        self.rskf = RepeatedStratifiedKFold(n_splits=self.k_fold, n_repeats=1, random_state=self.seed[0])

    def _bootstrap(self, data):
        total_samples = self.sample_complexity * self.n_splits
        data_idx = np.arange(data.shape[0])
        choices = self.random_state.choice(a=data_idx , size=total_samples, replace=True).reshape(self.n_splits, self.sample_complexity)
        self.split_idx = choices

    def _model(self, models):
        local_dist_samples = []
        for model in models:
            mu = np.mean(model, axis=0)
            cov = np.cov(model)
            samples = self.random_state.multivariate_normal(mu, cov, self.sample_complexity)
            local_dist_samples.append(samples)

    def _split_corr(self, data):
        pass

class Random(Sampler):

    def __init__(self, data, n_splits=10, sample_complexity=100, seed=None, k=10):
        self.n_splits = n_splits
        self.mode = SplitType.Random
        super(Random, self).__init__(data, n_splits, sample_complexity, seed, k)

class Bootstrap(Sampler):

    def __init__(self, data, n_splits=10, sample_complexity=100, seed=None, k=10):
        self.n_splits = n_splits
        self.mode = SplitType.Bootstrap
        super(Bootstrap, self).__init__(data, n_splits, sample_complexity, seed, k)

class Model(Sampler):

    def __init__(self, data, n_splits=10, sample_complexity=100, seed=None, k=10):
        self.n_splits = n_splits
        self.mode = SplitType.Model

        super(Model, self).__init__(data, n_splits, sample_complexity, seed, k)


import threading
import json

import webapp2
import httplib2
from oauth2client import crypt, client

_cached_http = httplib2.Http(client.MemoryCache())

def verify_id_token(id_token, audience, http=None,
                    cert_uri=client.ID_TOKEN_VERIFICATON_CERTS):
    """Verifies a signed JWT id_token.

    This function requires PyOpenSSL and because of that it does not work on
    App Engine.

    Args:
      id_token: string, A Signed JWT.
      audience: string, The audience 'aud' that the token should be for.
      http: httplib2.Http, instance to use to make the HTTP request. Callers
        should supply an instance that has caching enabled.
      cert_uri: string, URI of the certificates in JSON format to
        verify the JWT against.

    Returns:
      The deserialized JSON in the JWT.

    Raises:
      oauth2client.crypt.AppIdentityError if the JWT fails to verify.
    """
    if http is None:
        http = _cached_http

    resp, content = http.request(cert_uri)

    if resp.status == 200:
        certs = json.loads(content)
        return crypt.verify_signed_jwt_with_certs(id_token, certs, audience)
    else:
        raise client.VerifyJwtTokenError('Status code: %d' % resp.status)

def get_current_user():
    """  GAE compatibility method. """
    request = webapp2.get_request()
    app = webapp2.get_app()
    audience = app.config.get('idtoken_audience')
    if not audience:
        raise Exception('idtoken_audience not configured')
    token = request.headers.get('x-w69b-idtoken')
    return _user_from_token(token, audience)

class User(object):
    """ Appengine User compatible User class. """

    def __init__(self, email=None, _user_id=None):
        self._email = email
        self._user_id = _user_id

    def email(self):
        return self._email

    def nickname(self):
        return self.email()

    def user_id(self):
        return self._user_id

def _user_from_token(token, audience):
    """ Returns User object or None if token is not valid or None. """
    if token is None:
        return None
    try:
        verified_token = verify_id_token(token, audience)
        return User(email=verified_token['email'],
                    _user_id=verified_token['sub'])
    except (crypt.AppIdentityError, KeyError):
        return None

class Decorator(object):
    """
    Provides user_aware decorator that gives access to user as
    decorator.user (None it not authenticated)

    """

    def __init__(self, audience):
        self._thread_local_store = threading.local()
        self.audience = audience
        self._header_name = 'x-w69b-idtoken'

    @property
    def user(self):
        return getattr(self._thread_local_store, 'user', None)

    @user.setter
    def user(self, user):
        self._thread_local_store.user = user

    def user_aware(self, method):
        """
        Provides decorator.user object that for request handler methods
        that use this decorator. The property is None if no user is
        authenticated.
        """

        def setup_user(request_handler, *args, **kwargs):
            token = request_handler.request.headers.get(self._header_name)
            self.user = _user_from_token(token, self.audience)
            try:
                resp = method(request_handler, *args, **kwargs)
            finally:
                self.user = None
            return resp

        return setup_user


import unittest

def countingSubDomainClicks(domain_counts):
    click_map = {}

    for click_domain in domain_counts:
        click_count = int(click_domain.split(",")[0])
        domain = click_domain.split(",")[1]
        domain_parts = domain.split(".")
        subdomains = []

        for i in range(len(domain_parts)):
            subdomains.append(".".join(domain_parts[i:]))

        for subdomain in subdomains:
            if subdomain not in click_map:
                click_map[subdomain] = click_count
            else:
                click_map[subdomain] += click_count

    return click_map

class test(unittest.TestCase):
    def test_one(self):
        domain_counts = ["900,google.com", "60,mail.yahoo.com", "10,mobile.sports.yahoo.com", "40,sports.yahoo.com", "300,yahoo.com",
                         "10,stackoverflow.com", "20,overflow.com", "5,com.com", "2,en.wikipdia.org", "1,m.wikipedia.org", "1,mobile.sports", "1,google.co.uk"]
        click_map = {'google.com': 900, 'com': 1345, 'mail.yahoo.com': 60, 'yahoo.com': 410, 'mobile.sports.yahoo.com': 10, 'sports.yahoo.com': 50, 'stackoverflow.com': 10, 'overflow.com': 20, 'com.com': 5,
                         'en.wikipdia.org': 2, 'wikipdia.org': 2, 'org': 3, 'm.wikipedia.org': 1, 'wikipedia.org': 1, 'mobile.sports': 1, 'sports': 1, 'google.co.uk': 1, 'co.uk': 1, 'uk': 1}
        self.assertEqual(click_map, countingSubDomainClicks(domain_counts))

if __name__ == '__main__':
    unittest.main()


import numpy as np
import os
import pandas as pd
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.model_selection import cross_val_score, cross_val_predict, StratifiedKFold, LeaveOneOut
from sklearn.metrics import roc_auc_score

def getFeaturesAndLabels(reref, pp, epoch, target, repetitions, win_length, step):
   # Define paths
   feature_path = 'PreprocessedData/Features/{}/'.format(pp)
   label_path = 'PreprocessedData/Labels/'

   # Load data
   features = np.load(feature_path + '{}_{}_features_{}_w{}_st{}.npy'.format(pp, reref, epoch, win_length, step))
   labelsDF = pd.read_pickle(label_path + '{}_labels.pkl'.format(pp))

   # Deal with NaN values
   if target == 'decision':
      labelsDF.dropna(inplace=True)

   elif target == 'accuracy':
      labelsDF.dropna(inplace=True)
      labelsDF.reset_index(drop=True, inplace=True)

   elif target == 'stimulus_category':
      if labelsDF[target].sum() < labelsDF.shape[0]/2:
         labelsDF[target].fillna(1, inplace=True)
      else:
         labelsDF[target].fillna(0, inplace=True)

   # Extract features of interest (based on repetition selected)
   indices = labelsDF.index[labelsDF.repetition.isin(repetitions)].to_numpy()
   features = features[indices,:,:]

   # Define Labels of interest
   labels = labelsDF[target][labelsDF.repetition.isin(repetitions)].astype(int).to_numpy()
   r_name = ','.join([str(x) for x in repetitions])

   return features, labels, r_name

def permTest(features, labels, n_permutations=1000, cv_method='LeaveOneOut'):
   dim = features.shape[-2]
   n_wind = features.shape[1]

   score_perms = np.zeros((dim,n_permutations))
   error_perms = np.zeros((dim,n_permutations))

   for i in range(dim):
      for perm in range(n_permutations):
      # Permute labels
         permuted_labels = np.random.permutation(labels)
         random_wind = np.random.choice(n_wind) # select a random window

         X = features[:,random_wind,i,:]

         # Define Classifier, run Crossvalidation for permuted labels dataset
         clf = LinearDiscriminantAnalysis(solver='lsqr', shrinkage='auto')

         # Define cross validation method to use
         if cv_method == 'LeaveOneOut':
            cv = LeaveOneOut()
            CV_pred = cross_val_predict(clf, X, permuted_labels, cv=cv)
            score_perms[i,perm] = roc_auc_score(permuted_labels, CV_pred)

         elif cv_method == 'KFold':
            cv = StratifiedKFold(n_splits=5)
            perm_scores_env = cross_val_score(clf, X, permuted_labels, cv=cv, scoring="roc_auc", error_score='raise')

            # Store permuted scores, stds
            score_perms[i,perm] = perm_scores_env.mean()
            error_perms[i,perm] = perm_scores_env.std()

   if cv_method == 'LeaveOneOut':
      return score_perms

   elif cv_method == 'KFold':
      return score_perms, error_perms

def classifier(features, labels, cv_method='LeaveOneOut'):
   dim = features.shape[-2]
   n_wind = features.shape[1]

   score_means = np.zeros((dim,n_wind))
   errors = np.zeros((dim,n_wind))

   # Run Classifier for each channel and for each window
   clf = LinearDiscriminantAnalysis(solver='lsqr', shrinkage='auto')
   for i in range(dim):
      for w in range(n_wind):
         X = features[:,w,i,:]

   # Define cross validation method to use
         if cv_method == 'LeaveOneOut':
            cv = LeaveOneOut()
            CV_pred = cross_val_predict(clf, X, labels, cv=cv)
            score_means[i,w] = roc_auc_score(labels, CV_pred)

         elif cv_method == 'KFold':
            cv = StratifiedKFold(n_splits=5)
            CV_scores = cross_val_score(clf, X, labels, cv=cv, scoring='roc_auc')

            score_means[i,w] = CV_scores.mean()
            errors[i,w] = CV_scores.std()

   if cv_method == 'LeaveOneOut':
      return score_means

   elif cv_method == 'KFold':
      return score_means, errors

def estimatePVals(score_perms, score_means):
   dim = features.shape[-2]
   n_wind = features.shape[1]

   # Get p-values
   p_vals = np.zeros((dim,n_wind))

   for i in range(dim):
      for w in range(n_wind):
         p_vals[i,w] = np.count_nonzero(score_perms[i] > score_means[i,w]) / len(score_perms[i])

   # Estimate significant threshold and significant channels
   score_perms_sorted = np.sort(score_perms)
   threshold = np.zeros((dim,6))
   significant_indices = []
   for i in range(dim):
      threshold[i] = np.percentile(score_perms_sorted[i], q=[0.1, 1, 5, 95, 99, 99.9])
      significant_indices.append(np.arange(n_wind)[score_means[i] > threshold[i][3]])
   significant_indices = np.array(significant_indices, dtype=object)
   return p_vals, threshold, significant_indices

if __name__=="__main__":
   reref='ESR'
   epoch = 'long_stim'
   target = 'decision'
   repetitions = [1]
   PPs = ['p01', 'p02', 'p03', 'p04', 'p05']
   cv_method = 'LeaveOneOut'  #'KFold'
   significant_indices_epoch = 'stimulus'
   only_significant_indices = True
   permutation = True
   n_permutations = 1000
   win_length = 0.1
   step = 0.05

   for pp in PPs:
   # Define OutPath
      out_path = 'DecodingResults/{}/{}/{}/{}/'.format(reref, epoch, target, pp)
      if not os.path.exists(out_path):
         os.makedirs(out_path)

   # Get features and labels
      features, labels, r_name = getFeaturesAndLabels(reref, pp, epoch, target, repetitions, win_length, step)

      if only_significant_indices == True:
      # Get significant indices
         significant_indices = np.load('DecodingResults/{}/{}/{}/{}/{}_decoder_{}_{}_permTest.npz'.format(reref, significant_indices_epoch, target, pp, pp, r_name, cv_method))['significant_indices']

      # Subselect only feautures from significant channels
         features = features[:,:,significant_indices,:]

   # Run classifier
      if cv_method == 'LeaveOneOut':
         score_means = classifier(features, labels, cv_method=cv_method)
      elif cv_method == 'KFold':
         score_means, errors = classifier(features, labels, cv_method=cv_method)

   # Save classifier scores
      if cv_method == 'LeaveOneOut':
         np.savez(out_path + '{}_decoder_{}_w{}_st{}_{}_onlySign'.format(pp, r_name, win_length, step, cv_method),
               score_means=score_means
               )
      elif cv_method == 'KFold':
         np.savez(out_path + '{}_decoder_{}_w{}_st{}_{}_onlySign'.format(pp, r_name, win_length, step, cv_method),
               score_means=score_means,
               errors=errors
               )

      if permutation == True:
      # Run permutation test
         if cv_method == 'LeaveOneOut':
            score_perms = permTest(features, labels, n_permutations=n_permutations, cv_method=cv_method)
         elif cv_method == 'KFold':
            score_perms, error_perms = permTest(features, labels, n_permutations=n_permutations, cv_method=cv_method)

      # Estimate significance threshold and p_vals
         p_vals, threshold, significant_indices = estimatePVals(score_perms, score_means)

      # Save permTest data
         if cv_method == 'LeaveOneOut':
            np.savez(out_path + '{}_decoder_{}_w{}_st{}_{}_permTest_onlySign'.format(pp, r_name, win_length, step, cv_method),
               score_perms=score_perms,
               p_vals=p_vals,
               threshold=threshold,
               significant_indices=significant_indices
               )
         elif cv_method == 'KFold':
            np.savez(out_path + '{}_decoder_{}_w{}_st{}_{}_permTest_onlySign'.format(pp, r_name, win_length, step, cv_method),
               score_perms=score_perms,
               error_perms=error_perms,
               p_vals=p_vals,
               threshold=threshold,
               significant_indices=significant_indices
               )


from cgitb import html
import argparse, inspect, json, time, requests, re, spotipy, configparser, logging, sys
from fileinput import filename
from glob import glob
from pydoc import doc
from bs4 import BeautifulSoup
from difflib import SequenceMatcher
from datetime import datetime
from spotipy.oauth2 import SpotifyOAuth

class LaiterieScrapper:
    laiterie_url = 'https://www.artefact.org/la-laiterie/programmation'

    def scrap_url(self, pager):
        html_text = handle_http_request('GET', self.laiterie_url + '?p=' + str(pager)).text
        global soup
        soup = BeautifulSoup(html_text, 'html.parser')
        if not soup.find_all(class_="liste-wp"):
            return False
        return True

    def get_artists(self):
        logging.info("Scrapping artists...")
        pager = 1
        artists = []
        while (self.scrap_url(pager)):
            pager += 1
            for artist in soup.find_all(class_='artiste tete-affiche'):
                p = artist.find_parent(class_='event-block with-image table-row')
                s = p.find(class_='statut')
                if not p or not s or 'Annulé' not in s.text:
                    artists.append((re.sub(
                        '(?i)(([\"«].*[\"»])|(\+{1})|([«\"\'(\-]{1}[a-zA-Z0-9 ]*tour[a-zA-Z0-9 ]*[»\"\'(\-]?)|(-[ a-zA-Z0-9)]*))', "", artist.text)).strip())
        return artists

class Spotify:
    base_url = 'https://api.spotify.com/v1/'
    playlist_url = base_url + 'playlists/0djk4ksDSzklafJj2z1D4F/tracks'
    scopes = 'playlist-modify-public playlist-modify-private'

    def __init__(self, client_id, client_secret):
        self.client_id = client_id
        self.client_secret = client_secret
        self.authenticate()

    def authenticate(self):
        global token_info, sp
        sp_oauth = SpotifyOAuth(client_id=self.client_id,client_secret=self.client_secret,redirect_uri='http://example.com',scope=self.scopes)
        token_info = sp_oauth.get_cached_token()
        if not token_info:
            auth_url = sp_oauth.get_authorize_url()
            response = input('Paste the above link into your browser, then paste the redirect url here: ')
            code = sp_oauth.parse_response_code(response)
            token_info = sp_oauth.get_access_token(code)
        self.token = token_info['access_token']
        self.headers = {
            'Authorization': f'Bearer {self.token}',
            'Content-Type': 'application/json'
        }
        sp = spotipy.Spotify(auth=self.token)

    def refresh_token(self):
        logging.info("Refreshing token...")
        sp_oauth = SpotifyOAuth(client_id=self.client_id,client_secret=self.client_secret,redirect_uri='http://example.com',scope=self.scopes)
        token_info = sp_oauth.get_cached_token()
        if SpotifyOAuth.is_token_expired(token_info):
            token_info = SpotifyOAuth.refresh_access_token(token_info['refresh_token'])
            self.token = token_info['access_token']
            self.headers = {
                'Authorization': f'Bearer {self.token}',
                'Content-Type': 'application/json'
            }

    def search_artist(self, name):
        logging.info(f'Searching for {name}...')
        url = self.base_url + f'search?q={name}&type=artist&include_external=audio'
        response = handle_http_request('GET', url, headers=self.headers)
        if int(response.json().get('artists').get('total')) == 0:
            logging.info(f'No results for {name}')
            return
        best_match = ('', 0)
        for artist in response.json().get('artists').get('items'):
            ratio = SequenceMatcher(None, artist.get('name').upper(), name.upper()).ratio()
            if ratio > best_match[1]:
                best_match = (artist, ratio)
        if best_match[1] < 0.95:
            f_best_match = best_match
            name = re.sub('(?i)((live)|(dj set)|(\([a-zA-Z ]+\))|( (\&|et|and).+)|[^0-9a-zÀ-ÿ ]+)', '', name).strip()
            for artist in response.json().get('artists').get('items'):
                if name.upper() == artist.get('name').upper():
                    best_match = (artist, SequenceMatcher(None, artist.get('name').upper(), name.upper()).ratio())
                    break
            if f_best_match == best_match:
                if f_best_match == best_match:
                    logging.info(f'No fine match for {name}')
                    return []
        return best_match[0].get('href')

    def get_artist_top_tracks(self, artist_url, amount=1):
        top_tracks_url = artist_url + '/top-tracks?market=FR'
        response = handle_http_request('GET', top_tracks_url, headers=self.headers)
        tracks = response.json().get('tracks')
        return [x.get('uri') for x in tracks[0:amount]]

    def get_last_release_top_tracks(self, artist_url, offset = 0, amount=1):
        last_release_url = artist_url + '/albums?include_groups=album,single&market=FR&limit=50'
        response = handle_http_request('GET', last_release_url, headers=self.headers)
        albums = response.json().get('items')
        if not albums:
            return []
        for album in albums:
            if album.get('release_date_precision') == 'year':
                album['release_date'] = '{}-01-01'.format(album.get('release_date'))
            elif album.get('release_date_precision') == 'month':
                album['release_date'] = '{}-01'.format(album.get('release_date'))
        sorted_albums = sorted(albums, key=lambda x: datetime.strptime(x['release_date'], '%Y-%m-%d'), reverse = True)
        while sorted_albums[0].get('total_tracks') <= offset:
            sorted_albums.pop(0)
            offset -= 1
        response = handle_http_request('GET', sorted_albums[0].get('href'), headers=self.headers)
        tracklist = [x.get('id') for x in response.json().get('tracks').get('items')]
        track_url = f'{self.base_url}tracks?ids={",".join(tracklist)}'
        response = handle_http_request('GET', track_url, self.headers)
        tracks = [(x.get('uri'), x.get('popularity')) for x in response.json().get('tracks')]
        tracks.sort(key=lambda x: x[1], reverse = True)
        return [x[0] for x in tracks[offset:offset+amount]]

    def get_current_tracks(self):
        current_tracks = handle_http_request('GET', self.playlist_url, headers=self.headers).json().get('items')
        return [x.get('track').get('uri') for x in current_tracks]

    def add_track_to_playlist(self, track_uris, force=False):
        logging.info("Adding tracks to playlist...")
        if not force:
            current_track_uris = self.get_current_tracks()
            for current_track_uri in current_track_uris:
                if current_track_uri in track_uris:
                    track_uris.remove(current_track_uri)
        if track_uris:
            data = json.dumps({
              "uris" : track_uris
            })
            handle_http_request('POST', self.playlist_url, data=data, headers=self.headers)

    def clear_past_shows(self, track_uris):
        logging.info("Clearing past shows...")
        current_track_uris = self.get_current_tracks()
        uris_to_delete = []
        for current_track_uri in current_track_uris:
            if current_track_uri not in track_uris:
                uris_to_delete.append(current_track_uri)
        if uris_to_delete:
            data = json.dumps({
                  "uris" : uris_to_delete
            })
            handle_http_request('DELETE', self.playlist_url, headers=self.headers, data=data)

count_call = 0

def handle_http_request(type, url, headers={}, data={}):
    global count_call
    if count_call != 0 and count_call % 50 == 0:
        logging.info(f'Pausing script 10 sec to avoid 429 (total count: {count_call})...')
        time.sleep(10)
    if type == 'GET':
        response = requests.get(url, headers=headers)
    elif type == 'POST':
        response = requests.post(url, headers=headers, data=data)
    elif type == 'PUT':
        response = requests.put(url, headers=headers, data=data)
    elif type == 'DELETE':
        response = requests.delete(url, headers=headers, data=data)
    count_call += 1
    if not response.ok:
        frm = inspect.stack()[1]
        logging.error(f'HttpError: "({response.status_code}) {response.reason}"  at line {frm[2]} <{frm[3]}>')
        exit()
    return response

def main():
    config = configparser.ConfigParser()
    try:
        with open('./.conf') as f:
            config.read_file(f)
    except IOError:
        raise Exception('.conf file doesn \'t exist')

    log_level = config['logging']['level']
    logging.basicConfig(level=getattr(logging, log_level), filename='.log', filemode='w', format='%(asctime)s - %(levelname)s: %(message)s')

    spotify = Spotify(config['spotify']['client_id'], config['spotify']['client_secret'])
    parser = argparse.ArgumentParser()
    parser.add_argument("-r", "--refresh-token", help = "Refresh spotify access token.", action="store_true")
    args = parser.parse_args()

    logging.info(f"New script exec with arg {sys.argv[1:]}")

    if args.refresh_token:
        spotify.refresh_token()
    else:
        ls = LaiterieScrapper()
        artists = ls.get_artists()
        tracks = []
        for artist in artists:
            artist_url = spotify.search_artist(artist)
            if artist_url:
                top_tracks = spotify.get_artist_top_tracks(artist_url)
                last_release_top_tracks = []
                offset = 0
                while not last_release_top_tracks:
                    found_tracks = spotify.get_last_release_top_tracks(artist_url, offset)
                    if not found_tracks:
                        break
                    if not any(check in found_tracks for check in top_tracks):
                        last_release_top_tracks = found_tracks
                    else:
                        offset += 1
                tracks.extend(top_tracks)
                tracks.extend(last_release_top_tracks)
        spotify.clear_past_shows(tracks)
        spotify.add_track_to_playlist(tracks)

if __name__=="__main__":
    main()


word = input()
words = ['BTS','SBS','BS','CBS','SES']

Min = 2e18
def abc(level, remains):
    global Min
    if len(remains) == 0:
        if level < Min:
            Min = level

    for i in range(5):
        if remains[0:len(words[i])] == words[i]:
            abc(level+1, remains[len(words[i]):])

abc(0,word)
print(Min)


import sys

d = {
    ')': '(',
    ']': '['
}

def isBracket(text):
    stack = []
    for c in text:
        if c in '([':
            stack.append(c)
        elif c in ')]':
            if stack:
                top = stack.pop()
                if d[c] != top:
                    return False
            else:
                return False
    return len(stack) == 0

lines = []
while True:
    line = sys.stdin.readline().rstrip()
    if line == '.':
        break
    else:
        lines.append(line)
'''
for l in lines:
    if isBracket(l):
        print('yes')
    else:
        print('no')

'''
for l in lines:
    print('yes' if isBracket(l) else 'no')


#!/usr/bin/python3

read_sample = 0
filename = ["input.txt", "sample.txt"][read_sample]
lines = open(filename).read().strip().split('\n')

class Machine:
    def __init__(self):
        self.cycles = 0
        self.reg = 1

    def exec(self, func):
        if func != None:
            func(self)

    def run(self, command, func = None):
        ops = command.split(" ")
        instr = ops[0]
        if instr == "noop":
            self.cycles += 1; self.exec(func)
        elif instr == "addx":
            self.cycles += 1; self.exec(func)
            self.cycles += 1; self.exec(func)
            self.reg += int(ops[1])
        else:
            print("Unrecognized instruction")

total = 0
def interim(m: Machine):
    global total
    if m.cycles in [20, 60, 100, 140, 180, 220]:
        total += m.cycles * m.reg

m = Machine()
for line in lines:
    m.run(line, interim)

print(total)


#!/usr/bin/python3

from flask import Flask, request

import sys
from multiprocessing import Process, Queue

import json
from werkzeug.wrappers import Response

global cl

def classifyrunner2(queue, request):
    import classify
    cl = classify.Classify()
    cl.do_learntestclassify(queue, request)

def predictrunner(queue, request):
    import predict
    pr = predict.Predict()
    pr.do_learntestlist(queue, request)

def hasgpu():
    import torch
    return torch.cuda.is_available()

app = Flask(__name__)

@app.route('/eval', methods=['POST'])
def do_eval():
    import classify
    cl = classify.Classify()
    return cl.do_eval(request)

@app.route('/classify', methods=['POST'])
def do_classify():
    import classify
    cl = classify.Classify()
    return cl.do_classify(request)

@app.route('/test', methods=['POST'])
def do_test():
    import classify
    cl = classify.Classify()
    return cl.do_test(request)

@app.route('/learntest', methods=['POST'])
def do_learntest():
    import classify
    cl = classify.Classify()
    return cl.do_learntest(request)

@app.route('/learntestclassify', methods=['POST'])
def do_learntestclassify():
    def classifyrunner(queue, request):
        try:
            import classify
            cl = classify.Classify()
            return cl.do_learntestclassify(queue, request)
        except:
            import sys,traceback
            traceback.print_exc(file=sys.stdout)
            print("\n")
            import random
            f = open("/tmp/outgem" + argstr() + str(random.randint(1000,9999)) +".txt", "w")
            f.write(request.get_data(as_text=True))
            traceback.print_exc(file=f)
            f.close()
            return(Response(json.dumps({"classifycatarray": None, "classifyprobarray": None, "accuracy": None, "loss": None }), mimetype='application/json'))
    return classifyrunner(None, request)
    queue = Queue()
    process = Process(target=classifyrunner, args=(queue, request))
    process.start()
    result = queue.get()
    process.join()
    return result

@app.route('/predictone', methods=['POST'])
def do_learntestpredictone():
    queue = Queue()
    process = Process(target=predictrunner, args=(queue, request))
    process.start()
    result = queue.get()
    process.join()
    return result

@app.route('/predict', methods=['POST'])
def do_learntestpredict():
    queue = Queue()
    process = Process(target=predictrunner, args=(queue, request))
    process.start()
    result = queue.get()
    process.join()
    return result

@app.route('/dataset', methods=['POST'])
def do_dataset():
    def classifyrunner(queue, request):
        try:
            import classify
            cl = classify.Classify()
            cl.do_dataset(queue, request)
        except:
            import sys,traceback
            traceback.print_exc(file=sys.stdout)
            print("\n")
            import random
            f = open("/tmp/outgem" + argstr() + str(random.randint(1000,9999)) + ".txt", "w")
            f.write(request.get_data(as_text=True))
            traceback.print_exc(file=f)
            f.close()
            return(Response(json.dumps({"accuracy": None, "loss": None}), mimetype='application/json'))
    return classifyrunner(None, request)
    queue = Queue()
    process = Process(target=classifyrunner, args=(queue, request))
    process.start()
    result = queue.get()
    process.join()
    return result

@app.route('/filename', methods=['POST'])
def do_filename():
    def filenamerunner(queue, request):
        import classify
        cl = classify.Classify()
        return cl.do_filename(queue, request)
    return filenamerunner(None, request)
    queue = Queue()
    process = Process(target=filenamerunner, args=(queue, request))
    process.start()
    result = queue.get()
    process.join()
    return result

def argstr():
    if len(sys.argv) > 1 and sys.argv[1].isnumeric():
        return sys.argv[1]
    else:
        return str(80)

if __name__ == '__main__':
#    queue = Queue()
#    process = Process(target=hasgpurunner, args=(queue, None))
#    process.start()
#    process.join()
#    hasgpu = queue.get()
    hasgpu = hasgpu()
    print("Has GPU", hasgpu)
    threaded = False
    if len(sys.argv) > 1 and (not hasgpu) and sys.argv[1] == 'multi':
        threaded = True
        print("Run threaded")
    port = argstr()
    print("Used port", port)
    app.run(host='0.0.0.0', port=port, threaded=threaded)


#!/usr/bin/env python
# encoding: utf-8

"""
@description: 多元线性回归

@version: 1.0
@author: BaoQiang
@license: Apache Licence
@contact: mailbaoqiang@gmail.com
@site: http://www.github.com/githubao
@software: PyCharm
@file: muti_liner.py
@time: 2016/11/23 20:40
"""

from numpy.linalg import inv,lstsq
from numpy import dot,transpose
from sklearn.linear_model import LinearRegression

def main():
    x = [[1,1,1],[1,1,2],[1,2,1]]
    y = [[6],[9],[8]]

    print(dot(inv(dot(transpose(x),x)), dot(transpose(x),y)))

    print(lstsq(x,y)[0])

    model = LinearRegression()
    model.fit(x,y)
    x2 = [[1,3,5]]
    y2 = model.predict(x2)
    print(y2)

if __name__ == '__main__':
    main()


class User():

    def __init__(self, x, y):
        self.name = ''
        self.monlist_name = []
        self.monlist = []
        self.itemlist = {}
        self.money = 100
        self.x , self.y = x , y
        self.nx, self.ny = x , y
        self.id = 'P'

    def User_inven(self):
        print(self.name, '님의 인벤토리')
        print('보유 몬스터',self.monlist_name)
        print('보유 아이템',self.itemlist)
        print('보유 돈',self.money)

    def move(self, direction):
        if direction == 'w':
            self.nx, self.ny = self.x, self.y - 1

        elif direction == 'a':
            self.nx, self.ny = self.x - 1, self.y

        elif direction == 's':
            self.nx, self.ny = self.x, self.y + 1

        elif direction == 'd':
            self.nx, self.ny = self.x + 1, self.y

        a = 0
        b = 0
        for i in gamemap:
            for j in i:
                if a == self.nx and b == self.ny:
                    gamemap[b][a] = self.id

                    print('플레이어 위치 : P \n')
                    print('C : 초원마을 S : 사막마을 M : 물마을 \n')
                    for c in range(len(gamemap)):
                        print(gamemap[c])
                    print('\n')
                    print('\n')
                else:
                    gamemap[b][a] = gamemap_real[b][a]
                a += 1
            b += 1
            a = 0

        if not self.collide():
            self.x, self.y = self.nx, self.ny

    def collide(self):
        if gamemap[self.ny][self.nx] == 1:
            print('길이 아닙니다.')
            return True
        else:
            print('현재 위치 좌표는','[',self.nx + 1 ,',', self.ny + 1,']','입니다')
            return False

gamemap = [
    ['1','1','1','1','1','1','1'],
    ['1','C','0','0','0','1','1'],
    ['1','0','0','0','0','1','1'],
    ['1','0','0','0','M','1','1'],
    ['1','S','0','0','0','1','1'],
    ['1','0','0','0','0','1','1'],
    ['1','1','1','1','1','1','1']
]

gamemap_real = [
    ['1','1','1','1','1','1','1'],
    ['1','C','0','0','0','1','1'],
    ['1','0','0','0','0','1','1'],
    ['1','0','0','0','M','1','1'],
    ['1','S','0','0','0','1','1'],
    ['1','0','0','0','0','1','1'],
    ['1','1','1','1','1','1','1']
]


import numpy as np
from tqdm import tqdm

class FeatExpect:
    def __call__(self, state, action):
        raise NotImplementedError

    def fit(self, *args, **kwargs):
        raise NotImplementedError

class MonteCarlo(FeatExpect):
    def __init__(self, state_to_psi, action_space, gamma, quiet=True):

        self.state_to_psi = state_to_psi
        self.action_space = action_space
        self.gamma = gamma
        self.quiet = quiet

        self.feat_expect_key = None
        self.feat_expect_val = None
        self.n_estimates = None

    def __call__(self, state, action):
        results = list()
        for single_state, single_action in zip(state, action):
            match_index = self.get_key(single_state, single_action)
            results.append(self.feat_expect_val[match_index.squeeze()])
        return np.vstack(results)

    def fit(self, expert_states, expert_actions, absorbing_states):
        """
        Fits a batch of data for calculating the feature expectation

        Args:
            expert_states (np.ndarray):  matrix of states with shape (N, M) -
                N: number os steps, M: dimensionality of the state space;
            expert_actions (np.ndarray): matrix of actions with shape (N, M) -
                N: number os steps, M: dimensionality of the actions space;
            absorbing_states (np.ndarray):  matrix of absorbing with shape (N,) -
                N: number os steps
        """
        assert len(expert_states.shape) == len(expert_actions.shape) == 2
        assert len(absorbing_states.shape) == 1

        if self.feat_expect_key is None:
            self.feat_expect_key = np.empty(
                (0, np.concatenate([expert_states[0, :], expert_actions[0, :]]).size))
            self.feat_expect_val = np.empty(
                (0, self.state_to_psi(expert_states[0, :], expert_actions[0, :]).size))
            self.n_estimates = np.empty((0,))

        absorbing_states_indexes = np.argwhere(absorbing_states).squeeze() + 1

        for episodic_states, episodic_actions, episodic_absorbing in tqdm(zip(
                np.split(expert_states, absorbing_states_indexes),
                np.split(expert_actions, absorbing_states_indexes),
                np.split(absorbing_states, absorbing_states_indexes),
                ), position=0):
            if episodic_states.size != 0:
                self._calculate_feat_expect_episode(episodic_states, episodic_actions)

    def get_key(self, state, action):
        """
        Gets index of the inputs state action feature vector

        Args:
            psi_vector (np.ndarray): Array of shape (M,) with M being the dimensionality of the psi space

        Returns:
            Integer of the position of the vector in the feat_expect_key
        """
        match_index = np.argwhere((np.array([np.append(state, action)]) == self.feat_expect_key).all(axis=1)).squeeze()
        return match_index

    def _add_feat_expect(self, state, action, feat_expect_val):
        match_index = self.get_key(state, action)
        if match_index.size == 1:
            self.feat_expect_val[match_index, :] = np.add(self.feat_expect_val[match_index, :] *
                                                          self.n_estimates[match_index], feat_expect_val) \
                                                   / (self.n_estimates[match_index] + 1)
            self.n_estimates[match_index] += 1
        else:
            self.feat_expect_key = np.append(self.feat_expect_key, np.array([np.append(state, action)]), axis=0)
            self.feat_expect_val = np.append(self.feat_expect_val, np.zeros_like(np.array([feat_expect_val])), axis=0)
            self.n_estimates = np.append(self.n_estimates, 0)
            self._add_feat_expect(state, action, feat_expect_val)

    def _calculate_feat_expect_episode(self, states_trajectories, actions_trajectories):
        """
        Args:
            Calculates the rollout of one episode.

            states_trajectories (np.ndarray):  matrix of states with shape (N, M) -
                N: number os steps, M: dimensionality of the state space;
            actions_trajectories (np.ndarray): matrix of actions with shape (N, M) -
                N: number os steps, M: dimensionality of the actions space;

        """

        feat_expect = np.zeros_like(self.state_to_psi(states_trajectories[0], actions_trajectories[0]))
        for i in tqdm(range(states_trajectories.shape[0] - 1, -1, -1), position=1):
            step_psi = self.state_to_psi(states_trajectories[i], actions_trajectories[i])
            feat_expect = np.add(self.gamma * feat_expect, step_psi)
            self._add_feat_expect(states_trajectories[i], actions_trajectories[i], feat_expect)

            for action in self.action_space:
                self._add_feat_expect(states_trajectories[i], action,
                                      feat_expect * self.gamma)

class LSTDmu(FeatExpect):
    def __init__(self, expert_state, expert_actions, state_action_to_psi, state_to_phi, gamma, policy):
        self.expert_state = expert_state
        self.expert_actions = expert_actions

        self.state_action_to_psi = state_action_to_psi
        self.state_to_phi = state_to_phi

        self.policy = policy

        self.gamma = gamma

        psi = self.state_action_to_psi(self.expert_state, self.expert_actions)
        psi_prime = psi[1:, :]
        psi_prime = np.concatenate([psi_prime, np.array([np.ones_like(psi_prime[-1, :])])], axis=0)

        phi = self.state_to_phi(self.expert_state, self.expert_actions)
        self.csi = self.lstd_mu_func(psi, psi_prime, phi, gamma)

    def __call__(self, state, action):
        state, action = super().__call__(state, action)
        psi = self.state_action_to_psi(state, action)
        res = self.feature_expectation(psi, self.csi)
        return res

    def fit(self, *args, **kwargs):
        pass

    @staticmethod
    def lstd_mu_func(psi, psi_prime, phi, gamma):
        """
        Least-Squares Temporal Differences \mu
        This function is used to calculate to estimate the feature
        expectation in the SCIRL algorithm both described at :
        \"Edouard Klein, Matthieu Geist, Bilal PIOT, and Olivier Pietquin.
        Inverse Reinforcement Learning through Structured Classification. In
        Advances in Neural Information Processing Systems (NIPS 2012), Lake
        Tahoe (NV, USA), December 2012.\"

        Args:
             psi (np.ndarray): feature matrix whose rows are the feature
                vectors with respect to present state;
             psi_prime (np.ndarray): feature matrix whose rows are the feature
                vectors with respect to next state;
             phi (np.ndarray): 2D feature matrix whose rows are the
                reward’s feature vectors.

        Returns:
            Weights by which the dot product with the psi matrix gives the
            feature expectations.

        """
        A = np.dot(psi.T, psi - gamma * psi_prime)
        b = np.dot(psi.T, phi)

        return np.dot(np.linalg.inv(A + 0.0001 * np.identity(A.shape[0])), b)

    @staticmethod
    def feature_expectation(psi, csi):
        """

        Args:
            psi (np.ndarray): feature matrix whose rows are the feature
                vectors with respect to present state;
            csi (np.ndarray): Weights by which the dot product with the psi
            matrix gives the feature expectations.

        Returns:
            Weights by which the dot product with the psi matrix gives the
            feature expectations.
        """
        return np.dot(psi, csi)


import logging

import cv2
import numpy as np

def 解码(流):
    if type(流)==str:
        图 = cv2.imdecode(np.array([ord(i) for i in 流], dtype=np.uint8), cv2.IMREAD_UNCHANGED)
    elif type(流)==bytes:
        图 = cv2.imdecode(np.array([i for i in 流], dtype=np.uint8), cv2.IMREAD_UNCHANGED)
    else:
        raise '流应当为str或bytes格式。'
    return 图

def 编码为webp(图):
    retval, buf = cv2.imencode(".webp",
                               图,
                               [cv2.IMWRITE_WEBP_QUALITY, 90])
    assert retval, '图像编码失败'
    logging.warning(type(buf))
    return buf.tobytes()

def 做头(原图):
    r, c = 原图.shape[:2]
    if r > c:
        r0 = int((r - c) / 2)
        切片 = 原图[r0:r0 + c, 0:c]
    else:
        c0 = int((c - r) / 2)
        print()
        切片 = 原图[0:r, c0:c0 + r]
    大头像 = cv2.resize(切片, (512, 512), interpolation=cv2.INTER_AREA)
    小头像 = cv2.resize(切片, (128, 128), interpolation=cv2.INTER_AREA)
    return 编码为webp(大头像), 编码为webp(小头像)


import os
import pty
import select
import signal
import subprocess
import termios
import threading
import tty

from utils import *

logger = Logger('terminal_exp.log')

class TerminalOutputHandler(object):
    def __init__(self):
        self.last_data = ''

    def receive_output(self, data):
        data = self.last_data + data
        sys.stdout.write(data)
        sys.stdout.flush()
        logger.log('[stdout]"%s"(%s)' % (data, to_hex_str(data)))

    def receive_error(self, data):
        sys.stderr.write(data)

class Terminal(object):
    def __init__(self):
        self.popen_obj = subprocess.Popen(['/usr/bin/script', '-fqc', '/bin/bash'],
                            stdin=subprocess.PIPE,
                            stdout=subprocess.PIPE,
                            stderr=subprocess.PIPE)
        self.terminal_output_handler = TerminalOutputHandler()
        self.poll_thread = threading.Thread(target=self._run_poll_thread)
        self.poll_thread.start()

    def _run_poll_thread(self):
        # poll thread
        stdout_fd = self.popen_obj.stdout.fileno()
        stderr_fd = self.popen_obj.stderr.fileno()
        make_file_nonblocking(self.popen_obj.stdout)
        make_file_nonblocking(self.popen_obj.stderr)
        while True:
            rlist, _, xlist = select.select([stdout_fd, stderr_fd], [], [stdout_fd, stderr_fd])
            if stdout_fd in rlist or stdout_fd in xlist:
                data = self.popen_obj.stdout.read()
                if not data:
                    self.close()
                self.receive_stdout_data(data)
            if stderr_fd in rlist or stderr_fd in xlist:
                data = self.popen_obj.stderr.read()
                if not data:
                    self.close()
                self.receive_stderr_data(data)

    def receive_stdout_data(self, data):
        # poll thread
        self.terminal_output_handler.receive_output(data)

    def receive_stderr_data(self, data):
        # poll thread
        self.terminal_output_handler.receive_error(data)

    def close(self):
        os._exit(0)

    def write(self, data):
        self.popen_obj.stdin.write(data)
        logger.log('[stdin]"%s"(%s)' % (data, to_hex_str(data)))

class InputController(object):
    def __init__(self):
        self.old_stdin_setting = termios.tcgetattr(sys.stdin.fileno())
        tty.setraw(sys.stdin.fileno())

    def restore_stdin(self):
        termios.tcsetattr(sys.stdin.fileno(), termios.TCSADRAIN, self.old_stdin_setting)

    def read(self):
        return sys.stdin.read(1)

def t1():
    terminal = Terminal()
    input = InputController()
    while True:
        data = input.read()
        if not data:
            os._exit()
        terminal.write(data)

def use_script():
    obj = subprocess.Popen(['/usr/bin/script', '-fqc', '/bin/bash'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    obj.stdin.write('ls ; echo cmd finish with code $?. >&2\n')
    #obj.stdin.write('ls\n')
    #obj.stdin.write('sleep 1\n')
    obj.stdin.write('exit\n')
    stdout = obj.stdout.read()
    stderr = obj.stderr.read()
    print('stdout (%s), stderr (%s)' % (stdout, stderr))

class TerminalPty(object):
    def __init__(self):
        pid, fd = pty.fork()
        if pid == 0:
            # child process
            subprocess.call(['/bin/bash'], shell=False)
            os._exit(0)
        self.child_pid = pid
        self.pty_fd = fd

    def run(self):
        old_stdin_setting = set_stdin_raw()
        try:
            make_file_nonblocking(self.pty_fd)
            make_file_nonblocking(sys.stdin)
            self.install_window_size_change_signal_handler()
            while True:
                try:
                    rlist, _, xlist = select.select([self.pty_fd, sys.stdin.fileno()], [], [self.pty_fd, sys.stdin.fileno()])
                except select.error as ex:
                    if ex[0] == 4:
                        continue
                    raise
                if self.pty_fd in rlist or self.pty_fd in xlist:
                    try:
                        data = os.read(self.pty_fd, 1024)
                    except OSError:
                        break
                    if not data:
                        logger.log('no pty_fd data')
                        raise Exception()
                    logger.log('[from shell](%s)' % data)
                    sys.stdout.write(data)
                    sys.stdout.flush()
                if sys.stdin.fileno() in rlist or sys.stdin.fileno() in xlist:
                    data = sys.stdin.read()
                    if not data:
                        logger.log('no input data')
                        raise Exception()
                    logger.log('[from terminal](%s)' % data)
                    os.write(self.pty_fd, data)

        finally:
            restore_stdin(old_stdin_setting)

    def install_window_size_change_signal_handler(self):
        def handler(signum, _):
            w, h = get_terminal_size(sys.stdin.fileno())
            set_terminal_size(self.pty_fd, w, h)
            logger.log('adjust terminal size to w = %d, h = %d' % (w, h))

        signal.signal(signal.SIGWINCH, handler)

def use_forkpty():
    w, h = get_terminal_size(sys.stdin.fileno())
    print('w = %d, h = %d' % (w, h))
    terminal = TerminalPty()
    terminal.run()

def main():
    use_forkpty()

if __name__ == '__main__':
    main()


import tensorflow as tf
import numpy as np

_LABELS = ['true', 'false', 'half-true']
# The "distance" for a false-true mistake is 2, and for every other pair - 1
_LABEL_NUMERIC_VALUES = {'false': 0, 'half-true': 1, 'true': 2}

def tf_f1_score(labels, predictions):
    f1s = [0, 0, 0]

    labels = tf.cast(labels, tf.float64)
    predictions = tf.cast(predictions, tf.float64)

    for i, axis in enumerate([None, 0]):
        TP = tf.count_nonzero(predictions * labels, axis=axis)
        TN = tf.count_nonzero((predictions - 1) * (labels - 1), axis=axis)
        FP = tf.count_nonzero(predictions * (labels - 1), axis=axis)
        FN = tf.count_nonzero((predictions - 1) * labels, axis=axis)

        epsilon = tf.cast(tf.keras.backend.epsilon(), 'int64')

        precision = TP / (TP + FP + epsilon)
        recall = TP / (TP + FN + epsilon)
        f1 = 2 * precision * recall / (precision + recall)

        f1s[i] = tf.reduce_mean(f1)

    weights = tf.reduce_sum(labels, axis=0)
    weights /= tf.reduce_sum(weights)

    f1s[2] = tf.reduce_sum(f1 * weights)

    micro, macro, weighted = f1s
    return {'micro': micro, 'macro': macro, 'weighted': weighted}

def _compute_confusion_matrix(gold_labels, pred_labels):
    """ Computes Confusion Matrix. """
    conf_matrix = {
        'true': {'true': 0, 'false': 0, 'half-true': 0},
        'false': {'true': 0, 'false': 0, 'half-true': 0},
        'half-true': {'true': 0, 'false': 0, 'half-true': 0}
    }

    for pred_label, gold_label in zip(pred_labels, gold_labels):
        pred_label = pred_label.lower()
        true_label = gold_label.lower()
        conf_matrix[true_label][pred_label] += 1

    return conf_matrix

def _compute_accuracy(conf_matrix):
    """ Computes Accuracy. """
    num_claims = sum([sum(row.values()) for row in conf_matrix.values()])
    correct_claims = sum([conf_matrix[l][l] for l in _LABELS])
    if num_claims:
        return correct_claims / num_claims
    else:
        return 0.0

def _compute_macro_f1(conf_matrix):
    """ Computes Macro F1. """
    p = {'true': 0, 'false': 0, 'half-true': 0}
    r = {'true': 0, 'false': 0, 'half-true': 0}

    for label in _LABELS:
        all_predicted = sum([conf_matrix[l][label] for l in _LABELS])

        if all_predicted:
            p[label] = conf_matrix[label][label] / all_predicted
        else:
            p[label] = 0.0
        all_gold = sum([conf_matrix[label][l] for l in _LABELS])

        if all_gold == 0:
            raise ValueError('No instances for class {} found!'.format(label))

        r[label] = conf_matrix[label][label] / all_gold

    f1 = {'true': 0, 'false': 0, 'half-true': 0}
    for label in _LABELS:
        if p[label] + r[label]:
            f1[label] = 2.0 * p[label] * r[label] / (p[label] + r[label])
        else:
            f1[label] = 0.0

    return sum(f1.values()) / len(f1)

def _compute_macro_recall(conf_matrix):
    """ Computes Macro Recall """
    r = {}
    for label in _LABELS:
        all_gold = sum([conf_matrix[label][l] for l in _LABELS])
        if all_gold == 0:
            raise ValueError('No instances for class {} found!'.format(label))

        r[label] = conf_matrix[label][label] / all_gold

    return sum(r.values()) / len(r)

def _compute_mean_absolute_error(conf_matrix):
    """ Computes Mean Absolute Error (MAE). """
    num_claims = sum([sum(row.values()) for row in conf_matrix.values()])
    distance_sum = 0.0
    for gold_label in conf_matrix:
        for pred_label in conf_matrix:
            distance = abs(_LABEL_NUMERIC_VALUES[gold_label] - _LABEL_NUMERIC_VALUES[pred_label])
            distance_sum += conf_matrix[gold_label][pred_label] * distance
    if num_claims:
        return distance_sum / num_claims
    else:
        return 0.0

def _compute_macro_averaged_mae(conf_matrix):
    """ Computes Macro-averaged Mean Absolute Error. """
    mae = {}
    for label in _LABELS:
        all_gold = sum([conf_matrix[label][l] for l in _LABELS])
        distance_sum = 0.0
        gold_label_value = _LABEL_NUMERIC_VALUES[label]
        for pred_label in conf_matrix[label]:
            distance = abs(gold_label_value - _LABEL_NUMERIC_VALUES[pred_label])
            distance_sum += conf_matrix[label][pred_label] * distance
        if all_gold == 0:
            raise ValueError('No instances for class {} found!'.format(label))
        mae[label] = distance_sum / all_gold
    return sum(mae.values()) / len(mae)

def mae(gold_labels, pred_labels):
    return _compute_mean_absolute_error(_compute_confusion_matrix(gold_labels, pred_labels))

def macro_averaged_mae(gold_labels, pred_labels):
    return _compute_macro_averaged_mae(_compute_confusion_matrix(gold_labels, pred_labels))

def accuracy(gold_labels, pred_labels):
    return _compute_accuracy(_compute_confusion_matrix(gold_labels, pred_labels))

def macro_f1(gold_labels, pred_labels):
    return _compute_macro_f1(_compute_confusion_matrix(gold_labels, pred_labels))

def macro_recall(gold_labels, pred_labels):
    return _compute_macro_recall(_compute_confusion_matrix(gold_labels, pred_labels))

metric_callables = {
    'mae': mae,
    'macro_averaged_mae': macro_averaged_mae,
    'accuracy': accuracy,
    'macro_f1': macro_f1,
    'macro_recall': macro_recall,
}


from pymunk import Vec2d

from app.cmp import Component
from pyglet.gl import *
from pyglet.graphics import Group
from pyglet.graphics import OrderedGroup

class Transform(Group):
    """
    Hierarchical pyglet group to make object on object
    """
    def on_remove(self): #dummy from Component
        pass

    def __init__(self, pos, size=Vec2d(0, 0), angle=0, anchor=None):
        super().__init__(parent=None)
        """

        :param pos: anchor point position
        :param size: initial size of transformable entity (can be grabed from renderable.size() )
        :param angle: angle in radians
        :param anchor: center of rotation and scaling
        """

        self._bb = [
            Vec2d(0, 0),  # min
            Vec2d(0, 0)   # max
        ]
        self._parent = None  # relative posititoning
        self._ppos = Vec2d(0, 0)  # parent positioning
        self._childs = []
        self._pos = [       # local pos
            Vec2d(0, 0),    # for sprite anchor
            Vec2d(0, 0),    # for line
            Vec2d(0, 0),    # for futurer modifible quad
            Vec2d(0, 0)     # for futurer modifible quad
        ]
        self._v = [       # final counted vertixes
            Vec2d(0, 0),  # for sprite anchor
            Vec2d(0, 0),  # for line
            Vec2d(0, 0),  # for futurer modifible quad
            Vec2d(0, 0)   # for futurer modifible quad
        ]
        self._anchor = Vec2d(0.0, 0.0)
        self._size = size
        self._pos[1] = pos + size
        if anchor:
            self._anchor = anchor
        if pos:
            self._pos[0] = pos

        self.pre_pos = Vec2d(0, 0) # for check.. update something like graphics or not
        self._angle = angle
        self.pre_angle = self._angle

        self._scale = Vec2d(1, 1)
        self.pre_scale = Vec2d(0, 0)

        self._modified = True  #check if need to redraw

        self.unzoomable = False  # camera zoom does not affect renderable sizes
        self.last_cam_zoom = 1   #
        self.update_vertix()
        self.calc_bb()

    def _set_modified(self):
        """
        internal usage update modified to True for self and childs
        :return:
        """
        self._modified = True
        for c in self._childs:
            c._set_modified()
        self.calc_bb()

    def redrawed(self):
        """
        not for childs
        :return:
        """
        self._modified = False

    def other_point(self, val):
        """
        Used for lines with two _pos
        Try to find another end of segment if param is the one of their side
        :param val: one of the segment point
        :return: other point or nothing
        """
        if val == self._pos[0]:
            return self._pos[1]
        if val == self._pos[1]:
            return self._pos[0]
        return None

    def replace_pt(self, self_src, self_dest):
        for i in range(4):
            if self._pos[i] == self_src:
                self._pos[i] = self_dest
                return True
        return False

    def modified(self, zoom=None):
        if not self.unzoomable:
            return self._modified
        else:
            if zoom and zoom != self.last_cam_zoom:
                self._modified = True
                return self._modified

    @property
    def pos(self):
        """
        :return: local position
        """
        return self._pos[0]

    @pos.setter
    def pos(self, val):
        """
        Sets a local position
        :param val:
        :return:
        """
        if val != self._pos[0]:
            self._pos[0] = val
            self._set_modified()

    @staticmethod
    def recur_pos(tr):
        if tr.parent is None:
            # nothin upper
            if tr.__class__ == Transform:
                return tr.pos
            else:
                return Vec2d(0, 0)
        else:
            #return same parent transformation
            #TODO calc angle and scale
            return Transform.recur_pos(tr.parent) + tr.pos

    @property
    def g_pos(self):
        """
        :return: global position calculated from the parents
        """
        return Transform.recur_pos(self)

        if self.parent and self.parent.__class__ == Transform:
                return self.parent.g_pos + self._pos[0]
        else:
            return self._pos[0]

    @property
    def pos1(self):
        """
        :return: local position
        """
        return self._pos[1]

    @pos1.setter
    def pos1(self, val):
        """
        Sets a local position
        :param val:
        :return:
        """
        if val != self._pos[1]:
            self._pos[1] = val
            self._set_modified()

    @property
    def g_pos1(self):
        """
        :return: global position calculated from the parents
        """
        if self._parent and self.parent is Transform:
            return self._parent.g_pos + self._pos[1]
        else:
            return self._pos[1]

    @property
    def angle(self):
        if self._parent and self.parent is Transform:
            return self._parent.angle + self._angle
        else:
            return self._angle

    @angle.setter
    def angle(self, val):
        if val != self._angle:
            self._angle = val
            self._set_modified()

    @property
    def scale(self):
        return self._scale

    @scale.setter
    def scale(self, val):
        if val != self._scale:
            self._scale = val
            self._set_modified()

    @property
    def x(self):
        if self._parent and self.parent is Transform:
            return self._parent.x + self._pos[0].x
        else:
            return self._pos[0].x

    @x.setter
    def x(self, val):
        """
        Warning!!
        calculate relative position prevous if on _parent!
        :param val:
        :return:
        """
        self._pos[0].x = val
        self._set_modified()

    @property
    def y(self):
        if self._parent and self.parent is Transform:
            return self._parent.y + self._pos[0].y
        else:
            return self._pos[0].y

    @y.setter
    def y(self, val):
        """
        Warning!!
        calculate relative position prevous if on _parent!
        :param val:
        :return:
        """
        self._pos[0].y = val
        self._set_modified()

    @property
    def x1(self):
        if self._parent and self.parent is Transform:
            return self._parent.x + self._pos[1].x
        else:
            return self._pos[1].x

    @x1.setter
    def x1(self, val):
        """
        Warning!!
        calculate relative position prevous if on _parent!
        :param val:
        :return:
        """
        self._pos[1].x = val
        self._set_modified()

    @property
    def y1(self):
        if self._parent and self.parent is Transform:
            return self._parent.y + self._pos[1].y
        else:
            return self._pos[1].y

    @y1.setter
    def y1(self, val):
        """
        Warning!!
        calculate relative position prevous if on _parent!
        :param val:
        :return:
        """
        self._pos[1].y = val
        self._set_modified()

    @property
    def anchor(self):
        return self._anchor

    @anchor.setter
    def anchor(self, val):
        self._anchor = val

    @property
    def w(self):
        if self.unzoomable:
            return self._size.x
        else:
            return self._size.x

    @property
    def h(self):
        if self.unzoomable:
            return self._size.y
        else:
            return self._size.y

    """
    @property
    def parent(self):
        return self._parent
    """

    """
    @parent.setter
    def parent(self, val):
        if val:
            val._childs.append(self)
            self._parent = val
        else:
            if self._parent:
                self._parent._childs.remove(self)
    """

    def scale_to(self, des_wh):
        #TODO rescale
        return

    def calc_bb(self):
        self._bb[0].x = self._v[0].x
        self._bb[0].y = self._v[0].y
        self._bb[1].x = self._v[0].x
        self._bb[1].y = self._v[0].y
        for i in range(1, 4):
            # minimal point
            if self._v[i].x < self._bb[0].x:
                self._bb[0].x = self._v[i].x
            if self._v[i].y < self._bb[0].y:
                self._bb[0].y = self._v[i].y
            # maximal point
            if self._v[i].x > self._bb[1].x:
                self._bb[1].x = self._v[i].x
            if self._v[i].y > self._bb[1].y:
                self._bb[1].y = self._v[i].y

    def get_in_bb(self, pos):
        v = pos - self._pos[0]
        if self._bb[0].x < v.x < self._bb[1].x and \
           self._bb[0].y < v.y < self._bb[1].y:
            return v
        else:
            return None

    def update_vertix(self):
        if self._parent:
            self._ppos.x = self._parent.x
            self._ppos.y = self._parent.y
        self._v[0] = Vec2d(-self._anchor.x * self._scale.x,
                           -self._anchor.y * self._scale.y)
        self._v[0].rotate(self._angle)
        self._v[0] = self._v[0] + self._ppos

        self._v[1] = Vec2d((self._size.x - self._anchor.x) * self._scale.x,
                           -self._anchor.y * self._scale.y)
        self._v[1].rotate(self._angle)
        self._v[1] = self._v[1] + self._ppos

        self._v[2] = Vec2d((self._size.x - self._anchor.x) * self._scale.x,
                           (self._size.y - self._anchor.y) * self._scale.y)
        self._v[2].rotate(self._angle)
        self._v[2] = self._v[2] + self._ppos

        self._v[3] = Vec2d(-self._anchor.x * self._scale.x,
                           (self._size.y - self._anchor.y) * self._scale.y)
        self._v[3].rotate(self._angle)
        self._v[3] = self._v[3] + self._ppos

    def update_vertix_uz(self, zoom):  # FIXME: unzoomable sprites does not show at begin
        if self._parent:
            self._ppos.x = self._parent.x
            self._ppos.y = self._parent.y
        self._v[0] = Vec2d(-self._anchor.x / self.last_cam_zoom,
                           -self._anchor.y / self.last_cam_zoom)
        self._v[0].rotate(self._angle)
        self._v[0] = self._v[0] + self._ppos

        self._v[1] = Vec2d((self._size.x - self._anchor.x) / self.last_cam_zoom,
                           -self._anchor.y / self.last_cam_zoom)
        self._v[1].rotate(self._angle)
        self._v[1] = self._v[1] + self._ppos

        self._v[2] = Vec2d((self._size.x - self._anchor.x) / self.last_cam_zoom,
                           (self._size.y - self._anchor.y) / self.last_cam_zoom)
        self._v[2].rotate(self._angle)
        self._v[2] = self._v[2] + self._ppos

        self._v[3] = Vec2d(-self._anchor.x / self.last_cam_zoom,
                           (self._size.y - self._anchor.y) / self.last_cam_zoom)
        self._v[3].rotate(self._angle)
        self._v[3] = self._v[3] + self._ppos

    def q_verts(self):
        return [0, 0,
                self._pos[1].x-self._pos[0].x, 0,
                self._pos[1].x-self._pos[0].x, self._pos[1].y-self._pos[0].y,
                0, self._pos[1].y-self._pos[0].y]

    def l_verts(self):
        return [0, 0,
                self._pos[1].x-self._pos[0].x, self._pos[1].y-self._pos[0].y]

    def vertixes(self, zoom=None):
        if self.unzoomable:
            if self.last_cam_zoom != zoom or self._modified:
                self.last_cam_zoom = zoom
                self.update_vertix_uz(zoom)
        else:
            if self._modified:
                self.update_vertix()

        self._modified = False
        self.calc_bb()

        return [
            self._v[0].x + self._pos[0].x, self._v[0].y + self._pos[0].y,
            self._v[1].x + self._pos[0].x, self._v[1].y + self._pos[0].y,
            self._v[2].x + self._pos[0].x, self._v[2].y + self._pos[0].y,
            self._v[3].x + self._pos[0].x, self._v[3].y + self._pos[0].y
        ]

    def set_state(self):
        # callback apply local transforamtions
        glPushMatrix()
        glTranslatef(self._pos[0].x, self._pos[0].y, 0.0)
        glRotatef(self._angle, 0.0, 0.0, 1.0)
        glTranslatef(-self._anchor.x, -self._anchor.y, 0.0)
        glScalef(self._scale.x, self._scale.y, 0.0)

    def unset_state(self):
        # callback restore from local transformation
        glPopMatrix()


# LSTM for sequence classification in the IMDB dataset

import os
import operator
import numpy as np
import math
import csv
import sys
from keras.models import Sequential, Model
from keras.layers import LSTM, BatchNormalization, Dense, SpatialDropout1D, CuDNNLSTM, Reshape
from keras.engine.input_layer import Input
from keras.layers.embeddings import Embedding
from keras.layers.convolutional import Conv1D, Conv2D, Conv3D
from keras.layers.convolutional import MaxPooling1D, MaxPooling2D, MaxPooling3D
from keras.layers.core import Dropout, Lambda
from keras.preprocessing import sequence
from keras.preprocessing.sequence import TimeseriesGenerator
from keras.callbacks import EarlyStopping, ModelCheckpoint
from keras import optimizers

article_length = 400
batch_size = 64
epochs = 100
input_dimension = int(math.sqrt(article_length))

file = open('Dictionary.txt', mode = 'r')
lines = file.readlines()
output = (x.replace("\n",'').split(",") for x in lines)
encoding = {}
x = next(output)
while not (x) == ['']:
	encoding[x[0]] = x[1]
	x = next(output)
file.close()

article_path = sys.argv[1]
file = open(article_path, mode='r', encoding='utf8')
reading = file.readlines()
lines = ''
for line in reading:
	lines += line

words = lines.replace('\n',' ').replace('"', '').replace("'",'').replace(",",'').replace(".",'').replace("?",'').replace("!",'').lower().strip(" ").replace("—",'').replace("-",'').split(" ")
words = words[:article_length]

for i in range(len(words)):
	try:
		words[i] = str(encoding[words[i]])
	except KeyError as e:
		words[i] = "2"
while len(words) < article_length:
			words.append('2')
article = np.expand_dims(np.reshape(np.asarray(words),(input_dimension, input_dimension)), axis = 0)
num_categories = 3

np.random.seed()
top_words = 10000
embedding_vector_length = 400

inputs = Input((input_dimension,input_dimension))
m = Lambda(lambda x : x)(inputs)
m = Reshape((article_length,))(m)
m = Embedding(top_words, embedding_vector_length, input_length=article_length)(m)
m = Reshape((input_dimension,input_dimension,embedding_vector_length,))(m)

m = Conv2D(filters = embedding_vector_length, kernel_size = (3,3),padding='same',  activation='relu')(m)
m = Conv2D(filters = embedding_vector_length, kernel_size = (3,3),padding='same',  activation='relu')(m)
m = MaxPooling2D((2, 2))(m)
m = Conv2D(filters = embedding_vector_length, kernel_size = (3,3),padding='same',  activation='relu')(m)
m = Conv2D(filters = embedding_vector_length, kernel_size = (3,3),padding='same',  activation='relu')(m)
m = MaxPooling2D((2, 2))(m)
m = Reshape((int((input_dimension / 4)**2),embedding_vector_length,))(m)
m = (Conv1D(filters=32, kernel_size=3, padding='same', activation='relu'))(m)
m = (BatchNormalization())(m)
m = (MaxPooling1D(pool_size=2))(m)
m = (SpatialDropout1D(0.1))(m)
m = (Conv1D(filters=32, kernel_size=3, padding='same', activation='relu'))(m)
m = (BatchNormalization())(m)
m = (MaxPooling1D(pool_size=2))(m)
m = (Dropout(0.1))(m)
m = (CuDNNLSTM(100))(m)
outputs = (Dense(num_categories, activation='softmax'))(m)
model = Model(inputs = [inputs], outputs = [outputs])
model.compile(loss='binary_crossentropy', optimizer=optimizers.SGD(lr=1e-3, momentum=0.9), metrics=['accuracy'])
model.load_weights('weights/56-0.21.h5')

prediction = model.predict(article)
print(prediction)
prediction = prediction[0]
category = max(prediction)

if category == prediction[0]:
	message = "health"
elif category == prediction[1]:
	message = "politics"
elif category == prediction[2]:
	message = "tech"

print("article is about " + message)


class Point:
    def __init__(self,x,y):
        self.x = x
        self.y = y
    def cal_distance(self,point2):
        point1 = self
        dist = (point1.x-point2.x)**2+(point1.y-point2.y)**2
        dist = dist**0.5
        return dist
p1 = Point(1,1)
p2 = Point(5,4)
print("The distance is {0}".format(p1.cal_distance(p2)))


import time
import cmd_ping
# in seconds how long to monitor network
monitorTime = 360
targetServer = '172.217.4.46'
#how long a connection has to wait before timeout (s)
timeout = 10
#how high ping has to spike to count as a spike
spikeThreshold = 300
#delay between pings (s)
delay = .2

logStream = open('logs.txt', 'w')
numPings = 0
spikeCount = 0
init_time = time.time()
current_time = time.strftime("%H:%M:%S", time.localtime())
print("Starting " + str(monitorTime) + "s Ping Test to " + targetServer + " at " + current_time)
while time.time() - init_time < monitorTime:
    start = time.time()
    result = cmd_ping.ping(targetServer, timeout, logStream)
    pingTime = (time.time() - start)*1000
    numPings += 1
    if not result:
        spikeCount += 1
        print("Request Timed out (>" + str(timeout) + "s)" + " at " + time.strftime("%H:%M:%S", time.localtime()))
    elif pingTime > spikeThreshold:
        spikeCount += 1
        print("Ping Spike of", pingTime, "at " + time.strftime("%H:%M:%S", time.localtime()))
    time.sleep(delay)
print("RESULTS:")
print(spikeCount, "Ping Spikes in", monitorTime, "seconds")


import flask, json
from flask import Flask, request, jsonify
from src import actor, movie, graph, JSON, scraper

app = Flask(__name__)

@app.errorhandler(404)
def not_found(error):
    return flask.make_response(jsonify({'error': 'Not found'}), 404)

@app.route('/')
def index():
    return "CS242 Assignment2.1 part 3: API Creation"

# ----------------------------- GET --------------------------------------

# /actors/all
# Get all actors name
@app.route('/actors/all', methods=['GET'])
def get_all_actors():
    return jsonify(list(g.actors.keys()))

# /actors/Bruce_Willis
@app.route('/actors/<string:actor_name>', methods=['GET'])
def get_actor_info(actor_name):
    name = actor_name.replace("_", " ")
    try:
        a = actor_data[name]
    except:
        return flask.make_response(jsonify({'error': 'Not found: ' + name}), 404)
    return jsonify(a)

# actors?name=Bruce_Willis&age=61
# /actors?name=Bob
@app.route('/actors', methods=['GET'])
def get_actor_by_filter():

    actor_name = request.args.get('name')
    name_list = []
    if actor_name:
        if '|' in actor_name:
            actor_names = actor_name.split("|")
            for n in actor_names:
                n = n.replace('_', ' ')
                name_list.append(n)
        else:
            name_list.append(actor_name.replace('_', ' '))
    print(name_list)

    actor_age = request.args.get('age')
    age_list = []
    if actor_age:
        if '|' in actor_age:
            actor_ages = actor_age.split('|')
            for n in actor_ages:
                age_list.append(int(n))
        else:
            age_list.append(int(actor_age))
    print(age_list)

    result = {}
    for a in list(g.actors.keys()):
        if not name_list:
            if actor_data[a]["age"] in age_list:
                result[a] = actor_data[a]

        else:
            if actor_data[a]["age"] in age_list or not age_list:
                for an in name_list:
                    if an == a or an in a:
                        result[a] = actor_data[a]

    if result == {}:
        return flask.make_response(jsonify({'Error': 'Not found'}), 404)

    return flask.make_response(jsonify(result), 200)

# /movies/all
# Get all movies name
@app.route('/movies/all', methods=['GET'])
def get_all_movies():
    return jsonify(list(g.movies.keys()))

# /movies/Toys
@app.route('/movies/<string:movie_name>', methods=['GET'])
def get_movie_info(movie_name):
    name = movie_name.replace("_", " ")
    try:
        m = movie_data[name]
    except:
        return flask.make_response(jsonify({'error': 'Not found: ' + name}), 404)
    return jsonify(m)

# /movies?name=Sunset&year=1988
# /movies?name=Toys
#http://127.0.0.1:5000/movies?name=Sunset|Toys&year=1988

@app.route('/movies', methods=['GET'])
def get_movie_by_filter():

    movie_name = request.args.get('name')
    name_list = []
    if movie_name:
        if '|' in movie_name:
            movie_names = movie_name.split("|")
            for n in movie_names:
                n = n.replace('_', ' ')
                name_list.append(n)
        else:
            name_list.append(movie_name.replace('_', ' '))
    print(name_list)

    movie_year = request.args.get('year')
    year_list = []
    if movie_year:
        if '|' in movie_year:
            movie_years = movie_year.split('|')
            for n in movie_years:
                year_list.append(int(n))
        else:
            year_list.append(int(movie_year))
    print(year_list)

    result = {}
    for a in list(g.movies.keys()):
        if not name_list:
            if movie_data[a]["year"] in year_list:
                result[a] = movie_data[a]
        else:
            if movie_data[a]["year"] in year_list or not year_list:
                for an in name_list:
                    if an == a or an in a:
                        result[a] = movie_data[a]

    if result == {}:
        return flask.make_response(jsonify({'Error': 'Not found: '}), 404)

    return flask.make_response(jsonify(result), 200)

# ----------------------------- PUT --------------------------------------

# Leverage PUT requests to update standing content in backend
# curl -i -X PUT -H "Content-Type: application/json" -d '
# {"total_gross":500}'http://localhost:4567/api/a/actors/Bruce_Willis
@app.route('/actors/update/<string:name>', methods=['PUT'])
def put_actor(name):

    name = name.replace('_', ' ')
    if name not in [*data[0]]:
        return flask.make_response(jsonify({'Error':  name + ' not exists in backend'}), 404)

    ndata = request.get_json()
    for item in ndata:
        try:
            data[0][name][item] = ndata[item]
        except:
            return flask.make_response(jsonify({'Error': item + ' not found'}), 404)

    with open("data copy.json", 'w') as f:
        json.dump(data, f, indent=2)

    return flask.make_response(jsonify({'Success': name + ' updated'}), 200)

@app.route('/movies/update/<string:name>', methods=['PUT'])
def put_movie(name):

    name = name.replace('_', ' ')
    if name not in [*data[1]]:
        return flask.make_response(jsonify({'Error':  name + ' not exists in backend'}), 404)

    ndata = request.get_json()
    for item in ndata:
        try:
            data[1][name][item] = ndata[item]
        except:
            return flask.make_response(jsonify({'Error': item + ' not found'}), 404)

    with open("data copy.json", 'w') as f:
        json.dump(data, f, indent=2)

    return flask.make_response(jsonify({'Success': name + ' updated'}), 200)

# ----------------------------- POST --------------------------------------

@app.route('/actors/add/<string:name>', methods=['POST'])
def add_actor(name):

    name = name.replace('_', ' ')
    if name in [*data[0]]:
        return flask.make_response(jsonify({'Error': name + ' already exists in backend'}), 404)

    ndata = request.get_json()
    data[0][name] = ndata

    with open("data copy.json", 'w') as f:
        json.dump(data, f, indent=2)

    return flask.make_response(jsonify({'Success': name + ' updated'}), 200)

@app.route('/movies/add/<string:name>', methods=['POST'])
def add_movie(name):

    name = name.replace('_', ' ')
    if name in [*data[1]]:
        return flask.make_response(jsonify({'Error': name + ' already exists in backend'}), 404)

    ndata = request.get_json()
    data[1][name] = ndata

    with open("data copy.json", 'w') as f:
        json.dump(data, f, indent=2)

    return flask.make_response(jsonify({'Success': name + ' updated'}), 200)

# ----------------------------- DELETE --------------------------------------

# http://localhost:5000/actor/delete/name_new_1
@app.route('/actors/delete/<string:name>', methods=['DELETE'])
def delete_actor(name):

    name = name.replace('_', ' ')
    if name not in [*data[0]]:
        return flask.make_response(jsonify({'Error': name + ' not exists in backend'}), 404)

    try:
        del data[0][name]
    except:
        return flask.make_response(jsonify({'Error: Cannot Delete'}), 404)

    with open("data copy.json", 'w') as f:
        json.dump(data, f, indent=2)

    return flask.make_response(jsonify({'Success': name + ' deleted'}), 200)

@app.route('/movies/delete/<string:name>', methods=['DELETE'])
def delete_movie(name):

    name = name.replace('_', ' ')
    if name not in [*data[1]]:
        return flask.make_response(jsonify({'Error': name + ' not exists in backend'}), 404)

    try:
        del data[1][name]
    except:
        return flask.make_response(jsonify({'Error: Cannot Delete'}), 404)

    with open("data copy.json", 'w') as f:
        json.dump(data, f, indent=2)

    return flask.make_response(jsonify({'Success': name + ' deleted'}), 200)

if __name__ == '__main__':

    data = json.loads(open('data copy.json').read())

    g, actor_data, movie_data = JSON.retrieve_from_Json('data.json')

    app.run(debug=True)


import numpy as np
from .testing_set_generator import TestingSetGenerator
from main.codebase.models.euclidean import Vivaldi
from main.codebase.models.matrix_completion import SimpleMF, PenaltyDecomposition, NMFWrapper, SVDWrapper
from main.codebase.models.networks3d import Networks3D, Networks3DAlg2
from main.codebase.models.time_series import SES, TSMF, TSMFAbstract,TSMFV2
from .config import *
from functools import reduce
import argparse
import logging
import os
import sys
import pandas as pd
from datetime import datetime
from time import time
from joblib import Parallel, delayed

np.random.seed(5)
parser = argparse.ArgumentParser()
parser.add_argument("--verbose", "-v", dest='verbosity', help="increase output verbosity",
                    action="store_true")
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument('-a',"--all",dest="test_all_models", action="store_true", help="Test on all models")
group.add_argument('-m','--models',dest='model_list', nargs='+', help='Models to evaluate')
parser.add_argument('-p', '--processes', dest='processes', type=int)
parser.add_argument("test_size", help="Size of test set to evaluate models on", type=int)
parser.add_argument("missing_value_ratio", help='Ratio of missing values in matrices',type=float)
parser.add_argument("fpath", help='Path to matrices', type=str)
args = parser.parse_args()

logFormatter = logging.Formatter("[%(asctime)s] [%(levelname)-5.5s]  %(message)s")
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
logPath = 'output/logs'
if not os.path.exists('output/Accuracy'):
        logger.info('creating directory Accuracy')
        os.makedirs('output/Accuracy')
if not os.path.exists('output/logs'):
        os.makedirs('output/logs')
if args.verbosity:
   print("verbosity turned on")
   fileHandler = logging.FileHandler("{0}/eval-run{1}.log".format(logPath, datetime.now().isoformat()))
   fileHandler.setFormatter(logFormatter)
   logger.addHandler(fileHandler)
   handler = logging.StreamHandler(sys.stdout)
   handler.setFormatter(logFormatter)
   logger.addHandler(handler)
logger.info("Loading Testing Set Generator")
ts = TestingSetGenerator(fpath=args.fpath, missing_value_ratio=args.missing_value_ratio, test_set_size=args.test_size, lags=LAGS)

def get_true_results(M, M_true):
    y_test = M_true[np.isnan(M)]
    y_test = y_test[y_test.nonzero()]
    return y_test

def get_results(M, M_true, M_hat):
    y_hat = M_hat[np.isnan(M)]
    y_test = M_true[np.isnan(M)]
    y_hat = y_hat[y_test.nonzero()] #zero values crash relative error calculation
    rows_of_nan_entries = np.where( (np.isnan(M)) & (M_true!=0) )[0]
    assert y_hat.shape[0] == rows_of_nan_entries.shape[0]
    return y_hat, rows_of_nan_entries

models = {}
models['SimpleMF'] = SimpleMF
# models['Vivaldi'] = Vivaldi
# models['PenaltyDecomposition'] = PenaltyDecomposition
# models['Networks3D'] = Networks3D
# models['Networks3DAlg2'] = Networks3DAlg2
models['TSMF'] = TSMF
models['TSMFV2'] = TSMFV2
models['SES'] = SES
models['SVD'] = SVDWrapper(rank=10)
models['NMF'] = NMFWrapper(rank=10)
models['TSMF-SVD'] = TSMFAbstract(models['SVD'],SES(**parameters['SES']))
models['TSMF-NMF'] = TSMFAbstract(models['NMF'],SES(**parameters['SES']))
models_set = list(models.keys())
if args.test_all_models:
    logger.info("Testing on all models")
elif args.model_list:
    for m in models_set:
        if m not in args.model_list:
            models.pop(m)

eval_df = {}
logger.info("Beginning evaluation on models :\n {}".format('\t'.join(models.keys())))
for i in range(len(ts.test_set)):
    logger.info("Run {}/{}".format(i+1, args.test_size))
    ix = ts.test_set_indices[i]
    logger.info("On matrix ID {}".format(ix))
    M = ts.test_set_missing[i]
    M_true = ts.test_set[i]
    if 'true' in eval_df:
        eval_df['true'] = np.concatenate([eval_df['true'], get_true_results(M, M_true)])
    else:
        eval_df['true'] = get_true_results(M, M_true)

def eval_on_model(model_label, i):
    ix = ts.test_set_indices[i]
    M = ts.test_set_missing[i]
    start = time()
    if model_label in parameters:
        model = models[model_label](**parameters[model_label])
    elif model_label not in ['SVD','NMF','TSMF-SVD', 'TSMF-NMF']:
        model = models[model_label]()
    else:
        model = models[model_label]
    if model_label=='Networks3DAlg2':
        model.fit(ts.matrices_with_missing[:ix+1])
    elif model_label in ['TSMF', 'SES', 'TSMF-SVD', 'TSMF-NMF', 'TSMFV2']:
        model.fit(ts.matrices_with_missing, ix)
    else:
        model.fit(M)
    M_hat = model.predict()
    logger.info("Evaluation completed on {}, took {}s".format(model_label,time()-start))
    return M_hat
totals = []
users = []
INIT = True

for model_label in models:
        logger.info("Starting on model {}".format(model_label))
        mhats = Parallel(n_jobs=args.processes,verbose=1)(delayed(eval_on_model)(model_label,i) for i in range(len(ts.test_set)))
        for i in range(len(ts.test_set)):
            M_true = ts.test_set[i]
            M = ts.test_set_missing[i]
            M_hat = mhats[i]
            mhats[i],rows = get_results(M, M_true, M_hat)
            if INIT:
                users.append(rows)
                totals.append(len(mhats[i]))
        INIT = False
        eval_df[model_label] = np.concatenate(mhats)
labels = []
for i,ix in enumerate(ts.test_set_indices):
    label = ['matrixid-{}'.format(ix) for _ in range(totals[i])]
    labels+= label
eval_df['label'] = labels
eval_df['user'] = np.concatenate(users)

eval_df = pd.DataFrame(eval_df)
eval_df.to_csv('output/Accuracy/evaluation_run_{}-{}-{}-{}.csv'.format(datetime.now().isoformat(),args.test_size, args.missing_value_ratio,args.fpath.split('/')[-2]))
print(eval_df)
for k,v in parameters.items():
    logger.info("Model {}\nParameters:\n{}".format(k,'\n'.join(['{}\t{}'.format(label,val) for label, val in v.items()])))


from unittest import mock

from flask import url_for

from parser import MemoryGameRepository

class TestHealthCheck:

    def test_should_ping_return_pong(self, client):
        response = client.get(url_for('ping'))
        assert response.status_code == 200
        assert response.get_data() == b'pong!'

class TestGameAPI:

    @mock.patch.object(MemoryGameRepository, 'store', {})
    def test_should_get_games(self, client, game_with_player_with_one_kill):
        memory_repo = MemoryGameRepository()
        memory_repo.add(game_with_player_with_one_kill)
        game_uid = game_with_player_with_one_kill.uid
        response = client.get(url_for('get_games'))
        assert response.status_code == 200
        assert 'games' in response.json
        assert response.json['games'][0]['uid'] == game_uid
        assert response.json['games'][0]['total_kills'] == 1

    @mock.patch.object(MemoryGameRepository, 'store', {})
    def test_should_get_game_by_uid(self, client, game_with_player_with_one_kill):
        memory_repo = MemoryGameRepository()
        memory_repo.add(game_with_player_with_one_kill)
        game = memory_repo.get_active_game()
        response = client.get(url_for('get_game_by_uid', uid=game.uid))
        assert response.status_code == 200
        assert game.total_kills == response.json['total_kills']
        assert [p.name for p in game.players] == response.json['players']

    def test_should_return_not_found_when_get_games_by_uid(self, client):
        response = client.get(url_for('get_game_by_uid', uid='asdasd'))
        assert response.status_code == 404
        assert response.json['message'] == 'Game not found'


from itertools import combinations

n = int(input())
arr = list(map(int, input().split()))
summ = sum(arr)
if n == 1:
    print(arr[0])
    exit()
ans = summ
for i in range(1, n):
    temp = combinations(arr, i)
    for ele in temp:
        val = sum(ele)
        ans = min(ans, abs(summ - 2 * val))
print(ans)


import discord
from discord.ext import commands
import traceback

class Admin(commands.Cog):
    """Admin-only commands that make the bot dynamic."""

    def __init__(self, bot):
        self.bot = bot

    async def cog_check(self, ctx):
        return await self.bot.is_owner(ctx.author)

    @commands.command(hidden=True)
    async def load(self, ctx, *, module):
        """Loads a module."""
        try:
            self.bot.load_extension(module)
        except commands.ExtensionError as e:
            await ctx.send(f'{e.__class__.__name__}: {e}')
            traceback.print_exc()
        else:
            await ctx.send('\N{OK HAND SIGN}')

    @commands.command(hidden=True)
    async def unload(self, ctx, *, module):
        """Unloads a module."""
        try:
            self.bot.unload_extension(module)
        except commands.ExtensionError as e:
            await ctx.send(f'{e.__class__.__name__}: {e}')
        else:
            await ctx.send('\N{OK HAND SIGN}')

    @commands.command(name='reload', hidden=True)
    async def _reload(self, ctx, *, module):
        """Reloads a module."""
        try:
            self.bot.reload_extension(module)
        except commands.ExtensionError as e:
            await ctx.send(f'{e.__class__.__name__}: {e}')
            traceback.print_exc()
        else:
            await ctx.send('\N{OK HAND SIGN}')

def setup(bot):
    bot.add_cog(Admin(bot))


def read_file(fname):
    try:
        f = open(fname,'rt') #Genera error
        text = f.read()
    except FileNotFoundError:
        text = f'No existe el fichero{fname} en el directorio'
    return text

print(read_file('sample.txt'))
print(read_file('sample2.txt'))


from data import question_data
from question_model import Question
from quiz_brain import QuizBrain

question_bank = []
is_right = True
has_questions = True
for question in question_data:
    q_text = question["text"]
    q_answer = question["answer"]
    question = Question(q_text, q_answer)
    question_bank.append(question)

quiz_brain = QuizBrain(question_bank)

while has_questions:
    quiz_brain.next_question()
    has_questions = quiz_brain.still_has_questions()

print("Congratulations. You completed the quiz")
print(f"Your final score is: {quiz_brain.score}/{len(question_bank)}")