import json
import spacy
from spacy_download import load_spacy

#before running :
# python -m spacy download en_core_web_trf
#following https://towardsdatascience.com/building-sentiment-classifier-using-spacy-3-0-transformers-c744bfc767b
#to train:
# python -m spacy train config.cfg --output ./data/units/unit_models/train_\".spacy --paths.train ./data/units/train/spacy_train/train_set_\".spacy --paths.dev ./data/units/train/spacy_train/train_set_\".spacy
# python -m spacy train config.cfg --output ./data/units/unit_models/train_\'.spacy --paths.train ./data/units/train/spacy_train/train_set_\'.spacy --paths.dev ./data/units/train/spacy_train/train_set_\'.spacy
# python -m spacy train config.cfg --output ./data/units/unit_models/train_a.spacy --paths.train ./data/units/train/spacy_train/train_set_a.spacy --paths.dev ./data/units/train/spacy_train/train_set_a.spacy
# python -m spacy train config.cfg --output ./data/units/unit_models/train_b.spacy --paths.train ./data/units/train/spacy_train/train_set_b.spacy --paths.dev ./data/units/train/spacy_train/train_set_b.spacy
# python -m spacy train config.cfg --output ./data/units/unit_models/train_c.spacy --paths.train ./data/units/train/spacy_train/train_set_c.spacy --paths.dev ./data/units/train/spacy_train/train_set_c.spacy
# python -m spacy train config.cfg --output ./data/units/unit_models/train_dram.spacy --paths.train ./data/units/train/spacy_train/train_set_dram.spacy --paths.dev ./data/units/train/spacy_train/train_set_dram.spacy
# python -m spacy train config.cfg --output ./data/units/unit_models/train_F.spacy --paths.train ./data/units/train/spacy_train/train_set_F.spacy --paths.dev ./data/units/train/spacy_train/train_set_F.spacy
# python -m spacy train config.cfg --output ./data/units/unit_models/train_kn.spacy --paths.train ./data/units/train/spacy_train/train_set_kn.spacy --paths.dev ./data/units/train/spacy_train/train_set_kn.spacy
# python -m spacy train config.cfg --output ./data/units/unit_models/train_kt.spacy --paths.train ./data/units/train/spacy_train/train_set_kt.spacy --paths.dev ./data/units/train/spacy_train/train_set_kt.spacy
# python -m spacy train config.cfg --output ./data/units/unit_models/train_p.spacy --paths.train ./data/units/train/spacy_train/train_set_p.spacy --paths.dev ./data/units/train/spacy_train/train_set_p.spacy
# python -m spacy train config.cfg --output ./data/units/unit_models/train_pound.spacy --paths.train ./data/units/train/spacy_train/train_set_pound.spacy --paths.dev ./data/units/train/spacy_train/train_set_pound.spacy
# python -m spacy train config.cfg --output ./data/units/unit_models/train_R.spacy --paths.train ./data/units/train/spacy_train/train_set_R.spacy --paths.dev ./data/units/train/spacy_train/train_set_R.spacy
# python -m spacy train config.cfg --output ./data/units/unit_models/train_¥.spacy --paths.train ./data/units/train/spacy_train/train_set_¥.spacy --paths.dev ./data/units/train/spacy_train/train_set_¥.spacy
# python -m spacy train config.cfg --output ./data/units/unit_models/train_′.spacy --paths.train ./data/units/train/spacy_train/train_set_′.spacy --paths.dev ./data/units/train/spacy_train/train_set_′.spacy
# python -m spacy train config.cfg --output ./data/units/unit_models/train_″.spacy --paths.train ./data/units/train/spacy_train/train_set_″.spacy --paths.dev ./data/units/train/spacy_train/train_set_″.spacy
# python -m spacy train config.cfg --output ./data/units/unit_models/train_BIGP.spacy --paths.train ./data/units/train/spacy_train/train_set_BIGP.spacy --paths.dev ./data/units/train/spacy_train/train_set_BIGP.spacy
# python -m spacy train config.cfg --output ./data/units/unit_models/train_BIGC.spacy --paths.train ./data/units/train/spacy_train/train_set_BIGC.spacy --paths.dev ./data/units/train/spacy_train/train_set_BIGC.spacy
# python -m spacy train config.cfg --output ./data/units/unit_models/train_BIGB.spacy --paths.train ./data/units/train/spacy_train/train_set_BIGB.spacy --paths.dev ./data/units/train/spacy_train/train_set_BIGB.spacy

from pathlib import Path
from spacy.tokens import DocBin
TOPDIR = Path(__file__).parent.parent.parent
ambigious_units={'c': ['cent', 'celsius'],
                 '¥': ['chinese yuan', 'japanese yen'],
                 'kn': ['croatian kuna', 'knot'], 'p': ['point', 'penny'],
                 'R': ['south african rand', 'roentgen'], 'b': ['barn', 'bit'], "'": ['foot', 'minute'],
                 '′': ['foot', 'minute'], '"': ['inch', 'second'], '″': ['inch', 'second'], 'C': ['celsius', 'coulomb'],
                 'F': ['fahrenheit', 'farad'], 'kt': ['kiloton', 'knot'], 'B': ['byte', 'bel'],
                 'P': ['poise', 'pixel'],'dram': ['armenian dram', 'dram'], 'pound': ['pound sterling', 'pound-mass'],
                 'a': ['acre', 'year']}

def training_set_per_unit(units,training_data_path):
    training_set_ = []
    path=TOPDIR.joinpath(training_data_path)
    for file in path.iterdir():
        if file.suffix == ".json":
            with file.open("r", encoding="utf-8") as train_file:
                train_json=json.load(train_file)
                for line in train_json:
                    if line["unit"] in units:
                        training_set_.append(line)

    target_names = list(frozenset([i["unit"] for i in training_set_]))
    target_names_dict={}
    for i,name in enumerate(target_names):
        target_names_dict[name]=i

    tuples=[]
    for row in training_set_:
        tuples.append((row["text"],row["unit"]))
    return tuples,target_names_dict

def document(data,target_names_dict):
    #Creating empty list called "text"
    text = []
    nlp=load_spacy("en_core_web_trf")
    for doc, label in nlp.pipe(data, as_tuples = True):
        for name,i in target_names_dict.items():
            if name==label:
                doc.cats[name]=1
            else:
                doc.cats[name]=0
        text.append(doc)

    return(text)

if __name__ == '__main__':
    training_data_path="data/units/train"#locatin of the the raw json file as training
    training_data_output="data/units/train/spacy_train/"#locatin of the outputs from spacy in bin format

    for key,values in ambigious_units.items():
        print("for surface form :",key)
        training_set,target_names_dict = training_set_per_unit(values,training_data_path)
        print("total number of samples",len(training_set))
        print("passing the train dataset into function 'document'....")
        train_docs = document(training_set,target_names_dict)
        print("Creating binary document using DocBin function in spaCy...")
        doc_bin = DocBin(docs = train_docs)
        print("Saving the binary document as train.spacy...." +training_data_output+"train_set_"+key+".spacy")
        if key=="C" or key=="B" or key=="P":
            doc_bin.to_disk(TOPDIR.joinpath(training_data_output+"train_set_BIG"+key+".spacy"))
        else:
            doc_bin.to_disk(TOPDIR.joinpath(+training_data_output+"/train_set_"+key+".spacy"))
        print("=====================")


import socket
import time
import threading

PORT = 10101
HOST = "localhost"

def process_user_input(client_socket, username):
    # Show user interface
    users, messages = get_interface_data(client_socket)
    display_interface(users, messages)

    user_connected = True

    while user_connected:

        user_msg = input()
        if user_msg.lower() == "quit":
            user_connected = False
        else:
            client_socket.send("send {}\r\n".format(user_msg).encode())
            client_socket.recv(1024)

def get_interface_data(client_socket):
    # Get users
    client_socket.send(b"get users\r\n")
    users = client_socket.recv(1024).decode().rstrip("\r\n").split(",")

    # Get messages
    client_socket.send(b"get messages\r\n")
    response = client_socket.recv(1024).decode()

    messages = []

    response_msgs = response.rstrip("\r\n").split("\r\n")
    if response_msgs[0] != "":
        for msg in response.rstrip("\r\n").split("\r\n"):
            split_msg = msg.split("::")
            messages.append((split_msg[0], split_msg[1]))

    return users, messages

def display_interface(users, messages):
    print("\n" * 100)
    print("\n### Users ###")
    for user in users:
        print(user)

    print("\n### Messages ###")
    for msg in messages:
          print("{}: {}".format(msg[0], msg[1]))

    print("\nEnter a message (or QUIT): ")

def create_listener(host, port):
    listen_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    listen_socket.connect((host, port))
    listen_socket.send(b"listen\r\n")
    listen_socket.recv(1024)
    listen_thread = threading.Thread(target=listen, args=(listen_socket,))
    listen_thread.start()

def listen(listen_socket):
    while True:
        msg = listen_socket.recv(1024).decode().rstrip("\r\n")
        msg_lines = msg.split("\r\n")
        users = msg_lines[0].split(":")[1].split(",")
        messages = []
        for line in msg_lines[2:]:
            tokens = line.split("::")
            messages.append((tokens[0], tokens[1]))
        display_interface(users, messages)

if __name__ == "__main__":
    print("Connecting to server...")

    client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    client_socket.connect((HOST, PORT))

    print("Connected!")

    username = input("Hello, please enter a username: ")
    client_socket.send("hello {}\r\n".format(username).encode())
    client_socket.recv(1024)

    create_listener(HOST, PORT)

    process_user_input(client_socket, username)


from django.db import models

from category.models import Category
from user.models import TimeStampedModel, User

class Question(TimeStampedModel):
    title = models.CharField(max_length=255)
    contents = models.TextField(blank=True, default="")
    writer = models.ForeignKey(
        User, on_delete=models.CASCADE)
    is_completed = models.BooleanField(default=False)
    category = models.ForeignKey(
        Category, on_delete=models.CASCADE, null=True
    )
    point = models.IntegerField(default=0)
    limit = models.IntegerField(default=1800)
    is_open = models.BooleanField(default=True)
    user_class = models.CharField(max_length=64, blank=True)
    region = models.CharField(max_length=64, blank=True)

    def __str__(self):
        return self.title


import sys
import os
from sklearn.naive_bayes import BernoulliNB
from sklearn.feature_extraction.text import CountVectorizer
from nltk.corpus import stopwords
import numpy as np
from sklearn.externals import joblib
from sklearn.base import clone
from sklearn.dummy import DummyClassifier
from scipy import sparse

sys.path.insert(0, './data_files_scripts')

class Classify:
    """
    A classifier which can categorize tweets into one or more of the
    25 categories, as required by TREC.
    """
    catadictionary={'GoodsServices':0, 'SearchAndRescue':1,'InformationWanted':2,'Volunteer':3,'Donations':4,
                    'MovePeople':5, 'FirstPartyObservation': 6, 'ThirdPartyObservation': 7, 'Weather': 8,
                    'EmergingThreats': 9, 'SignificantEventChange':10, 'MultimediaShare': 11, 'ServiceAvailable': 12,
                    'Factoid': 13, 'Official': 14, 'CleanUp':15, 'Hashtags': 16, 'PastNews': 17, 'ContinuingNews': 18,
                    'Advice': 19, 'Sentiment':20, 'Discussion': 21, 'Irrelevant': 22, 'Unknown': 23, 'KnownAlready': 24}
    actionable = ['SearchAndRescue', 'MovePeople', 'InformationWanted']
    knowledge = ['FirstPartyObservation', 'EmergingThreats',
                 'SignificantEventChange', 'MultimediaShare', 'Official']

    def __init__(self, tweet_texts=None, cats=None, vocab_size=2000, model=BernoulliNB(alpha = 0.1),
        pretrained=None):
        """
        Create and train classifier. Can specify path to pretrained
        classifiers using "pretrained"

        :param tweet_texts: list of tweets to train classifier on
        :param cats: matrix of categories that belong to the tweets
        :param vocab_size: maximum number of words in classifier
        :param model: model to use for classification
        :param pretrained: path to pretained classifiers, if using
                            pretrained classifiers
        """
        self.cat = cats
        self.text = tweet_texts
        self.model = model
        self.classifiers = list()
        self.vectorizer = None
        self.vect_train = None

        if pretrained is None:
            self.train(vocab_size=vocab_size)
        else: # load pretrained classifiers
            for f in sorted(os.listdir(pretrained)):
                fn = os.fsdecode(f)
                if fn.endswith('v.pkl'):
                    self.vectorizer = joblib.load(pretrained+fn)
                else:
                    self.classifiers.append(joblib.load(pretrained+fn))

    def train(self, text=None, cats=None, vocab_size=2000):
        """
        Fits classifiers to the training data provided. If
        already trained, clears classifiers and retrains.

        :param text: tweets to train on. defaults to tweets provided
            on creation
        :param cats: actual labels
        :param vocab_size: number of words as max features
        """
        if text is None:
            text = self.text
        if cats is None:
            cats = self.cat

        # fit vectorizer
        self.vectorizer = CountVectorizer(stop_words=stopwords.words(),
                                          binary=True,
                                          max_features=vocab_size)
        self.vect_train = self.vectorizer.fit_transform(text)

        # add feature determining if hashtag in tweet
        hashtags = np.array([[1] if '#' in t else [0] for t in text])
        addtl_feat = sparse.hstack([self.vect_train, hashtags])

        # clear classifiers (in case of retraining)
        self.classifiers = list()

        cat_arr = np.array(cats) # convert to array

        # train
        for i in range(0, len(cat_arr[0])):
            # unknown should not be predicted unless no other category found
            # so use dummy classifier only predicting 0 for unknown
            if i == self.catadictionary['Unknown']:
                m = DummyClassifier('constant', constant=0)
            else:
                # clone original model. "clone" is needed or it will
                # just keep training the original model on all categories
                m = clone(self.model)
            # fit model and append to list of models
            c = m.fit(addtl_feat, cat_arr[:,i])
            self.classifiers.append(c)

    def save_classifier(self, path='pretrained/'):
        """
        Saves the classifier to the specified path

        :param path: directory to save classifier and vectorizer into
        """
        # save vectorizer
        joblib.dump(self.vectorizer, path+'v.pkl', compress=1)
        # save classifiers
        for n in range(0,len(self.classifiers)):
            joblib.dump(self.classifiers[n], path+'c%02d.pkl' % n, compress=1)
        print("Classifiers saved to: " + path)

    def map_id(self, category):
        """
        Return the indices of the given categories e.g. 0 = 'Advice'

        :param category: categories to lookup

        :return: list of int index
        """
        returner = []
        for c in category:
            if c in self.catadictionary:
                returner.append(self.catadictionary.get(c))
        return returner

    def mat_all_categories(self, actual, prediction):
        """
        Evaluator returning confusion matrices for all categories
        as a dictionary, with the keys being the categories and
        values being confusion matrix dictionaries

        :param actual: actual category matrix
        :param prediction: prediction matrix

        :return: dictionary of confusion matrix by category
        """
        ind_to_cat = self.category_indices()
        ret = dict()
        actual_arr = np.array(actual)
        prediction_arr = np.array(prediction)
        for n in range(0, len(actual[0])):
            vals = self.mat_one_category(actual_arr[:,n], prediction_arr[:,n])
            ret[ind_to_cat[n]] = vals
        return ret

    def mat_one_category(self, actual, prediction):
        """
        Evaluator returning confusion matrix for a single category as a dict

        :param actual: numpy array of binary category vals
        :param prediction: binary numpy array of predictions

        :return: dict of number of predictions,
                true pos, true neg, false pos,
                and false neg for predictions
        """
        eval = {'Number of Predictions': len(actual),
                'True Positive': 0, 'True Negative': 0,
                'False Positive': 0, 'False Negative': 0}

        for x in range(0, len(actual)):
            if actual[x] == 1:
                if prediction[x] == 1:
                    eval['True Positive'] += 1
                else:
                    eval['False Negative'] +=1
            else:
                if prediction[x] == 1:
                    eval['False Positive'] += 1
                else:
                    eval['True Negative'] += 1
        return eval

    def evaluate(self, actual, prediction):
        """
        Evaluator, returning overall confusion matrix, accuracy
        recall, precision, f1, one label, category, and perfect match
        scores as a dictionary

        :param actual: a matrix of actual binary values
        :param prediction: a matrix of the predicted binary values

        :return: dictionary of number of predictions, true/false
                positive/negative, number of rows with at least 1
                true positive, number of perfect match rows,
                accuracy, precision, recall, f1, one label,
                and perfect match scores
        """
        # result matrix
        evaluation_mat = {'Number of Predictions': len(actual)*len(actual[0]),
                          'True Positive': 0, 'True Negative': 0,
                          'False Positive': 0, 'False Negative': 0,
                          'One Label': 0, 'Perfect Match': 0}
        one_label = False # used to check if at least one label in current row is true pos

        # evaluate by row
        for x in range(0, len(actual)):
            # check for perfect match
            if np.array_equal(actual[x], prediction[x]):
                evaluation_mat['Perfect Match'] += 1

            # iterate through predictions
            for y in range(0, len(actual[x])):
                if actual[x][y] == 1:
                    if prediction[x][y] == 1:
                        # both positive
                        evaluation_mat['True Positive'] += 1
                        one_label = True
                    else:
                        # prediction negative, actually positive
                        evaluation_mat['False Negative'] += 1
                else:
                    if prediction[x][y] == 1:
                        # prediction positive, actually negative
                        evaluation_mat['False Positive'] += 1
                    else:
                        # both negative
                        evaluation_mat['True Negative'] += 1

            # check if at least one true pos
            if one_label:
                evaluation_mat['One Label'] += 1
            one_label = False

        # once all rows checked, use confusion matrix and one label /
        # perfect match counts to calculate other statistics
        stats = self.stats_calc(evaluation_mat['True Positive'],
                                evaluation_mat['True Negative'],
                                evaluation_mat['False Positive'],
                                evaluation_mat['False Negative'],
                                evaluation_mat['One Label'],
                                evaluation_mat['Perfect Match'],
                                cats=len(actual[0]))
        ret = {**evaluation_mat, **stats}
        return ret

    def predict(self, tweets):
        """
        Returns an array of predictions for the given features.

        :param tweets: a list or array of string tweets
        :returns: predictions matrix

        :throws RuntimeError: if classifiers have not been trained
        """
        if len(self.classifiers) == 0:
            raise RuntimeError("Classifiers have not been trained!")
        tokenized = self.vectorizer.transform(tweets)
        hashtags = [[1] if '#' in t else [0] for t in tweets]
        addtl_feat = sparse.hstack([tokenized, hashtags])

        predictions = np.zeros((len(tweets), len(self.classifiers)))

        for i in range(0, len(self.classifiers)):
            predictions[:, i] = self.classifiers[i].predict(addtl_feat)

        # if nothing predicted, category should be unknown
        for row in predictions:
            if np.sum(row) == 0:
                row[self.catadictionary['Unknown']] = 1
        return predictions

    def stats_calc(self, tp, tn, fp, fn, one_lab, perf_match, cats=25):
        """
        Calculate summary statistics, return as dict.

        :param tp: # of true postitives
        :param tn: # of true negatives
        :param fp: # of false positives
        :param fn: # of false negatives
        :param one_lab: # with 1 true positive
        :param perf_match: # with all labels correct

        :return: dict of scores
        """
        ret = dict()
        n = tp + tn + fp + fn

        # one label/perfect match is out of number of
        # tweets, not predictions
        t = n/cats
        ret['One Label Score'] = one_lab/t
        ret['Perfect Match Score'] = perf_match/t
        ret['Accuracy'] = (tp+tn)/n
        try:
            ret['Precision'] = tp/(tp+fp)
        except ZeroDivisionError:
            ret['Precision'] = 0
        try:
            ret['Recall'] = tp/(tp+fn)
        except ZeroDivisionError:
            ret['Recall'] = 0
        try:
            ret['F1 Score'] = (2*(ret['Precision']*ret['Recall']))/(ret['Precision']+ret['Recall'])
        except ZeroDivisionError:
            ret['F1 Score'] = 0
        return ret

    def category_indices(self):
        """
        Return dict of index to category, based on the catadict
        """
        ret = dict()
        for key in self.catadictionary:
            ret[self.catadictionary[key]] = key
        return ret

    def special_mats(self, mat):
        """
        Calculate knowledge and actionable confusion matrices from a category confusion matrix dict

        :param mat: a dictionary of conf matrices for categories as formed by self.mat_all_categories

        :return: dictionary of name to dict confusion matrix

        :raise ValueError: if any of the stats in self.actionable or self.knowledge don't appear in mat
        """
        act = {'Number of Predictions': 0,
               'True Positive': 0, 'True Negative': 0,
               'False Positive': 0, 'False Negative': 0}
        know = {'Number of Predictions': 0,
                'True Positive': 0, 'True Negative': 0,
                'False Positive': 0, 'False Negative': 0}
        for m in self.actionable:
            if m in mat:
                for stat in mat[m]:
                    act[stat] += mat[m][stat]
            else:
                raise ValueError("Incorrectly formed dictionary passed to calculate actionable stats.")
        for m in self.knowledge:
            if m in mat:
                for stat in mat[m]:
                    know[stat] += mat[m][stat]
            else:
                raise ValueError("Incorrectly formed dictionary passed to calculate knowledge stats.")
        return {'Actionable': act, 'Knowledge': know}


def n_primos(n):
    i = 2
    qtd = 0
    while(i<=n):
        eh_primo = ehprimo(i)
        if eh_primo:
            qtd = qtd + 1
        i = i + 1
    return qtd
def ehprimo(n):
    d = 2
    metade = n//2
    primo = True
    while d < metade + 1:
        if n % d == 0:
            primo = False
        d = d + 1
    return primo
n = 0
n = int(input("Digite um numero: "))
while(n<2):
    print("Numero invalido!")
    n = int(input("Digite um numero: "))
print(n_primos(n))


"""
 * File Name: views.py
 * Description: Used to get the last 24 hour summary of all active markets and specific market.
 * Author: Dineshkumar Dhayalan
 * Author Email: dineshkumar.dhayalan@ltts.com
"""
from app.CommonLib import helper
from app.CommonLib.security_helper import TokenOperations as security
from app.market.helper import BittrexRequests
from app import BITTREX_MARKET_SUMMARIES_API, BITTREX_MARKET_SUMMARY_API

@security.token_required
def get_all_market_summaries():
    """
    Used to get the last 24 hour summary of all active markets.
    :return: response object (json)
    """
    try:
        resp = BittrexRequests(BITTREX_MARKET_SUMMARIES_API).get_data()
        # response - failed
        if resp.get('status') is not None:
            return helper.response_jsonify(resp)

        return helper.response('success', {"items": resp['result']}, "fetched all market summaries successfully", 200)
    except Exception as e:
        details = "Market summaries api unable to read data - Exception occurred " + str(e)
        return helper.response('failed', {}, details, 500)

@security.token_required
def get_market_summary(market):
    """
    Used to get the last 24 hour summary of a specific market.
    :param market: market name like btc-ltc pass to payload
    :return: response object (json)
    """
    try:
        payload = {"market": market}
        resp = BittrexRequests(BITTREX_MARKET_SUMMARY_API).get_data(payload=payload)
        # response - failed
        if resp.get('status') is not None:
            return helper.response_jsonify(resp)

        return helper.response('success', {"items": resp['result']}, "fetched market summary successfully", 200)
    except Exception as e:
        details = "Market summary api unable to read data - Exception occurred " + str(e)
        return helper.response('failed', {}, details, 500)


import argparse
import sys

def main():
    #Making a argparse object
    parser = argparse.ArgumentParser()
    #Taking inputs of variables through the CLI
    parser.add_argument('--x', type=float, default=1.0,
                        help='What is the first number?')
    parser.add_argument('--y', type=float, default=1.0,
                        help='What is the second number?')
    parser.add_argument('--operation', type=str, default='add',
                        help='What operation?(add, sub, mul, div or mod)')
    #Combining all the input variables into a single variable namely args
    args = parser.parse_args()
    #Printing the result of calling calc with args as a parameter
    sys.stdout.write(str(calc(args)))

def calc(args):
    if args.operation == 'add' :
        return args.x+args.y
    elif args.operation == 'sub':
        return args.x-args.y
    elif args.operation == 'mul':
        return args.x*args.y
    elif args.operation == 'div':
        return args.x/args.y
    elif args.operation == 'mod':
        return args.x%args.y

if __name__ == '__main__':
    main()

"""
INPUT

Goto Cmd Prompt and locate the file by changing directory...open the file using
command 'python file_name'...Run the program using the below command
python Argparse_For_CLI.py --x=2 --y=5 --operation=mul

OUTPUT
10.0

"""


import cv2
import imagehash
import xml.etree.ElementTree
import sys

from PIL import Image
from pathlib import Path

hashes = {}

class Extractor():
    def __init__(self, root_path, video_file_path, images_dir, skipped_frames=1000, interactive=False):
        self.video_file = str(video_file_path)

        event_name = list(video_file_path.parts)[
            len(list(root_path.parts)) - 1:-1]
        self.images_path = Path(
            "{}/{}".format(images_dir, "-".join(event_name)))

        self.skipped_frames = skipped_frames
        self.cap = None
        self.frames_cnt = 0
        self.interactive = interactive

    def process(self):
        self.cap = cv2.VideoCapture(self.video_file)
        self.frames_cnt = int(self.cap.get(cv2.CAP_PROP_FRAME_COUNT))

        self.images_path.mkdir(parents=True, exist_ok=True)

        i = 0
        while self.cap.isOpened():
            # get image
            ok, frame = self.cap.read()
            if not ok:
                break

            # skip
            i += self.skipped_frames
            if i > self.frames_cnt:
                i = self.frames_cnt
            self.cap.set(cv2.CAP_PROP_POS_FRAMES, i)

            # save the image
            image = Image.fromarray(frame)
            hash = str(imagehash.phash(image, hash_size=12))
            if hash in hashes:
                continue
            hashes[hash] = True

            # show image
            if self.interactive:
                cv2.imshow('frame', frame)
                b = False
                r = False
                while True:
                    k = cv2.waitKey(0)
                    if k & 0xFF == ord('q'):  # quit
                        b = True
                        break
                    elif k & 0xFF == ord('r'):  # reject
                        r = True
                        break
                    elif k & 0xFF == ord('a'):  # accept
                        break
                if b:
                    break
                elif r:
                    continue  # skip to next frame

            # save image
            image_path = "{}/{}.jpg".format(str(self.images_path), i)
            if not Path(image_path).exists():
                cv2.imwrite(image_path, frame)
        try:
            self.images_path.rmdir()
        except Exception as e:
            pass


"""
This module holds tests for error messages and stacktraces

Created on Oct 18, 2013

@author: pupssman
"""

from hamcrest import has_property, assert_that, has_properties, has_string
from hamcrest.library.text.stringcontainsinorder import string_contains_in_order

def has_error(message='', trace=''):
    return has_property('{}test-cases',
                        has_property('test-case',
                                     has_property('failure',
                                                  has_properties({
                                                      'message': message,
                                                      'stack-trace': has_string(trace)
                                                  }))))

def test_smoke(report_for):
    report = report_for("""
    def test_X():
        raise RuntimeError("Foo bar baz")
    """)

    assert_that(report, has_error(message='RuntimeError: Foo bar baz',
                                  trace=string_contains_in_order('raise',
                                                                 'RuntimeError("Foo bar baz")',
                                                                 "RuntimeError: Foo bar baz")))

def test_setup_error(report_for):
    report = report_for("""
    import pytest

    @pytest.fixture
    def FOO():
        raise RuntimeError("ololo")

    def test_X(FOO):
        assert True
    """)

    assert_that(report, has_error(message='RuntimeError: ololo',
                                  trace=string_contains_in_order('FOO',
                                                                 'raise',
                                                                 'RuntimeError("ololo")',
                                                                 "RuntimeError: ololo")))

def test_missing_fixture(report_for):
    report = report_for("""
    def test_X(FOO):
        assert True
    """)

    assert_that(report, has_error(message=string_contains_in_order('FixtureLookupError'),
                                  trace=string_contains_in_order("fixture 'FOO' not found",
                                                                 'available fixtures',)))

def test_collect_error(report_for):
    report = report_for("""
    def test_Y():
        foo(
    """)

    assert_that(report, has_error(message='failed',
                                  trace=string_contains_in_order('import',
                                                                 'SyntaxError')))

def test_xpass(report_for):
    report = report_for("""
    import pytest

    @pytest.mark.xfail(reason='ololo')
    def test_Y():
        assert True
    """)

    assert_that(report, has_error(message='xpassed',
                                  trace='ololo'))

def test_xfail(report_for):
    report = report_for("""
    import pytest

    @pytest.mark.xfail(reason='ololo')
    def test_Y():
        assert False
    """)

    assert_that(report, has_error(message='ololo',
                                  trace=''))

def test_skip(report_for):
    report = report_for("""
    import pytest

    def test_Y():
        pytest.skip('ololo')
    """)

    assert_that(report, has_error(message='Skipped: ololo',
                                  trace=''))

def test_skip_long(report_for):
    report = report_for("""
    import pytest

    def test_Y():
        pytest.skip('ololo' * 16 + '!')
    """)

    assert_that(report, has_error(message='Skipped: ' + 'ololo' * 16 + '...',
                                  trace='Skipped: ' + 'ololo' * 16 + '!'))


#!/usr/bin/python
#-*- coding: utf-8 -*-

import sys
import time
import urllib
import urllib.parse
import requests
import numpy as np
import imp
from bs4 import BeautifulSoup
from openpyxl import Workbook
from urllib import request
from urllib import error
from fake_useragent import UserAgent
imp.reload(sys)

# Fake User Agents
ua = UserAgent()
people=[['No.','Name','Company']]

def builder_spider():
    page_num=1;
    builder_list=[['No.','Name','Reg No','Areas','Contact','T','F','Address','Web','Key Projects','Awards']]

    while(page_num>0):
        url='https://www.mbawa.com/become-a-member/find-a-member/page/'+str(page_num)+'/?member_type=residential-builder&button&find-a-member=true'
        time.sleep(np.random.rand()*5) # Random waitling time to cover

        # Try to get html code
        try:
            req = request.Request(url, headers={ua.random})
            source_code = request.urlopen(req).read()
            plain_text=str(source_code).replace('
',' ').replace('
',' ').replace('
',' ')
        except (error.HTTPError, error.URLError) as e:
            print_builder_lists_excel(builder_list,page_num)
            print ('Access denied.')
            continue

        soup = BeautifulSoup(plain_text)
        list_soup = soup.find('ol', {'class': 'results table-list'})

        if list_soup == None:
            page_num=-1
            print_builder_lists_excel(builder_list,page_num)
            print('All result has been stored.')
            break

        for builder_info in list_soup.findAll('article'):
            name = builder_info.find('a', {'target':'_blank'}).string.strip()
            try:
                company_url = builder_info.find('a', {'target':'_blank'}).get('href')
                detail = get_detail(company_url, name)
            except:
                print('No detail get')
                detail=[''] * 9
            builder_list.append([len(builder_list),name,detail[0],detail[1],detail[2],detail[3],detail[4],detail[5],detail[6],detail[7],detail[8]])
        print ('Downloading Information From Page %d' % page_num)
        page_num+=1
    return 1

def get_detail(url, name):
    detail=[''] * 9
    global people

    try:
        req = request.Request(url, headers=hds[np.random.randint(0,len(hds))])
        source_code = request.urlopen(req).read()
        plain_text=str(source_code).replace('
','').replace('
','').replace('
','').replace('\\n','')
    except (error.HTTPError, error.URLError) as e:
        print_builder_lists_excel(builder_list,0)
        print ('Access denied.')
        print (e)

    soup = BeautifulSoup(plain_text)

    try:
        ul = soup.find('ul', {'class':'member-meta'}).find_all('li')
    except:
        print('Company data not found: '+name)
        return detail

    for li in ul:
        if(li.find('strong') == None):
            try:
                [s.extract() for s in li('strong')]
                content = li.string.strip()
            except:
                print('Wrong type address')
                continue
            else:
                detail[5]=content
        elif(li.find('strong').string == 'Builders Reg No: '):
            try:
                [s.extract() for s in li('strong')]
                content = li.string.strip()
            except:
                print('Wrong type Reg No.')
                continue
            else:
                detail[0]=content
        elif(li.find('strong').string == 'Areas:'):
            try:
                [s.extract() for s in li('strong')]
                content = li.string.strip()
            except:
                print('Wrong type area')
                continue
            else:
                detail[1]=content
        elif(li.find('strong').string == 'Contact:'):
            try:
                [s.extract() for s in li('strong')]
                content = li.string.strip()
            except:
                print('Wrong type contact')
                continue
            else:
                if content != '':
                    people.append([content,name])
                    detail[2]=content
        elif(li.find('strong').string == 'T:'):
            try:
                [s.extract() for s in li('strong')]
                content = li.string.strip()
            except:
                print('Wrong type T')
                continue
            else:
                detail[3]=content
        elif(li.find('strong').string == 'F:'):
            try:
                [s.extract() for s in li('strong')]
                content = li.string.strip()
            except:
                print('Wrong type F')
                continue
            else:
                detail[4]=content
    try:
        web = soup.find('a', {'class':'btn btn-primary btn-uppercase m-b-1'}).get('href')
        detail[6]=web
    except:
        print('No web')

    divl = soup.find_all('div', {'class':'m-b-3'})
    for item in divl:
        if(item.find('h3') != None and item.find('h3').string == 'Key Projects'):
            item_list=[]
            li=item.find_all(['li','p'])
            for i in li:
                try:
                    if i.string.strip() != None:
                        item_list.append(i.string.strip())
                except:
                    continue
            detail[7]=','.join(item_list)
        elif(item.find('h3') != None and item.find('h3').string == 'Awards'):
            item_list=[]
            li=item.find_all(['li','p'])
            for i in li:
                try:
                    if i.string.strip() != None:
                        item_list.append(i.string.strip())
                except:
                    continue
            detail[8]=','.join(item_list)

    stuff = soup.find('h4', {'class':'primary'})
    if stuff != None and len(stuff.find_next_siblings('ul')) != 0:
        for person in stuff.find_next_siblings('ul')[0].find_all('li'):
            try:
                if person.string.strip() != '':
                    people.append([len(people),person.string.strip(),name])
            except:
                continue
    elif stuff != None and stuff.find_next_siblings('p') != None:
        for person in stuff.find_next_siblings('p'):
            try:
                if person.string.strip() != '':
                    people.append([len(people),person.string.strip(),name])
            except:
                continue

    return detail

def print_builder_lists_excel(builder_list,page_num):
    wb=Workbook(write_only=True)
    global people
    people = list(set([tuple(t) for t in people]))

    ws=wb.create_sheet('builder')
    ws2=wb.create_sheet('people')
    for bl in builder_list:
       ws.append([bl[0],bl[1],bl[2],bl[3],bl[4],bl[5],bl[6],bl[7],bl[8],bl[9],bl[10]])
    for person in people:
       ws2.append([person[0],person[1],person[2]])
    save_path='builder list '+time.strftime("%Y-%m-%d", time.localtime())+' page '+str(page_num)+'.xlsx'
    wb.save(save_path)

if __name__=='__main__':
    builder_lists=builder_spider()


from enigma_five import EnigmaFive
from random import randint

alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789."
wheels = ["V0","V1","V2","V3","V4","V5","V6","V7","V8","V9"]

# Makes a word with characters from our alphabet of a given length
def makeRandomWord(length = 5):
	word = ""
	for i in range(length):
		word += alphabet[randint(0,36)]
	return word

def makeInitialString():
	return makeRandomWord(5)

# Makes a random list of wheels for the Enigma configuration, in accordance with cert exclusion rules.
# In particular no wheel should appear twice, and the reverse side of each wheel VN is the wheel V(N+5 mod 10) which we must also
# exclude when N is present.
# For instance if we have V5, we cannot allow V5 to appear again. Also the back side of V5 is V0, so we must also exclude V0 when V5 is present.
def makeRandomWheelConfig():
	list = []
	excluded = []
	while len(list) < 5:
		n = randint(0,9)
		if n in excluded:
			continue # skip because Vn is present
		elif (n+5) % 10 in excluded:
			continue # skip because Vn's reverse side is present
		else:
			# Here we add n, and then exluce it and its reverse side
			excluded += [n, (n+5) % 10]
			list.append(wheels[n])

	return list

# Make a word list of a given length, with given max and min word sizes present
def makeWordList(wordCount = 10, maxWordSize = 10, minWordSize = 0):
	list = []
	for i in range(wordCount):
		word = makeRandomWord(randint(minWordSize,maxWordSize))
		list.append(word)
	return list

# Putting it all together now! We generate a list of random words of a certain length with the given size parameters.
# Then for each run in the count, we generate a machine with a random configuration of initial string and wheels. We
# test an encode/decode loop for each word in the list. If any words fail we record them to a failure list which we
# return at the end.
def testEncodeDecode(runCount = 100, wordCount = 100, maxWordSize = 100):
	wordList = makeWordList(wordCount, maxWordSize = maxWordSize)
	for i in range(runCount):
		wheelList = makeRandomWheelConfig()
		initialString = makeInitialString()
		machine = EnigmaFive(wheelList, initialString)

		failures = []

		for word in wordList:
			encodedString = machine.encode(word)
			decodedString = machine.decode(encodedString)

			if word == decodedString:
				continue
			else:
				failures.append({"word": word,
				"initialString": initialString,
				"wheelList": wheelList,
				"encodedString": encodedString,
				"decodedString": decodedString
				})

	return (failures)

# Takes a minute to run but I havent found a failure yet!
#print(testEncodeDecode(1000, 100, 100))


class Adder:
    def __init__(self, data = 0):
        self.data = data
    def add(self, x, y):
        print('Not Implement')

class ListAdder(Adder):
    def add(self, x, y):
        print(f'{x} + {y} = ', end = '')
        return list(x)+list(y)

class DictAdder(Adder):
    def add(self, x, y):
        print(f'{x} + {y} = ', end = '')
        for key in y:
            if key in x.keys():
                new_one = []
                new_one.append(x[key])
                new_one.append(y[key])
                x[key] = new_one
            else: x[key] = y[key]
        return x

def selftest():
    print('\t**** Start SELFTEST ****\n')
    print('*** Adder ***')
    z = Adder()
    s1 =1
    s2 =2
    z.add(s1, s2)
    print()

    print('*** ListAdder ***')
    y = ListAdder()
    l1 = [1,2,3,4]
    l2 = [5,6,7]
    print(y.add(l1,l2))
    print()

    print('*** DictAdder ***')
    x = DictAdder()
    d1 = {'a':1, 'b':2}
    d2 = {'b':3, 'c':4}
    print(x.add(d1,d2))

if __name__ == '__main__':
    selftest()

Упражнения VI/1.1.py


# version: 0.0.1

# import logging
import msvcrt
import os
from datetime import datetime, timedelta, time
import sys
from pydub import AudioSegment, effects
import shutil

def resource_path(relative_path):
    try:
        base_path = sys._MEIPASS
    except Exception:
        base_path = os.path.abspath(".")

    return os.path.join(base_path,
                        relative_path)

# Returns dictionary {<datetime: created> : <str: file name>} of voice files
def get_voice_files():
    dict_voice_files = {}
    all_files = os.listdir()

    for file in all_files:
        if file.startswith('audioclip') and file.endswith('.mp4'):
            try:
                file_timestamp = file[9:19]
                file_date = datetime.fromtimestamp(int(file_timestamp))
                dict_voice_files[file_date] = file

                # for debug
                # logging.info("Detected file -> created: {} | file name: {}".format(file_date.strftime("%d/%m/%Y, %H:%M:%S"), file))

            except (ValueError, TypeError):
                print("Error while getting int timestamp from str | file name: {}".format(file))
                break

    return dict_voice_files

def group_files_by_date(ungrouped_files, date_range):
    grouped_files = {}

    for date in ungrouped_files:
        group_date = datetime.date(date)
        if datetime.time(date) < time(5, 0, 0):
            group_date = group_date - timedelta(days=1)

        if date_range[0] <= group_date <= date_range[1]:
            if group_date in grouped_files.keys():
                grouped_files[group_date][date] = ungrouped_files[date]
            else:
                grouped_files[group_date] = {date : ungrouped_files[date]}

    return grouped_files

# Print iterations progress
def printProgressBar (iteration, total, prefix = 'Progress:', suffix = 'Complete', decimals = 1, length = 50, fill = '▒', printEnd = "\r"):
    """
    Call in a loop to create terminal progress bar
    @params:
        iteration   - Required  : current iteration (Int)
        total       - Required  : total iterations (Int)
        prefix      - Optional  : prefix string (Str)
        suffix      - Optional  : suffix string (Str)
        decimals    - Optional  : positive number of decimals in percent complete (Int)
        length      - Optional  : character length of bar (Int)
        fill        - Optional  : bar fill character (Str)
        printEnd    - Optional  : end character (e.g. "\r", "\r\n") (Str)
    """
    percent = ("{0:." + str(decimals) + "f}").format(100 * (iteration / float(total)))
    filledLength = int(length * iteration // total)
    bar = fill * filledLength + '-' * (length - filledLength)
    print(f'\r{prefix} |{bar}| {percent}% {suffix}', end = printEnd)
    # Print New Line on Complete
    if iteration == total:
        print()

def process_audio_files(grouped_files):
    printProgressBar(0,
                    len(grouped_files.keys()))

    if os.path.isdir("export"):
        shutil.rmtree("export")
    os.mkdir("export")

    for group_key in grouped_files:
        to_be_merged = AudioSegment.empty()

        for file_key in grouped_files[group_key]:
            to_be_merged += AudioSegment.from_file(grouped_files[group_key][file_key],
                                                format="mp4")

        to_be_merged += AudioSegment.from_file(resource_path("beep.wav"), format="wav")

        try:
            normalized_audio = effects.normalize(to_be_merged)
            normalized_audio.export("export/{}.mp3".format(group_key.strftime("%Y-%m-%d")), format="mp3")
        except Exception as e:
            print(e)
            msvcrt.getch()

        printProgressBar(list(grouped_files).index(group_key) + 1,
                            len(grouped_files.keys()))

    print("\nDONE | Your merged voice messages are located in 'export' directory!")

def is_valid_range_date_format(str_date):
    try:
        datetime.strptime(str_date, '%Y.%m.%d')
        return True
    except ValueError:
        return False

# Get date range from user
def get_process_range():
    range = [datetime(1900, 1, 1).date(), datetime(3000, 1, 1).date()]

    range_from_str = input("Process messages from [yyyy.mm.dd] (empty for no limit): ")
    while range_from_str != '' and not is_valid_range_date_format(range_from_str):
        range_from_str = input("typo ► Process messages from [yyyy.mm.dd] (empty for no limit): ")

    if range_from_str != '':
        range[0] = datetime.strptime(range_from_str, '%Y.%m.%d').date()

    range_to_str = input("Process messages to [yyyy.mm.dd] (empty for no limit): ")
    while range_to_str != '' and not is_valid_range_date_format(range_to_str):
        range_to_str = input("typo ► Process messages to [yyyy.mm.dd] (empty for no limit): ")

    if range_to_str != '':
        range[1] = datetime.strptime(range_to_str, '%Y.%m.%d').date()

    return range

def main(args=None):
    print("                 ╔════════════════════════════════╗")
    print("                 ║          Voicetelling          ║")
    print("                 ╚════════════════════════════════╝")
    print("This script merges Facebook Messenger voice messages by day into .mp3 files.")
    print("► https://github.com/smolikja/voicetelling")
    print("Developed by smolikja: https://github.com/smolikja")
    print("==================================================")

    # # for debug
    # logging.basicConfig(filename="std.log",
    #                     format='%(asctime)s %(message)s',
    #                     filemode='w',
    #                     level= logging.DEBUG)

    # Files into dictionary {<datetime: created> : <str: file name>}
    dict_voice_files = get_voice_files()

    if bool(dict_voice_files):
        range = get_process_range()

        # Files into dictionary {<datetime: group time> : {<datetime: created> : <str: file name>}}
        dict_grouped_files = group_files_by_date(dict_voice_files, date_range= range)

        print("\nProcessing into {} audio files...".format(len(dict_grouped_files.keys())))

        # Merge and export audio files
        process_audio_files(dict_grouped_files)
    else:
        print("\n>>> No voice files found. <<<\n")

    print("Press any key to exit.")
    msvcrt.getch()

if __name__ == '__main__':
    main()


import discord
from discord.ext import commands
from Models.Context import Context

class SameTimeAttackAddMemberCog(commands.Cog):
    """
    同時凸するメンバーの追加
    """
    def __init__(self, bot: commands.Bot):
        self.bot = bot

    @commands.command("dadd")
    async def add_member(self, ctx: commands.context.Context, *args):
        # 予測ダメージ取得
        suspect: int = int(args[0])

        # 同時凸開始
        context: Context = await Context.get_instance(self.bot)
        context.same_time_attack.add_member(ctx.message.author, suspect)
        await ctx.message.channel.send(context.same_time_attack.format_status())


from TimeCost import TimeCost

data = list()
with open('data.txt', 'r') as file:
    lis = [line.split(';') for line in file]
    for i in range(0, len(lis), 1):
        temp = TimeCost(lis[i], 2)
        data.append(temp)
with open('data1.csv', 'w') as file:
    for key in data:
        file.write("{};{}\n".format(key.date.strftime('%m.%d.%Y %H:%M'), key.cost))
    file.close()


__all__ = ['nombrar_numero']

__author__ = u'Roberto García Carvajal'

def _desempaquetar_segmento(x):
    """
        Extrae de la cadena las centenas, decenas y unidades por separado.
        Tener en cuenta que puede que la cadena tenga una longitud inferior 3.
        :param x: str de como mucho 3 caracteres.
        :return tuple: tupla de 3 enteros que representan a centenas, decenas y
         unidades.
    """
    index = 0
    c = 0
    d = 0
    u = 0
    l = len(x)
    if l > 3:
        raise ValueError(u"El segmento debe ser como mucho de longitud 3.")
    if l > 2:
        c = int(x[index])
        index += 1
    if l > 1:
        d = int(x[index])
        index += 1
    if l > 0:
        u = int(x[index])
    return c, d, u

def _nombrar_segmento(x, unidad_larga=False):
    """
        Nombra un segmento determinado. No incluye puntuación.
        :param x: str de, como mucho, 3 caracteres numéricos.
        :param unidad_larga: bool. Indica si la unidad se escribo como "uno"o
        "un".
        :return str con la transcripción del número.
    """
    c, d, u = _desempaquetar_segmento(x)
    # Mapa para las centenas. Con cuidado de '1', que será 'cien' si decenas y
    # unidades son 0.
    c_dict = {
        0: u"",
        1: ((d + u) > 0 and u"ciento" or u"cien"),
        2: u"doscientos",
        3: u"trescientos",
        4: u"cuatrocientos",
        5: u"quinientos",
        6: u"seiscientos",
        7: u"setecientos",
        8: u"ochocientos",
        9: u"novecientos",
    }
    # Mapa para decenas, con cuidado de que las unidades sean 0.
    d_dict = {
        0: u"",
        1: (u and u"dieci" or u"diez"),
        2: (u and u"veinti" or u"veinte"),
        3: (u and u"treinta y " or u"treinta"),
        4: (u and u"cuarenta y " or u"cuarenta"),
        5: (u and u"cincuenta y " or u"cincuenta"),
        6: (u and u"sesenta y " or u"sesenta"),
        7: (u and u"setenta y " or u"setenta"),
        8: (u and u"ochenta y " or u"ochenta"),
        9: (u and u"noventa y " or u"noventa"),
    }
    # Mapa de unidades, teniendo en cuenta la unidad_larga.
    # Además, si las decenas es 2, algunos números llevan tildes.
    u_dict = {
        0: u"",
        1: (unidad_larga and u"uno") or (d == 2 and u"ún") or u"un",
        2: (d == 2 and u"dós") or u"dos",
        3: (d == 2 and u"trés") or u"tres",
        4: u"cuatro",
        5: u"cinco",
        6: (d in (1, 2) and u"séis") or u"seis",
        7: u"siete",
        8: u"ocho",
        9: u"nueve",
    }
    c_res = c_dict[c]
    d_u_res = d_dict[d] + u_dict[u]
    # Caso especial de los números entre 11 y 15.
    if d == 1 and 0 < u < 6:
        d_u_res = {
            11: u"once",
            12: u"doce",
            13: u"trece",
            14: u"catorce",
            15: u"quince",
        }[10 + u]
    # Sólo incluimos separador si las dos partes del segmento tienen valores.
    separator = u""
    if c_res and d_u_res:
        separator = u" "
    return c_res + separator + d_u_res

def nombrar_numero(x):
    """
        Convierte un número a su formato escrito. Sólo acepta números enteros
        no negativos.
        :param x: int, entero no negativo a convertir a formato escrito.
        :return unicode: devuelve el número en formato alfabético.
    """
    # Comprobación del tipo.
    if not isinstance(x, int):
        raise ValueError(u"Tipo incorrecto. Se esperaba int, encontrado %s" %
                         x.__class__.__name__)
    # Comprobación de signo.
    if x < 0:
        raise ValueError(u"Se esperaba un entero no negativo.")
    if x == 0:
        return u"cero"
    # Ahora vamos a trocear el número en grupos de 3 en 3, empezando desde la
    # derecha y tomando nota del número de segmentos que tiene el número.
    # Almacenamos los segmentos en una lista de cadenas en orden inverso.
    # Ejemplos:
    # 1 -> ["1"]
    # 4234 -> ["234", "4"]
    # 10001 -> ["001", "10"]
    xx = u"%s" % x
    xx = xx[::-1]
    l = len(xx) / 3 + {False: 0, True: 1}[(len(xx) % 3) > 0]
    vx = []
    for i in range(0, l):
        vx.append(xx[3 * i:3 * (i + 1)][::-1])
    # vx = vx[::-1]

    resultado = u""
    mapa_sufijos_singular = {
        0: u"",
        1: u"mil",
        2: u"millón",
        3: u"mil",
        4: u"billón",
        5: u"mil",
        6: u"trillón",
    }
    mapa_sufijos_plural = {
        0: u"",
        1: u"mil",
        2: u"millones",
        3: u"mil",
        4: u"billones",
        5: u"mil",
        6: u"trillones",
    }
    # Recorremos los segmentos. Recordar que vamos a nombrar el número por
    # grupos de tres desde la derecha, añadiendo el sufijo según puntuación, si
    # corresponde.
    for index, v in enumerate(vx):
        resultado_segmento = _nombrar_segmento(v, unidad_larga=(index == 0))
        # Si el segmento es de millares y el resultado tiene valor o el segmento
        # es de millones, se añade el sufijo. Ejemplos:
        # - Para 1000001, segmentos '1', '000', '001'. Si estamos en el segmento
        #   '000', no deberíamos de poner 'mil'.
        # - Para 1000020001, segmentos '1', '000', '020', '001'. Si estamos en
        #   el segmento '000', deberíamos de poner "millones".
        if (resultado_segmento or (index % 2) == 0) and index > 0:
            resultado_segmento += u" "
            # Distinguimos entre singular o plural.
            if resultado_segmento == u"un ":
                # Si el resultado es un 1 y estamos nombrando millares, lo
                # dejamos vacío. Es decir: para 1000 no vamos a decir
                # 'un mil', sino sólo mil.
                if (index % 2) == 1:
                    resultado_segmento = mapa_sufijos_singular[index]
                else:
                    resultado_segmento += mapa_sufijos_singular[index]
            else:
                resultado_segmento += mapa_sufijos_plural[index]
        if resultado_segmento:
            resultado = u" " + resultado_segmento + resultado
    # Probablemente queden espacios a la izquierda (un mínimo de 1).
    # Los eliminamos.
    return resultado.lstrip()


from flask import Flask, request, render_template, flash, redirect, send_file, abort
from werkzeug.utils import secure_filename
import os

UPLOAD_FOLDER = 'uploads'
ALLOWED_EXTENSIONS = set(['wav'])

app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER

def allowed_file(filename):
    return '.' in filename and \
           filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

def is_mp3(filename):
    return '.' in filename and \
           filename.rsplit('.', 1)[1].lower() == 'mp3'

@app.route("/", methods=['GET', 'POST'])
def index():
    if request.method == 'POST':
        # check if the post request has the file part
        file_name = "sound_file"
        if file_name not in request.files:
            print("no file part")
            return redirect(request.url)
        file = request.files[file_name]
        # if user does not select file, browser also
        # submit a empty part without filename
        if file.filename == '':
            print('No selected file')
            return redirect(request.url)
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)
            file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
            # if is_mp3(file):
            #     file = convert_mp3_to_wav(file)
            # File is accepted
            transcribed_text = get_text_from_audio(file.filename)
            print(transcribed_text)
            return render_template('index.html', text=transcribed_text)

    return render_template('index.html')

def convert_mp3_to_wav(file):
    import pydub
    sound = pydub.AudioSegment.from_mp3("uploads/" + file.filename)
    output_filename = "uploads/" + file.filename + ".wav"
    if sound.export(output_filename, format="wav"):
        return output_filename

def get_text_from_audio(filename):
    audiofile = os.path.join(app.config['UPLOAD_FOLDER'], filename)
    import speech_recognition as sr
    r = sr.Recognizer()
    with sr.AudioFile(audiofile) as source:
        audio = r.record(source)
    try:
        # text = r.recognize_wit(audio, 'PE5SXFPEIPPST5JD434ZGQ3WKWXBTEOR')
        text = r.recognize_sphinx(audio)
        return text
    except sr.UnknownValueError:
        print("Could not understand audio")
        return None
    except sr.RequestError as e:
        print("Recog Error; {0}".format(e))
        return None


import torch
import torch.nn as nn
import torch.nn.functional as Functional

def square_distance(src, dst):
    B, N, _ = src.shape
    _, M, _ = dst.shape
    dist = -2 * torch.matmul(src.float(), dst.float().permute(0, 2, 1))
    dist += torch.sum(src ** 2, -1).view(B, N, 1)
    dist += torch.sum(dst ** 2, -1).view(B, 1, M)
    return dist

def index_points(points, idx):
    """
    Input:
        points: input points data, [B, N, C]
        idx: sample index data, [B, S]
    Return:
        new_points:, indexed points data, [B, S, C]
    """
    device = points.device
    B = points.shape[0]
    view_shape = list(idx.shape)
    view_shape[1:] = [1] * (len(view_shape) - 1)
    repeat_shape = list(idx.shape)
    repeat_shape[0] = 1
    batch_indices = torch.arange(B, dtype=torch.long).to(device).view(view_shape).repeat(repeat_shape)
    new_points = points[batch_indices, idx, :]
    return new_points

def farthest_point_sample(xyz, npoint):
    """
    Input:
        xyz: pointcloud data, [B, N, 3]
        npoint: number of samples
    Return:
        centroids: sampled pointcloud index, [B, npoint]
    """
    device = xyz.device
    B, N, C = xyz.shape
    centroids = torch.zeros(B, npoint, dtype=torch.long).to(device)
    distance = torch.ones(B, N).to(device) * 1e10
    farthest = torch.randint(0, N, (B,), dtype=torch.long).to(device)
    batch_indices = torch.arange(B, dtype=torch.long).to(device)
    for i in range(npoint):
        centroids[:, i] = farthest
        centroid = xyz[batch_indices, farthest, :].view(B, 1, 3)
        dist = torch.sum((xyz - centroid) ** 2, -1)
        mask = dist < distance
        distance[mask] = dist[mask]
        farthest = torch.max(distance, -1)[1]
    return centroids

def knn(nsample, xyz, new_xyz):
    dist = square_distance(xyz, new_xyz)
    id = torch.topk(dist,k=nsample,dim=1,largest=False)[1]
    id = torch.transpose(id, 1, 2)
    return id

class KNN_dist(nn.Module):
    def __init__(self,k):
        super(KNN_dist, self).__init__()
        self.R = nn.Sequential(
            nn.Linear(10,10),
            nn.LeakyReLU(0.2,inplace=True),
            nn.Linear(10,10),
            nn.LeakyReLU(0.2,inplace=True),
            nn.Linear(10,1),
        )
        self.k=k
    def forward(self,F,vertices):
        id = knn(self.k, vertices, vertices)
        F = index_points(F,id)
        v = index_points(vertices,id)
        v_0 = v[:,:,0,:].unsqueeze(-2).repeat(1,1,self.k,1)
        v_F = torch.cat((v_0, v, v_0-v,torch.norm(v_0-v,dim=-1,p=2).unsqueeze(-1)),-1)
        v_F = self.R(v_F.type(torch.FloatTensor).to('cuda:0'))
        F = torch.mul(v_F, F)
        F = torch.sum(F,-2)
        return F

class View_selector(nn.Module):
    def __init__(self, n_views, sampled_view):
        super(View_selector, self).__init__()
        self.n_views = n_views
        self.s_views = sampled_view
        self.cls = nn.Sequential(
            nn.Linear(512*self.s_views, 256*self.s_views),
            nn.LeakyReLU(0.2),
            nn.Linear(256*self.s_views, 40*self.s_views))
    def forward(self,F,vertices,k):
        id = farthest_point_sample(vertices,self.s_views)
        vertices1 = index_points(vertices,id)
        id_knn = knn(k,vertices,vertices1)
        F = index_points(F,id_knn)
        vertices = index_points(vertices,id_knn)
        F1 = F.transpose(1,2).reshape(F.shape[0],k,self.s_views*F.shape[-1])
        F_score = self.cls(F1).reshape(F.shape[0],k,self.s_views,40).transpose(1,2)
        F1_ = Functional.softmax(F_score,-3)
        F1_ = torch.max(F1_,-1)[0]
        F1_id = torch.argmax(F1_,-1)
        F1_id = Functional.one_hot(F1_id,4).float()
        F1_id_v = F1_id.unsqueeze(-1).repeat(1,1,1,3)
        F1_id_F = F1_id.unsqueeze(-1).repeat(1, 1, 1, 512)
        F_new = torch.mul(F1_id_F,F).sum(-2)
        vertices_new = torch.mul(F1_id_v,vertices).sum(-2)
        return F_new,F_score,vertices_new

class LocalGCN(nn.Module):
    def __init__(self,k,n_views):
        super(LocalGCN,self).__init__()
        self.conv = nn.Sequential(
            nn.Linear(512, 512),
            nn.BatchNorm1d(512),
            nn.LeakyReLU(0.2, inplace=True),
        )
        self.k = k
        self.n_views = n_views
        self.KNN = KNN_dist(k=self.k)
    def forward(self,F,V):
        F = self.KNN(F, V)
        F = F.view(-1, 800)
        F = self.conv(F)
        F = F.view(-1, self.n_views, 756)
        return F

class NonLocalMP(nn.Module):
    def __init__(self,n_view):
        super(NonLocalMP,self).__init__()
        self.n_view=n_view
        self.Relation = nn.Sequential(
            nn.Linear(2 * 512, 512),
            nn.LeakyReLU(0.2, inplace=True),
            nn.Linear(512, 512),
            nn.LeakyReLU(0.2, inplace=True),
            nn.Linear(512, 512),
            nn.LeakyReLU(0.2, inplace=True),
        )
        self.Fusion = nn.Sequential(
            nn.Linear(2 * 512, 512),
            nn.BatchNorm1d(512),
            nn.LeakyReLU(0.2, inplace=True),
        )
    def forward(self, F):
        F_i = torch.unsqueeze(F, 2)
        F_j = torch.unsqueeze(F, 1)
        F_i = F_i.repeat(1, 1, self.n_view, 1)
        F_j = F_j.repeat(1, self.n_view, 1, 1)
        M = torch.cat((F_i, F_j), 3)
        M = self.Relation(M)
        M = torch.sum(M,-2)
        F = torch.cat((F, M), 2)
        F = F.view(-1, 512 * 2)
        F = self.Fusion(F)
        F = F.view(-1, self.n_view, 512)
        return F


from sql.select_tables.utils.data import DataManager
from nltk.util import ngrams
from typing import List
from tqdm import tqdm
from json import dump
from sql.select_tables.config import parse_args

def _ngram_process(s: str, n: List[int]) -> List[str]:
    ngram = []
    for x in n:
        ngram = ngram + list(ngrams(s, x))
    ngram = ["".join(x) for x in ngram]
    ngram = list(set(ngram))
    return ngram

def _check_same_gram(a: List[str], b: List[str]) -> int:
    a.sort()
    b.sort()

    i = 0
    j = 0
    cnt = 0
    while i < len(a) and j < len(b):
        if a[i] < b[j]:
            i += 1
        elif a[i] > b[j]:
            j += 1
        else:
            cnt += 1
            i += 1
            j += 1
    return cnt

def get_candidate_tables(predict_data_path, schema_path, content_path,
                         ngram=(1, 2, 3, 4),
                         answer_size=6,
                         return_eval=False,
                         max_length=None):
    dm: DataManager = DataManager.load(
        predict_data_path, schema_path, content_path, max_length)
    lam = [0.1, 0.1, 0.1, 5, 5, 5, 5, 5, 5, 5]
    used_rec_gram = [True, True, True, False, False, False, False, False, False, False]

    real_answer: List[List[int]] = []
    predict_answer: List[List[int]] = []
    for q in tqdm(dm.questions):
        current_question = q.question
        current_schema = q.schema
        current_real_answer = q.tables

        real_answer.append(current_real_answer)
        predict_answer.append([])
        candidate_tables = list(range(len(current_schema)))
        question_ngram = _ngram_process(current_question, ngram)
        rec_gram = []

        for i in range(answer_size):
            best_answer = -1
            best_score = -1
            best_gram = []
            for t in candidate_tables:
                if used_rec_gram[i]:
                    current_question_gram = list(
                        set(question_ngram) - set(rec_gram))
                else:
                    current_question_gram = question_ngram

                current_table = current_schema[t]
                table_name_ngram = _ngram_process(
                    current_table.split('[SEP]')[0], ngram)
                schema_ngram = _ngram_process(current_table, ngram)
                current_score = lam[i] * _check_same_gram(
                    current_question_gram, schema_ngram) + _check_same_gram(current_question_gram, table_name_ngram)
                if current_score > best_score:
                    best_score = current_score
                    best_answer = t
                    best_gram = table_name_ngram

            if i == 0:
                candidate_tables = []
            predict_answer[-1].append(best_answer)
            candidate_tables = candidate_tables + dm.foreign_key[best_answer]
            candidate_tables = list(
                set(candidate_tables) - set(predict_answer[-1]))
            rec_gram = list(set(rec_gram + best_gram))

    recall = 0
    example_recall = 0
    # f1 = 0
    result = []
    for i in range(len(predict_answer)):
        cnt = _check_same_gram(predict_answer[i], real_answer[i])
        current_recall = cnt / len(real_answer[i])
        example_recall += 1 if current_recall == 1 else 0
        recall += current_recall

        predict_table = [dm.table_name[x]
                         for x in predict_answer[i]]
        real_table = [dm.table_name[x]
                      for x in real_answer[i]]
        question = dm.questions[i].question

        # if cnt != len(real_answer[i]):
        result.append(
            {'question': question,
             'question_id': dm.questions[i].question_id,
             'real_tables': real_table,
             'predict_tables': predict_table,
             'predict_tables_id': predict_answer[i]})

    if return_eval:
        return result, {'recall (table level)': recall/len(predict_answer),
                        'recall (example level)': example_recall/len(predict_answer)}
    else:
        return result

def main():
    args = parse_args()
    result, eval = \
        get_candidate_tables(args.predict_data_path,
                             args.schema_path,
                             args.content_path,
                             args.ngram,
                             args.answer_size,
                             return_eval=True,
                             max_length=args.max_length)
    with open(args.result_path, 'w', encoding='utf-8') as f:
        dump(result, f, ensure_ascii=False, indent=4)

    print('\n'.join([f'{k}: {v}' for k,v in eval.items()]))

if __name__ == '__main__':
    main()


import os
import sys
from io import BytesIO, IOBase

def main():
    t = int(input())
    for _ in range(t):
        n = int(input())
        A = list(map(int, input().rstrip().split()))
        MaximumCandies = list(map(int, input().rstrip().split()))
        distA = [0]
        distB = [0]
        for pos in range(n):
            distA.append(distA[-1]+A[pos])
            distB.append(distB[-1]+MaximumCandies[pos])
        timeTogether = 0
        pos = 0
        while pos < n:
            if distA[pos] == distB[pos]:
                check = True
                while pos < n and A[pos] == MaximumCandies[pos] :
                    check = False
                    timeTogether += A[pos]
                    pos += 1
                if check:
                    pos+=1
                continue
            pos += 1
        print(timeTogether)

##############################################################################################################
BUFSIZE = 8192

class FastIO(IOBase):
    newlines = 0

    def __init__(self, file):
        self._fd = file.fileno()
        self.buffer = BytesIO()
        self.writable = "x" in file.mode or "r" not in file.mode
        self.write = self.buffer.write if self.writable else None

    def read(self):
        while True:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            if not b:
                break
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines = 0
        return self.buffer.read()

    def readline(self):
        while self.newlines == 0:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            self.newlines = b.count(b"\n") + (not b)
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines -= 1
        return self.buffer.readline()

    def flush(self):
        if self.writable:
            os.write(self._fd, self.buffer.getvalue())
            self.buffer.truncate(0), self.buffer.seek(0)

class IOWrapper(IOBase):
    def __init__(self, file):
        self.buffer = FastIO(file)
        self.flush = self.buffer.flush
        self.writable = self.buffer.writable
        self.write = lambda s: self.buffer.write(s.encode("ascii"))
        self.read = lambda: self.buffer.read().decode("ascii")
        self.readline = lambda: self.buffer.readline().decode("ascii")

sys.stdin, sys.stdout = IOWrapper(sys.stdin), IOWrapper(sys.stdout)
input = lambda: sys.stdin.readline().rstrip("\r\n")

if __name__ == "__main__":
    main()


# -*- coding: utf-8 -*-
"""
Created on Wed May  5 12:43:07 2021

@author: Gaston
"""

def valor_absoluto(n):
    '''Calcula el valor absoluto de n

    Pre: n tiene que ser un numero entero
    Pos: Se devuelve el valor absoluto de n

    '''
    if n >= 0:
        return n
    else:
        return -n

#Invariante: si n es positivo n conserva su valor, sino se multiplica por -1
#%%
def suma_pares(l):
    '''Calcula la suma de los numeros pares de una lista

    Pre: los elementos de l enteros
    Pos: Se devuelve la suma de sus enteros pares

    '''
    res = 0
    for e in l:

        if e % 2 ==0:
            res += e
        else:
            res += 0
    return res

#invariante: res conserva su valor hasta que se encuentre un numero par en lista
#%%
def veces(a, b):
    '''Suma b veces el numero a

    Pre: a numeros entero, b numero entero positivo
    Pos: Se devuelve el resultado de a * b

    '''
    res = 0
    nb = b
    while nb != 0:
        #print(nb * a + res)
        res += a
        nb -= 1
    return res

#invariante: El valor de b decrece en cada ciclo hasta cero
#            res se acerca al valor buscado
#            res = a * (b - nb)
#%%
def collatz(n):
    '''Devuelve el numero de veces que se pueda aplicar la funcion de collatz
    hasta obtener un 1.

    Pre: n > 0
    Pos: numeros de veces que se aplicó la función

    '''
    res = 1

    while n != 1:
        if n % 2 == 0:       # si n es par, se divide entre 2.
            n = n//2
        else:               #Si n es impar, se multiplica por 3 y se suma 1.
            n = 3 * n + 1
        res += 1

    return res


import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QTreeView
from PyQt5.Qt import QStandardItemModel, QStandardItem
from PyQt5.QtGui import QFont, QColor

class StandardItem(QStandardItem):
    def __init__(self, txt = "", fontSize = 12, setBold = False, color = QColor(0, 0, 0)):
        super().__init__()
        fnt = QFont('Open Sans', fontSize)
        fnt.setBold(setBold)
        self.setEditable(False)
        self.setForeground(color)
        self.setFont(fnt)
        self.setText(txt)

class AppDemo(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("World diagram")
        self.resize(500, 700)
        treeView = QTreeView()
        treeView.setHeaderHidden(True)
        treeModel = QStandardItemModel()
        rootNode = treeModel.invisibleRootItem()
        america = StandardItem("America", 16, setBold = True)
        california = StandardItem("California", 14)
        okland = StandardItem("Okland", 14)
        texas = StandardItem("Texas", 14)
        america.appendRow(california)
        canada = StandardItem("Canada", 16, setBold = True)
        california.appendRow(okland)
        rootNode.appendRow(america)
        rootNode.appendRow(canada)
        treeView.setModel(treeModel)
        treeView.expandAll()
        self.setCentralWidget(treeView)

app = QApplication(sys.argv)
demo = AppDemo()
demo.show()
sys.exit(app.exec_())


import numpy as np
import scipy.special as sps

def the_transform(x,Nt = 500,Np = 500):

    N  = x.shape[0] - 1
    thetas = np.linspace(1e-10,np.pi,Nt)
    phis   = np.linspace(0,2*np.pi,Np)

    # duplicate the signal
    X = np.kron(x,np.ones((Np,Nt,1))).T

    # maps of angles
    Thetas, Phis = np.meshgrid(thetas,phis,indexing='ij')

    # map of phase space variable
    z = np.cos(Thetas/2)/np.sin(Thetas/2)*np.exp(1j*Phis)
    Z = np.kron(z,np.ones((N+1,1,1)))

    # indices
    ell = np.arange(N+1)
    L = np.kron(ell,np.ones((Np,Nt,1))).T

    # compute the transform using the generative function trick
    normZ  = np.sqrt(2*(1+np.abs(Z)**2))
    sumand = X*np.sqrt(sps.comb(N,L))*((1-Z)/(normZ))**L*((1+Z)/(normZ))**(N-L)
    Kz = np.sum(sumand,0)

    return Kz

def the_zeros(Kz, N, Nt = 500, Np = 500,feedback = False):

    thetas = np.linspace(1e-10,np.pi,Nt)
    phis   = np.linspace(0,2*np.pi,Np)

    # compute the zeros
    zx, zy    = extr2min(np.abs(Kz))

    # coordinates of the zeros on the sphre
    zp = phis[zy]
    zt = thetas[zx]

    # give some feedback
    if feedback:
        print('Local minima method has found '+str(zx.shape[0])+' zeros compared to the '+str(N)+' expected.')

    return zt, zp

def extr2min(M):
    central = M[1:-1, 1:-1]
    mask = np.full(central.shape, True, dtype=bool)
    sub_indices = (
        (np.s_[2:], np.s_[1:-1]),
        (np.s_[:-2], np.s_[1:-1]),
        (np.s_[1:-1], np.s_[2:]),
        (np.s_[1:-1], np.s_[:-2]),
        (np.s_[:-2], np.s_[:-2]),
        (np.s_[:-2], np.s_[2:]),
        (np.s_[2:], np.s_[2:]),
        (np.s_[2:], np.s_[:-2]),
    )
    for I, J in sub_indices:
        np.logical_and(mask, central <= M[I, J], out=mask, where=mask)

    x, y = np.where(mask)
    return x + 1, y + 1


weather_words = [
    "hava durumu", "weather", "havalar", "bugün hava", "hava", "havada"
]

weather_responses1 = [
    "", "Today is an overestimated ", "Today will be an exotic ",
    "Today is going to be a surprising ", "Today is an underestimated ",
    "Nothing surprising, Today will be ", "Currently it is ", "Today's the temperature is"
]

weather_responses2 = [
    "", "Keeping you alive will continue to be my top priority.",
    "Consider getting into suitable bodywear that will extend your life expectancy.",
    "Don't forget to take the motion tracker with you.",
    "I suspect the outside may be more dangerous than you think.",
    "Remember, they mostly come out at night.. mostly."
]

weather_responses3 = [
    "Have a nice day.", "Stay happy.", "Good luck.", "Session Over.",
    "Terminating Session..", "Ending.."
]

greeting_response1 = ["Hello!", "Hey", "Hi", "Selamlar"]

glad_response1 = [
    "Feedback noted.", "Here to serve", "Thank you",
    "Your appreciation is appreciated", "Always"
]

custom_status = [
    # 0:Playing, 1:Streaming, 2:Watching, 3:Listening
    [0, "kirli mesajlarınla", ""],
    [0, "verilerinle", ""],
    [0, "geleceğinle", ""],
    [0, "forbidden mesajlarıyla", ""],
    [0, "Roket Lig", ""],
    [1, "dünya şampiyonası", "https://www.twitch.tv/riotgames"],
    [2, "sessizce seni", ""],
    [2, "oyun oynayışını", ""],
    [2, "kazım değerlerini", ""],
    [2, "aileni", ""],
    [2, "bir sonraki hareketini", ""],
    [3, "konuşmalarını", ""],
    [3, "düşüncelerini", ""],
    [3, "K.Flay", ""],
    [3, "Saint Motel", ""],
    [3, "half·alive", ""]
]


def getter(_in):
    out = ''
    while True:
        n = _in()
        if not n:
            break
        out += n + '\n'
    return out

def analyze(string):
    p = {}
    for e in string.split('\n')[:-1]:
        e = e.split(' ')
        if e[0] not in p:
            p[e[0]] = []
        p[e[0]] += e[1:]
    return p

def process(data):
    p = {}
    for e in data.keys():
        if e not in p.keys():
            p[e] = []
        for f in data[e]:
            f = f.split('\'')
            if '-' in f[0]:
                year = f[1]
                f = f[0].split('-')
                for i in range(int(f[0]), int(f[1])+1):
                    j = ('0' + str(i))[-2:]
                    p[e] += [(j, year)]
            else:
                year = f[1]
                month = f[0]
                p[e] += [(month, year)]
    return p

_in = getter(input)
x = process(analyze(_in))
a = []
for e in x.keys():
    a += x[e]
a = [(y, x) for x, y in a]
a.sort()
a = [(int(y), int(x)) for x, y in a]
min = a[0]
max = a[-1]
x = {'date': [], **x}
for e in x:
    print(e, end=' ')
    for year in range(min[1], max[1]+1):
        for month in range(1, 13):
            if year == min[1] and month < min[0]:
                continue
            if year == max[1] and month > max[0]:
                continue
            string = ('0' + str(month))[-2:]+'\''+str(year)
            if e == 'date':
                print(string, end=' ')
            else:
                print(1 if (tuple(string.split('\'')) in x[e]) else 0, end=' ')
    print()


import gzip
import json
import logging
import mimetypes
import re
import sys
import traceback
from enum import Enum
import extruct
import rdflib
import requests
import urllib
import ssl
from requests.packages.urllib3.exceptions import *
from tika import parser
from fuji_server.helper.preprocessor import Preprocessor

class AcceptTypes(Enum):
    #TODO: this seems to be quite error prone..
    datacite_json = 'application/vnd.datacite.datacite+json'
    datacite_xml = 'application/vnd.datacite.datacite+xml'
    schemaorg = 'application/vnd.schemaorg.ld+json'
    html = 'text/html, application/xhtml+xml'
    xml = 'application/xml, text/xml;q=0.5'
    json = 'application/json, text/json;q=0.5'
    jsonld = 'application/ld+json'
    rdfjson = 'application/rdf+json'
    nt = 'text/n3, application/n-triples'
    rdfxml = 'application/rdf+xml, text/rdf;q=0.5, application/xml;q=0.1, text/xml;q=0.1'
    turtle = 'text/ttl, text/turtle, application/turtle, application/x-turtle;q=0.6, text/n3;q=0.3, text/rdf+n3;q=0.3, application/rdf+n3;q=0.3'
    rdf = 'text/turtle, application/turtle, application/x-turtle;q=0.8, application/rdf+xml, text/n3;q=0.9, text/rdf+n3;q=0.9,application/ld+json'
    default = '*/*'

class RequestHelper:
    def __init__(self, url, logInst: object = None):
        if logInst:
            self.logger = logInst
        else :
            self.logger = Preprocessor.logger #logging.getLogger(__name__)
        self.request_url = url
        self.redirect_url = None
        self.accept_type = AcceptTypes.default.value
        self.http_response = None
        self.parse_response = None
        self.response_status = None
        self.response_content = None # normally the response body
        self.response_header = None
        self.response_charset = 'utf-8'

    def setAcceptType(self, accepttype):
        if not isinstance(accepttype, AcceptTypes):
            raise TypeError('type must be an instance of AcceptTypes enum')
        self.accept_type = accepttype.value

    def getAcceptType(self):
        return self.accept_type

    def setRequestUrl(self, url):
        self.request_url = url

    def getHTTPResponse(self):
        return self.http_response

    def getResponseContent(self):
        return self.response_content.decode(self.response_charset)

    def getParsedResponse(self):
        return self.parse_response

    def getResponseHeader(self):
        return self.response_header

    def content_decode(self,content):
        if isinstance(content, 'str'):
          a=1
        return True

    def content_negotiate(self, metric_id=''):
        #TODO: not necessarily to be done with the landing page e.g. http://purl.org/vocommons/voaf resolves to a version URL which responds HTML instead of RDF
        self.metric_id=metric_id
        source = 'html'
        status_code = None
        if self.request_url is not None:
            try:
                self.logger.info('{0} : Retrieving page {1}'.format(metric_id, self.request_url))
                #TODO: find another way to handle SSL certficate problems; e.g. perform the request twice and return at least a warning
                tp_request = urllib.request.Request(self.request_url, headers={'Accept': self.accept_type, 'User-Agent': 'F-UJI'})
                context = ssl._create_unverified_context()
                tp_response =  urllib.request.urlopen(tp_request,context=context)
                self.http_response = tp_response
                self.response_content = tp_response.read()
                if tp_response.info().get('Content-Encoding') == 'gzip':
                    self.response_content = gzip.decompress(self.response_content)
                if tp_response.info().get_content_charset():
                    self.response_charset = tp_response.info().get_content_charset()
                self.response_header = tp_response.getheaders()
                self.redirect_url = tp_response.geturl()
                #self.http_response = requests.get(self.request_url, headers={'Accept': self.accept_type})
                #status_code = self.http_response.status_code
                self.response_status = status_code = self.http_response.status
                self.logger.info(
                    '%s : Content negotiation accept=%s, status=%s ' % (metric_id, self.accept_type, str(status_code)))
                if status_code == 200:
                    content_type = self.http_response.headers.get("Content-Type")
                    #try to find out if content type is byte then fix
                    try:
                        self.response_content.decode('utf-8')
                    except (UnicodeDecodeError, AttributeError):
                        self.response_content = str(self.response_content).encode('utf-8')
                    if content_type is None:
                        content_type = mimetypes.guess_type(self.request_url, strict=True)[0]
                    if content_type is None:
                        #just in case tika is not running use this as quick check for the most obvious
                        if re.match(r"<!doctype html>|<html",str(self.response_content.decode(self.response_charset)).strip(),re.IGNORECASE) is not None:
                            content_type ='text/html'
                    if content_type is None:
                        parsedFile = parser.from_buffer(self.response_content)
                        content_type = parsedFile.get("metadata").get('Content-Type')

                    if content_type is not None:
                        if 'text/plain' in content_type:
                            source = 'text'
                            self.logger.info('%s : Plain text has been responded as content type!' % metric_id)
                            #try to find type by url
                            guessed_format = rdflib.util.guess_format(self.request_url)
                            if guessed_format is not None:
                                self.parse_response  = self.parse_rdf(self.response_content.decode(self.response_charset), guessed_format)
                                source='rdf'
                                  #content_type = content_type.split(";", 1)[0]
                        else:
                            content_type = content_type.split(";", 1)[0]
                            while (True):
                                for at in AcceptTypes: #e.g., at.name = html, at.value = 'text/html, application/xhtml+xml'
                                    if content_type in at.value:
                                        if at.name == 'html':
                                            self.logger.info('%s : Found HTML page!' % metric_id)

                                            self.parse_response = self.parse_html(self.response_content.decode(self.response_charset))
                                            source='html'
                                            break
                                        if at.name == 'xml': # TODO other types (xml)
                                            #in case the XML indeed is a RDF:
                                            # quick one:
                                            if self.response_content.decode(self.response_charset).find('<rdf:RDF') > -1:
                                                self.logger.info('%s : Found RDF document by tag!' % metric_id)
                                                self.parse_response = self.parse_rdf(self.response_content.decode(self.response_charset), at.name)
                                                source='rdf'
                                            else:
                                                self.logger.info('%s : Found XML document!' % metric_id)
                                                self.parse_response  = self.response_content
                                                source='xml'
                                            break
                                        if at.name in ['schemaorg', 'json', 'jsonld', 'datacite_json']:
                                            try:
                                                self.parse_response  = json.loads(self.response_content)
                                                source='json'
                                                # result = json.loads(response.text)
                                                break
                                            except ValueError:
                                                self.logger.info(
                                                    '{0} : Retrieved response seems not to be valid JSON'.format(metric_id))

                                        if at.name in ['nt','rdf', 'rdfjson', 'ntriples', 'rdfxml', 'turtle']:
                                            self.parse_response  = self.parse_rdf(self.response_content, content_type)
                                            source='rdf'
                                            break

                                    # TODO (IMPORTANT) how to handle the rest e.g., text/plain, specify result type
                                break
                    else:
                        self.logger.warning('{0} : Content-type is NOT SPECIFIED'.format(metric_id))
                else:
                    self.logger.warning('{0} : NO successful response received, status code - {1}'.format(metric_id, str(status_code)))
            #except requests.exceptions.SSLError as e:
            except urllib.error.HTTPError as e:
            #    self.logger.warning('%s : SSL Error: Untrusted SSL certificate, failed to connect to %s ' % (metric_id, self.request_url))
            #    self.logger.exception("SSLError: {}".format(e))
            #    self.logger.exception('%s : SSL Error: Failed to connect to %s ' % (metric_id, self.request_url))
            #except requests.exceptions.RequestException as e:
                #All exceptions that Requests explicitly raises inherit from requests.exceptions.RequestException
                #self.logger.warning('%s : Request Error: Failed to connect to %s ' % (metric_id, self.request_url))
                self.logger.warning('%s : Content negotiation failed: accept=%s, status=%s ' % (metric_id, self.accept_type, str(e.code)))
                #self.logger.exception("{} : RequestException: {}".format(metric_id, e))
                #traceback.print_exc()
                #self.logger.exception('%s : Failed to connect to %s ' % (metric_id, self.request_url))
            except urllib.error.URLError as e:
                self.logger.warning("{} : RequestException: {} : {}".format(metric_id, e.reason, self.request_url))
                #self.logger.warning('%s : Content negotiation failed: accept=%s, status=%s ' % (metric_id, self.accept_type, str(e.code)))
        return source, self.parse_response

    def parse_html(self, html_texts):
        # extract contents from the landing page using extruct, which returns a dict with
        # keys 'json-ld', 'microdata', 'microformat','opengraph','rdfa'
        try:
            extracted = extruct.extract(html_texts.encode('utf8'))
        except:
            extracted=None
            self.logger.warning('%s : Failed to perform parsing on microdata or JSON %s' % (self.metric_id, self.request_url))
        #filtered = {k: v for k, v in extracted.items() if v}
        return extracted

    def parse_rdf(self, response, type):
        # TODO (not complete!!)
        # https://rdflib.readthedocs.io/en/stable/plugin_parsers.html
        # https://rdflib.readthedocs.io/en/stable/apidocs/rdflib.html#rdflib.graph.Graph.parse
        graph = None
        try:
            self.logger.info('%s : Try to parse RDF from %s' % (self.metric_id, self.request_url))
            graph = rdflib.Graph()
            graph.parse(data=response, format=type)
            #queries have to be done in specific metadata collector classes
        except:
            error = sys.exc_info()[0]
            self.logger.warning('%s : Failed to parse RDF %s %s' % (self.metric_id, self.request_url, str(error)))
            self.logger.debug(error)
        return graph

    # RDF data syntaxes (xml, n3, ntriples, trix, JSON-LD, ...)
    # Turtle is a simplified, RDF-only subset of N3.
    # N-Quads media type is application/n-quads and encoding is UTF-8.
    # N3 (Notation3) media type is text/n3, but text/rdf+n3 is also accepted. Character encoding is UTF-8.
    # JSON-LD media type is application/ld+json and the encoding is UTF-8.
    # RDF/JSON media type is application/rdf+json and the encoding is UTF-8.
    # RDF/XML media type is application/rdf+xml, but application/xml and text/xml are also accepted. The character encoding is UTF-8.
    # N-Triples media type is application/n-triples and encoding is in UTF-8.
    # Turtle media type is text/turtle, but application/x-turtle is also accepted. Character encoding is UTF-8.
    # RDFa media type is application/xhtml+xml and the encoding is UTF-8.
    # TODO handle 406 Not Acceptable or 300 Multiple Choices
    # TODO transform accept_types and parser types into a class

    def parse_xml(self, response, type):
        # TODO: implement a generic XML parsing which checks domain specific
        # document schema and performs a XSLT to get metadata elements
        # write some domain specific XSLTs and/or parsers
        self.logger.info('%s : Try to parse XML from %s' % (self.metric_id, self.request_url))
        self.logger.warning('%s : Domain specific XML parsing not yet implemented ' % (self.metric_id,))
        #print('Not yet implemented')
        return None


from flask import render_template
from flask import request
from flask import Flask

from replit import db
import datetime
import time

app = Flask(__name__)

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

@app.route('/history', methods=['GET', 'POST'])
def history():
  if request.method == 'GET':
    return render_template('history.html', data=db['history'])
  else:
    db['history'] = request.json['history']
    return {'success': True}

@app.route('/sync')
def sync():
  if time.time()-db['last_synced'] > 10:
    return {
      'internet': False,
      'last_synced': [round(float(i)) for i in str(datetime.timedelta(seconds=time.time()-db['last_synced'])).split(':')]
    }
  else:
    return {
      'internet': True,
      'last_synced': round(time.time()-db['last_synced'])
    }

@app.route('/update', methods=['POST'])
def update():
  if request.headers.get('x-forwarded-for') == 'YOUR IP':
    db['last_synced'] = float(request.form['last_synced'])

  return {'success': True}

# db['last_synced'] = time.time()
# db['history'] = []
app.run(host='0.0.0.0', port=8080)