import re
import os

import json
from difflib import SequenceMatcher

# data = ""
# lines = open("01.txt").readlines()
# for i, line in enumerate(lines):
#     data += line
#     if i %  8 in (0, 1):
#         data += "\n"

#     if i == 20:
#         break

def parse(data):
    questions = []
    pattern = re.compile(
        # r'(([0-9]+)\))([^\n]+)[\n]+([^\n]+)[\n]+([A]\)([^\n]+))[\n]+([B]\)([^\n]+))[\n]+([C]\)([^\n]+))[\n]+([D]\)([^\n]+))[\n]+([E]\)([^\n]+))',

        r'(([0-9]+)\.)([^\n]+)[\n]+([^\n]+)[\n]+([A]\)([^\n]+))[\n]+([B]\)([^\n]+))[\n]+([C]\)([^\n]+))[\n]+([D]\)([^\n]+))[\n]+([E]\)([^\n]+))',
        flags=re.IGNORECASE)

    for match in re.finditer(pattern, data):
        found = match.groups()
        question = {
            'no': found[1].strip(),
            'paragraph': found[2].strip(),
            'text': found[3].strip(),
            'answers': {'A': found[5].strip(), 'B': found[7].strip(), 'C': found[9].strip(), 'D': found[11].strip(), 'E': found[13].strip()},
            'isSimilarity': None,
            'correct': '',
        }

        nonsimilarityDeterminers = 'mamıştır|memiştir|memistir|lamaz|emez|değildir|yoktur|olmaz|bağdaşmaz|çelişir|beklenmez|yanlıştır'
        similarityDeterminers = 'abilir|ebilir|maktadır|mektedir|ıdır|idir|udur|edir|mıştır|miştir|muştur|sonuçtur|gerekir|beklenir|içerir|kaynaklanır|nitelendirilir|koyar'
        if re.search(nonsimilarityDeterminers, question['text']):
            question['isSimilarity'] = False
        elif re.search(similarityDeterminers, question['text']):
            question['isSimilarity'] = True
        else:
            # for correction
            print(question['no'], question['text'])
            exit(1)

        questions.append(question)

    i = data.find("CEVAP ANAHTARI")
    if i < 0:
        print("cevap anahtari yok")
        exit(1)

    cevapAnahtari = data[i + data[i:].find("\n"):].strip()
    print(cevapAnahtari)
    cevapAnahtari = [x.split("-") for x in cevapAnahtari.split(" ") if x != ""]
    cevapAnahtari = {int(x[0]):x[1] for x in cevapAnahtari}

    for q in questions:
        cevap = cevapAnahtari[int(q["no"])]
        assert(cevap in "ABCDE")
        q["correct"] = cevap

    return questions

questions = []

path = "./ana-dusunce/"
for fileNo in range(1, 25):
    if fileNo < 10:
        fileName = "0%d.txt" % fileNo
    else:
        fileName = "%d.txt" % fileNo
    fileName = os.path.join(path, fileName)
    data = open(fileName).read()
    print(fileName)
    questions.extend(parse(data))

path = "./yardimci-dusunce/"
for fileNo in range(1, 8):
    fileName = os.path.join(path, "0%d.txt" % fileNo)
    data = open(fileName).read()
    print(fileName)
    questions.extend(parse(data))

Q = []
LIMIT = 80
for i in range(len(questions)):
    print("%d / %d" % (i, len(questions)), end='\r')
    A = questions[i]["paragraph"][:LIMIT]

    found = False
    for j in range(i):
        B = questions[j]["paragraph"][:LIMIT]
        ratio = SequenceMatcher(None, A, B).ratio()
        if ratio > 0.8:
            found = True
            print(A)
            print(B)
            print(" ")
            break

    if not found:
        Q.append(questions[i])

print(len(questions))
print(len(Q))
questions = Q
# exit(1)
# print(len(questions))

paragraphs = []

olumlu = 0
olumsuz = 0

for q in questions:
    paragraphs.append(q["paragraph"][:LIMIT])
    if q["isSimilarity"]:
        olumlu += 1
    else:
        olumsuz += 1

print("olumlu:", olumlu)
print("olumsuz:", olumsuz)

#     print(question["no"])
#     print(question["paragraph"])
#     print(question["answers"])
#     print(question["isSimilarity"])
#     print()

ayniSorular = []
data = json.load(open('/taner/mnt/usbhdd2p1/docker/wd/python3/home/taner/ha-yayin/data.json', encoding="utf-8"))
for qNoA, q in enumerate(data):
    print(qNoA, end='\r')
    A = q["paragraph"][:LIMIT]
    for qNoB, B in enumerate(paragraphs):
        ratio = SequenceMatcher(None, A, B).ratio()
        if ratio > 0.8:
            # print(A)
            # print(B)
            # print()
            ayniSorular.append((qNoA, qNoB))
            break

print("A:", qNoA)
print("B:", len(questions))
print("ortak:", len(ayniSorular))

print("birlesim:", len(questions) + qNoA - len(ayniSorular))

with open("tumYeniSorular.json", "w") as outfile:
    json.dump(questions, outfile)

ayniSorular = set(x[1] for x in ayniSorular)
questions = [q for i, q in enumerate(questions) if i not in ayniSorular]
print(len(questions))

with open("farkliYeniSorular.json", "w") as outfile:
    json.dump(questions, outfile)


import pandas as pd
import pickle

from flask import Flask, jsonify, request

# Load the model
pickle_in = open('rfc.pkl', 'rb')
model = pickle.load(pickle_in)

# Init the app
app = Flask("default")

# Setup prediction endpoint
@app.route("/predict", methods=["POST"])
def predict():
    data = request.get_json()

    # Make predictions for each feature vector
    predictions = model.predict(pd.DataFrame([data]))

    # Create a response with class probabilities for each sample
    result = {"predictions": predictions[0]}

    return jsonify(result)

if __name__ == "__main__":
    # Run the app on local host and port 8000
    app.run(debug=True, host="0.0.0.0", port=8000)


import pandas as pd
import numpy as np

from loading import load_train, load_test

CONTEXT_TYPE_TEST = [1, 5, 20, 23]

class Preprocessing():
    """Load, clean and creature new features.

    Parameters
    ----------
    categorize_features : list of str
        The features to compute the counts and ratios.
    listen_type_features : list of str
        The features to compute the flow counts and ratios.
    combo_features1 : list of str
        The 1st feature of the conditional counts and ratios.
    combo_features2 : list of str
        The 2nd feature of the conditional counts and ratios.
    features_4_test_correction : list of str
        The features to correct in the test.
    fillna : bool
        If we fill the NaN values.
    """
    def __init__(self,
                 categorize_features=['user_id', 'artist_id', 'media_id', 'genre_id'],
                 listen_type_features=['user_id', 'media_id', 'media_id', 'genre_id'],
                 combo_features1=['user_id'],
                 combo_features2=['genre_id', 'artist_id', 'platform_family'],
                 features_4_test_correction=['user_id', 'artist_id', 'media_id', 'genre_id'],
                 drop_features=['album_id'],
                 flow_features=False,
                 context_features=False,
                 fillna=False):

        self.categorize_features = categorize_features
        self.listen_type_features = listen_type_features
        self.combo_features1 = combo_features1
        self.combo_features2 = combo_features2
        self.features_4_test_correction = features_4_test_correction
        self.drop_features = drop_features
        self.flow_features = flow_features
        self.context_features = context_features
        self.fillna = fillna

    @property
    def features_bis(self):
        """The bis features
        """
        features_bis = []
        for feat in self.train.columns:
            if '_bis' in feat:
                features_bis.append(feat)

        return features_bis

    @property
    def features_count(self):
        """The count features.
        """
        features_count = []
        for feat in self.features:
            if '_count' in feat:
                features_count.append(feat)

        return features_count

    @property
    def features_ratio(self):
        """The raio features.
        """
        features_ratio = []
        for feat in self.features:
            if '_ratio' in feat:
                features_ratio.append(feat)

        return features_ratio

    @property
    def features(self):
        """The features used in the prediction model.
        """
        other_features = ['listen_type', 'is_context', 'is_context_flow',
                  'is_listened_context', 'is_listened_flow',
                  'is_listened_context_flow']

        drop_features = self.categorize_features + self.drop_features + other_features + self.features_bis
        features = np.setdiff1d(self.train.columns.tolist(), drop_features + ['is_listened'], assume_unique=True)

        return features

    def load_raw_data(self, nrows=None, save_to_hdf=False):
        """Load the data from the csv or hdf (if it exists)

        Parameters
        ----------
        nrows : int or None
            The number of lines to load in the train.
        save_to_hdf : bool
            If the file is saved in hdf after beeing loaded
        """
        train = load_train(nrows=nrows, save_to_hdf=save_to_hdf)
        test = load_test(save_to_hdf=save_to_hdf)

        train.drop(self.drop_features, axis=1, inplace=True)
        test.drop(self.drop_features, axis=1, inplace=True)

        correct_dates(train)
        to_datetime(train, keep_dates=True)
        correct_dates(test)
        to_datetime(test, keep_dates=True)
        test.loc[test.listen_type == 0, 'listen_type'] = 1

        train['diff_days'] = (train.dt_listen - train.dt_media).dt.days
        test['diff_days'] = (test.dt_listen - test.dt_media).dt.days
        train.drop(['dt_listen', 'dt_media',], axis=1, inplace=True)
        test.drop(['dt_listen', 'dt_media',], axis=1, inplace=True)

        train.to_pickle('../input/train_clean.pkl')
        test.to_pickle('../input/test_clean.pkl')

        self.train = train
        self.test = test

    def load_cleaned_data(self):
        """Load the data cleaned.
        """
        try:
            self.train = pd.read_pickle('../input/train_clean.pkl')
            self.test = pd.read_pickle('../input/test_clean.pkl')
        except FileNotFoundError:
            self.load_raw_data()

    def create_new_features(self):
        """Create the new features count and ratios.
        """
        train = self.train

        train['is_context'] = train['context_type'].isin(CONTEXT_TYPE_TEST)
        train['is_context_flow'] = train['listen_type'] * train['is_context']

        train['is_listened_context'] = train['is_listened'] * train['is_context']
        train['is_listened_flow'] = train['is_listened'] * train['listen_type']
        train['is_listened_context_flow'] = train['is_listened'] * train['is_context_flow']

        for feature in self.categorize_features:
            gby_feat = train.groupby(feature)
            new_features(train, gby_feat, feature, feature in self.listen_type_features, self.context_features, self.flow_features, self.fillna)

        # Variable combinations
        for feat1 in self.combo_features1:
            for feat2 in self.combo_features2:
                gby_feat = train.groupby([feat1, feat2])
                name = feat1 + '_' + feat2
                new_features(train, gby_feat, name, feat1 in self.listen_type_features, self.context_features, self.flow_features, self.fillna)

    def create_time_features(self):
        """
        """
        train.sort(['user_id', 'ts_listen'], ascending=[True, True], inplace=True)
        train = train.reset_index(drop=True)

        test.sort(['user_id', 'ts_listen'], ascending=[True, True], inplace=True)
        test = test.reset_index(drop=True)
        dict_chronology_var = add_chronology_var(data_train = train[["user_id","ts_listen","listen_type","is_listened","media_duration"]],
                                        data_test = test[["user_id","ts_listen","listen_type","media_duration"]])

        train['is_last_listened'] = dict_chronology_var['train'].is_last_listened.values
        train['time_since_last_listen'] = dict_chronology_var['train'].time_since_last_listen.values

        test['is_last_listened'] = dict_chronology_var['test'].is_last_listened.values
        test['time_since_last_listen'] = dict_chronology_var['test'].time_since_last_listen.values

    def add_features_in_test(self, low=1, high=5, keep_full_train=False):
        """Merge the count and ratios of the user_id in the test file.

        Parameters
        ----------
        low : int
            Minimum count for the context in the randomization.
        high : int
            Maximum count for the context in the randomization.
        keep_full_train : bool
            If the full train is kept in the train_full attribute.
        """
        train = self.train
        test = self.test

        if keep_full_train:
            self.train_full = self.train.copy()

        for feature in self.categorize_features:
            gby_feat = train.groupby([feature])
            test = add_in_test(test, gby_feat, feature, feature in self.listen_type_features, feature, self.context_features, self.flow_features, self.fillna)

        for feat1 in self.combo_features1:
            for feat2 in self.combo_features2:
                gby_feat = train.groupby([feat1, feat2])
                name = feat1 + '_' + feat2
                test = add_in_test(test, gby_feat, name, feat1 in self.listen_type_features, [feat1, feat2], self.context_features, self.flow_features, self.fillna)

        self.train = train[(train.listen_type==1) & train.context_type.isin(CONTEXT_TYPE_TEST)].copy()

        # Correction
        for feat in self.features_4_test_correction:
            name = feat + '_context_flow_count_bis'
            ids = test[name].isnull() | (test[name]==0)
            test.loc[ids, name] = np.random.random_integers(low=low, high=high, size=ids.sum())
            if feat == 'genre_id':
                test.loc[(test[name] == 0), name] = 1

        self.test = test

    def save_data_pickle(self, save_full=False):
        """Save the data in a pickle file.

        Parameters
        ----------
        save_full : bool
            If the full train is also saved
        """
        self.train.to_pickle('../input/train_mod.pkl')
        self.test.to_pickle('../input/test_mod.pkl')
        if save_full:
            self.train_full.to_pickle('../input/train_full_mod.pkl')

    def load_data_pickle(self, load_full=False):
        """Load the data from the pickle file.
        """
        self.train = pd.read_pickle('../input/train_mod.pkl')
        self.test = pd.read_pickle('../input/test_mod.pkl')
        if load_full:
            self.train_full = pd.read_pickle('../input/train_full_mod.pkl')

def new_features(train, gby_feat, name, is_listen_type_feature, context_features, flow_features, fillna):
    """Create the count and ratio for a given groupby
    """

    # count and ratio on the all train
    count = gby_feat['is_listened'].transform('count')
    train[name + '_count'] = count
    train[name + '_count_bis'] = count
    train[name + '_ratio'] = gby_feat['is_listened'].transform('mean')

    if context_features:
        # Count and ratio for context observations
        count = gby_feat['is_context'].transform('sum')
        train[name + '_context_count'] = count
        train[name + '_context_count_bis'] = count
        train[name + '_context_ratio'] = gby_feat['is_listened_context'].transform('sum')/(1.*count)
        # Note that there should be NaN values if count=0.
        if fillna:
            train[name + '_context_ratio'].fillna(0.5, inplace=True)

    # Count and ration fot the flow observations
    if is_listen_type_feature:
        if flow_features:
            count = gby_feat['listen_type'].transform('sum')
            train[name + '_flow_count'] = count
            train[name + '_flow_count_bis'] = count
            train[name + '_flow_ratio'] = gby_feat['is_listened_flow'].transform('sum')/(1.*count)
            if fillna:
                train[name + '_flow_ratio'].fillna(0.5, inplace=True)

        count = gby_feat['is_context_flow'].transform('sum')
        train[name + '_context_flow_count'] = count
        train[name + '_context_flow_count_bis'] = count
        train[name + '_context_flow_ratio'] = gby_feat['is_listened_context_flow'].transform('sum')/(1.*count)
        if fillna:
            train[name + '_context_flow_ratio'].fillna(0.5, inplace=True)

def add_in_test(test, gby_feat, name, is_listen_type_feature, on_features, context_features, flow_features, fillna):
    """
    """
    test = test.join(gby_feat[name + '_count'].mean(), on=on_features)
    test = test.join(gby_feat[name + '_count_bis'].mean(), on=on_features)
    test = test.join(gby_feat[name + '_ratio'].mean(), on=on_features)
    if fillna:
        test[name + '_count'].fillna(0, inplace=True)
        test[name + '_count_bis'].fillna(0, inplace=True)
        test[name + '_ratio'].fillna(0.5, inplace=True)

    if context_features or not is_listen_type_feature:
        test = test.join(gby_feat[name + '_context_count'].mean(), on=on_features)
        test = test.join(gby_feat[name + '_context_count_bis'].mean(), on=on_features)
        test = test.join(gby_feat[name + '_context_ratio'].mean(), on=on_features)
        if fillna:
            test[name + '_context_count'].fillna(0, inplace=True)
            test[name + '_context_count_bis'].fillna(0, inplace=True)
            test[name + '_context_ratio'].fillna(0.5, inplace=True)

    if is_listen_type_feature:
        if flow_features:
            test = test.join(gby_feat[name + '_flow_count'].mean(), on=on_features)
            test = test.join(gby_feat[name + '_flow_count_bis'].mean(), on=on_features)
            test = test.join(gby_feat[name + '_flow_ratio'].mean(), on=on_features)
            if fillna:
                test[name + '_flow_count'].fillna(0, inplace=True)
                test[name + '_flow_count_bis'].fillna(0, inplace=True)
                test[name + '_flow_ratio'].fillna(0.5, inplace=True)

        test = test.join(gby_feat[name + '_context_flow_count'].mean(), on=on_features)
        test = test.join(gby_feat[name + '_context_flow_count_bis'].mean(), on=on_features)
        test = test.join(gby_feat[name + '_context_flow_ratio'].mean(), on=on_features)
        if fillna:
            test[name + '_context_flow_count'].fillna(0, inplace=True)
            test[name + '_context_flow_count_bis'].fillna(0, inplace=True)
            test[name + '_context_flow_ratio'].fillna(0.5, inplace=True)

    return test

def add_chronology_var(data_train, data_test):
    # on doit mettre train et test avec comme variables :
    # user_id, time_listen, is_listened (train)

    # variable is_last_listened
    data_train = train[["user_id","ts_listen","listen_type","is_listened","media_duration"]]
    data_test = test[["user_id","ts_listen","listen_type","media_duration"]]
    data_test['is_listened'] = -1
    data = pd.concat([data_train, data_test], axis=0, ignore_index=True)
    data.sort(['user_id', 'ts_listen'], ascending=[True, True], inplace=True)
    data = data.reset_index(drop=True)

    ## is_last_listened
    data['is_last_listened'] = -1
    index_test = np.where(data['is_listened'] == -1)[0]
    index_train = np.setdiff1d(np.arange(data.shape[0]), index_test)
    index_new_user = np.append(np.array([0]) , index_test[:(len(index_test)-1)] + 1)
    index_not_new_user = np.setdiff1d(np.arange(data.shape[0]), index_new_user)
    data.is_last_listened[index_not_new_user] = data.is_listened[(index_not_new_user-1)].values

    ## time_since_last_isten
    data['time_since_last_listen']= -1
    data.time_since_last_listen[index_not_new_user] = (data.ts_listen[index_not_new_user].values -
                                                       data.ts_listen[(index_not_new_user-1)].values)

    return {'train' : data.ix[index_train, ['is_last_listened','time_since_last_listen']] ,
            'test' : data.ix[index_test, ['is_last_listened','time_since_last_listen']]}

def correct_dates(data, date_feature='release_date'):
    """Correct weird dates.
    """
    data.loc[data[date_feature] < 19170000, date_feature] += 1000000
    data.loc[data[date_feature] > 20180000, date_feature] -= 10000000

def to_datetime(data, keep_dates=False):
    """Categorize the dates from the data and correct the inconsistencies.

    Parameters
    ----------
    data : pd.Dataframe
        The data with the features "ts_listen" and "ts_listen".
    """
    # Date series
    dates_listen = pd.to_datetime(data['ts_listen'], unit='s')
    dates_media = pd.to_datetime(data['release_date'], format="%Y%m%d")

    # When the listen dates are before the release dates
    idx_wrong_dates = np.where(dates_listen < dates_media)[0]
    for idx in idx_wrong_dates:
        dates_listen[idx] = dates_listen[idx].replace(
            day=dates_media[idx].day,
            month=dates_media[idx].month,
            year=dates_media[idx].year)

    # Replace the year of the date before the creation of deezer...
    tmp = dates_listen.dt.year < 2016
    dates_listen[tmp] = dates_listen[tmp].apply(lambda dt: dt.replace(year=2016))

    # Add the new features and drop the previous ones
    data.drop(['ts_listen', 'release_date'], axis=1, inplace=True)
    data['day_listen'] = dates_listen.dt.weekday
    data['hour_listen'] = dates_listen.dt.hour
    data['year_media'] = dates_media.dt.year

    if keep_dates:
        data['dt_listen'] = dates_listen
        data['dt_media'] = dates_media


import sys
import segmentModule as seg
import extractionModule as analyze
import numpy as np
import cv2
import time
import re
import pickle
import feature as f
import gabor_threads_roi as gabor
import os

#GLOBAL FLAG VARIABLES
#flags that are handled
showflag = 'show' in sys.argv
hogflag = 'hog' in sys.argv
binflag = 'bin' in sys.argv
sizeflag = 'size' in sys.argv
colorflag = 'color' in sys.argv
gaborflag = 'gabor' in sys.argv
hsvflag = 'hsv' in sys.argv
msflag = 'meanshift' in sys.argv
msbinflag = 'meanshiftbin' in sys.argv
fjmsflag = 'fjmeanshift' in sys.argv
qsflag = 'quickshift' in sys.argv
dbscanflag = 'dbscan' in sys.argv
pcaflag = 'pca' in sys.argv
ldaflag = 'lda' in sys.argv
wtflag = 'wt' in sys.argv
bifflag = 'bif' in sys.argv
blurflag = 'blur' in sys.argv
domcolorflag = 'domcolor' in sys.argv
#Check system argument length and mode
#if mode is bin do 3d color binning
start_time = time.time()

#display different modes
def display(original,labels=None,SHOWFLAG=True):

    #if mode is meanshift, apply meanshift
    if msflag:
        image, labels = analyze.meanshift(original)
        print(labels)
        if SHOWFLAG:
            seg.showSegments(image,labels)

    #if mode is meanshiftbin, convert 2d image to 3d using bin method and apply meanshift
    elif msbinflag:
        image,labels = analyze.meanshift(original,binning=True)
        print(labels)
        if SHOWFLAG:
            seg.showSegments(image,labels)

    #if mode is fjmeanshift, do fjmeanshift
    elif fjmsflag:
        if SHOWFLAG:
            image,labels = seg.getSegments(original,True)
        else:
            image,labels = seg.getSegments(original,False)
        print(labels)

    #if mode is fjmeanshift, do fjmeanshift
    elif qsflag:
        labels = analyze.quickmeanshift(original)
        if SHOWFLAG:
            seg.showSegments(original,labels)

    #if mode is meanshiftbin, convert 2d image to 3d using bin method and apply meanshift
    elif dbscanflag:
        image,labels = analyze.dbscan(original,binning=True)
        print(labels)
        if SHOWFLAG:
            seg.showSegments(image,labels)

    #if mode is size
    elif sizeflag:
        combined_filename = sys.argv[1]

        # Generate and save blob size for this blob we assume black as background
        size = analyze.extractBlobSize(original)
        print('--------------SIZE---------------')
        if SHOWFLAG:
            print(size)
        return size

    #if mode is dominant colors:
    elif domcolorflag:

        canvas = np.zeros(original.shape)
        h,w,d = canvas.shape
        for i in range(5,h-6):
            for j in range(5,w-6):
                centers = f.k_means_color(original[i-5:i+5,j-5:j+5,:])
                canvas[i,j] = centers[0]

        cv2.imshow('original image',original)
        cv2.imshow('dominant color image',canvas.astype(np.uint8))
        cv2.waitKey(0)

        '''
        centers = f.k_means_color(original)
        cv2.imshow('original image',original)
        for i,c in enumerate(centers):
            tmp = np.full((100,100,3),c)
            cv2.imshow('dom color ' + str(i),tmp)
        cv2.waitKey(0)
        '''

        return 1

    #if mode is texture
    elif textureflag:

        return 1

    #if mode is hog, show hog feature vector of image
    elif hogflag:
        hist = analyze.extractHOG(original,False)
        featurevector = hist.flatten()
        norm = analyze.normalize(featurevector)
        analyze.visualizeHOG(original)
        print('-------------HOG----------------')
        if SHOWFLAG:
            analyze.displayHistogram(featurevector)
        return norm

    #if mode is wavelettransform
    elif wtflag:
        analyze.visualizeWT(original,show=True)
        return 1

    #if mode is gabor, extract gabor feature from image using several orientations
    elif gaborflag:
        orientations = 16
        filters = gabor.build_filters(orientations)
        combined_filename = sys.argv[1]

        # Generate and save ALL hogs for this image
        result = gabor.run_gabor(original, filters, combined_filename, orientations, mode='training')
        featurevector = result.flatten()[1:]
        norm = analyze.normalize(featurevector)
        print('--------------Gabor---------------')
        if SHOWFLAG:
            analyze.displayHistogram(featurevector,'r--')
        return norm

    #if mode is color, show color histogram of image
    elif colorflag:
        hist = analyze.extractColorHist(original,False)
        print('-------------Color----------------')
        if SHOWFLAG:
            analyze.displayHistogram(hist)
        return hist

    elif binflag:
        hist = analyze.extractbinHist(original,False)
        norm = analyze.normalize(hist)
        if SHOWFLAG:
            analyze.displayHistogram(norm)
        return norm

    elif bifflag:
        gray = cv2.cvtColor(original,cv2.COLOR_BGR2GRAY)
        y,x = np.where(gray >= 0)
        out = analyze.bilinear_interpolate(gray,x,y).reshape((gray.shape))
        cv2.namedWindow('bilinear filtering', cv2.WINDOW_NORMAL)
        cv2.imshow('bilinear filtering', out.astype(np.uint8))
        cv2.waitKey(0)
        return 1

    elif blurflag:
        analyze.blurErode(original)

        return 1

    elif hsvflag:
        hsvimg = cv2.cvtColor(original, cv2.COLOR_BGR2HSV)
        hist = analyze.extractHSVHist(hsvimg,False)
        if SHOWFLAG:
            analyze.displayHistogram(hist)

        return hist

def scatter(instances,labels):
    if pcaflag:
        analyze.showPCA(instances,labels)

    elif ldaflag:
        optionID = sys.argv.index('lda') + 1
        if optionID <= len(sys.argv) - 1:
            option = sys.argv[optionID]
            analyze.showLDA2(instances,labels,classes=option)
        else:
            analyze.showLDA(instances,labels,mode='int')

if __name__ == '__main__':

    if len(sys.argv) >= 2:

        #if user input is doing lda or pca
        if os.path.isfile(sys.argv[1]) and (ldaflag or pcaflag):

            if os.path.splitext(sys.argv[1])[1] == '.npy':
                tmp = np.load(sys.argv[1],mmap_mode='r')
                instances = tmp[:,:-1].astype(float)
                labels = tmp[:,-1:].astype(int)
            elif os.path.isfile(sys.argv[2]):
                img = cv2.imread(sys.argv[1],cv2.IMREAD_COLOR)
                mask = cv2.imread(sys.argv[2],cv2.IMREAD_COLOR)
                seg_image,labels = seg.getSegments(img,False)

            scatter(instances,labels)

        #if user input to visuzlize is an image file
        else:
            #evaluate single image
            #check if the image was read in correctly
            if os.path.isfile(sys.argv[1]):
                original = cv2.imread(sys.argv[1],cv2.IMREAD_COLOR)
                display(original)
            else:
                print('invalid image! Could not open: %s' % sys.argv[1])
                quit()

    #if less than 3 args given
    else:
        print("wrong number of files as arguments expecting 3:")
        print("argv1 = image file/directory")
        print("argv2 + = modes of operation")
        sys.exit()

    #find out execution time
    print("--- %s seconds ---" % (time.time() - start_time))


import numpy as np
from numpy.linalg import norm

class ShapeCollection:
    def __init__(self):
        self.shapes = []

    def addShape(self, shape):
        self.shapes.append(shape)

    def computeMinDistance(self, X, Y):
        if len(self.shapes) == 0:
            return None
        dists = np.array([s.distance(X, Y) for s in self.shapes])

        minval = np.amin(dists, axis=0)
        maxval = np.amax(dists, axis=0)

        ret = minval

        # close = np.abs(minval - maxval) < 0.1

        # print(np.where(close))

        # ret[close] = np.average(dists, axis=0)[close]
        return ret

class Shape:
    def __init__(self):
        self.type = "shape"
        self.epsilon = 1e-5

    def distance(self, pos):
        raise ValueError()

class LineSegment(Shape):
    def __init__(self, p1, p2, width=None):
        super(LineSegment, self).__init__()
        if width is None:
            width = self.epsilon
        self.p1 = np.array(p1)
        self.p2 = np.array(p2)
        self.length = norm(self.p2 - self.p1)
        self.width = width

        l = (self.p2 - self.p1)
        # normalized vector along length
        self.l = l / self.length
        self.n = np.array([-l[1], l[0]])

    def distance(self, X, Y):

        mid = (self.p1 + self.p2) / 2

        deltaX = X - mid[0]
        deltaY = Y - mid[1]

        delta_l = (deltaX * self.l[0]) + (deltaY * self.l[1])
        delta_n = (deltaX * self.n[0]) + (deltaY * self.n[1])

        dist = np.zeros_like(X)

        # mask for several conditions
        within_endpoints = np.abs(delta_l) < self.length / 2
        within_n = np.abs(delta_n) <= self.width

        dist = np.sqrt((np.abs(delta_l) - self.length / 2)**2 + delta_n ** 2)

        # if between endpoints, snap to the normal distance
        dist[within_endpoints] = np.abs(delta_n[within_endpoints])
        dist[within_endpoints & within_n] = np.abs(
            delta_n[within_endpoints & within_n]) - self.width

        return dist

class Circle(Shape):
    def __init__(self, center, radius):
        super(Circle, self).__init__()

        self.center = np.array(center)
        self.radius = np.array(radius)

    def distance(self, X, Y):
        dX = (X - self.center[0])
        dY = (Y - self.center[1])

        dist = np.sqrt(dX * dX + dY * dY) - self.radius

        return dist


"""
Example of vectorizing for-loops to speed up computation time. Also attempts to
use Numba for further speed increases with autojit.

Uses the time.perf_counter() function for speed comparisons.

Change value of p to 6, 7, or 8 for best speed comparisons between the methods.
"""

import numpy as np
import numba as nb
import time

# Parameter
# ------------------------------------------------------------------------------

p = 7

# Loop Example
# ------------------------------------------------------------------------------

t1 = time.perf_counter()

A = []

for i in range(0, 10**p):
    A.append(i**3 + i**2)

t1end = time.perf_counter()

# Vectorized Array Example
# ------------------------------------------------------------------------------

t2 = time.perf_counter()

j = np.arange(0, 10**p)
B = j**3 + j**2

t2end = time.perf_counter()

# Vectorized Array Expanded Example
# ------------------------------------------------------------------------------

t3 = time.perf_counter()

k = np.arange(0, 10**p)
C = k*k*(k+1)

t3end = time.perf_counter()

# Vectorized Array Using Numba Example
# ------------------------------------------------------------------------------

# Note that Numba must "jit" the code during the first run, subsequent runs will
# be faster. The approach below includes the initial "jit-ing" of the code.
# Use %timeit in iPython to see the best of several runs of the function which
# should be faster than the vectorized array examples above.

t4 = time.perf_counter()

@nb.jit
def func():
    n = np.arange(0, 10**p)
    a = n*n*(n+1)
    return a

D = func()

t4end = time.perf_counter()

# Print Speed Comparisons
# ------------------------------------------------------------------------------

print('--- p =', p, ' ---')
print('{:.4f} s, for-loop'.format(t1end-t1))
print('{:.4f} s, vectorized array'.format(t2end-t2))
print('{:.4f} s, vectorized array expanded'.format(t3end-t3))
print('{:.4f} s, vectorized array with numba'.format(t4end-t4))


#ROT13 is a simple letter substitution cipher that replaces a letter with the letter 13 letters after it in the alphabet. ROT13 is an example of the Caesar cipher.
#
#Create a function that takes a string and returns the string ciphered with Rot13. If there are numbers or special characters included in the string, they should be returned as they are. Only letters from the latin/english alphabet should be shifted, like in the original Rot13 "implementation".
#
#Please note that using encode is considered cheating.

def rot13(message):
    alphabet = ['a','b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
    upper = False
    finalSentence = ""
    for charac in message:
        if charac.isupper():
            charac = charac.lower()
            upper = True
        try:
            index = alphabet.index(charac)
            index13after = (index + 13) % 26
            if upper:
                finalSentence = finalSentence + alphabet[index13after].upper()
                upper = False
            else:
                finalSentence = finalSentence + alphabet[index13after]
        except ValueError as ve:
            finalSentence = finalSentence + charac
    return finalSentence


# Distributed with a free-will license.
# Use it any way you want, profit or free, provided it fits in the licenses of its associated works.
# ADS7830
# This code is designed to work with the ADS7830_I2CADC_I2CS I2C Mini Module available from ControlEverything.com.
# https://www.controleverything.com/content/Analog-Digital-Converters?sku=ADS7830_I2CADC#tabs-0-product_tabset-2

from gpiozero import PWMLED
import smbus
from time import sleep
import math
# Get I2C bus
bus = smbus.SMBus(1)

red = PWMLED(17)
green = PWMLED(27)
blue = PWMLED(22)

while True:
	# ADS7830 address, 0x4b
	# Send command byte
	#		0x8C	Single ended inputs, Channel-0
	bus.write_byte(0x4b, 0x8C)

	sleep(0.1)

	# ADS7830 address, 0x48(72)
	# Read data back, 1 byte
	data = bus.read_byte(0x4b)

	# Output data to screen
	print ("Digital value of analog input :", data)

	degrees = (data / 255) * 359
	print(degrees)

	red_pwm = (math.sin(degrees) / 2) + 0.5
	blue_pwm = (math.sin(degrees + 120) / 2) + 0.5
	green_pwm = (math.sin(degrees + 240) / 2) + 0.5
	print(red_pwm, blue_pwm, green_pwm)

	red.value = red_pwm
	sleep(0.9)
	green.value = green_pwm
	sleep(0.9)
	blue.value = blue_pwm

#write_byte(address, command)

#command - 1 0 0 0 1 1 0 0 -> 0x8C


from typing import List, Optional, Union

import numpy as np
import pandas as pd
from pandas.api.types import is_datetime64_any_dtype as is_datetime
from sklearn.utils.validation import check_is_fitted

from feature_engine._docstrings.fit_attributes import (
    _feature_names_in_docstring,
    _n_features_in_docstring,
)
from feature_engine._docstrings.init_parameters.all_trasnformers import (
    _missing_values_docstring,
)
from feature_engine._docstrings.methods import (
    _fit_not_learn_docstring,
    _fit_transform_docstring,
    _transform_creation_docstring,
)
from feature_engine._docstrings.substitute import Substitution
from feature_engine.creation.base_creation import BaseCreation
from feature_engine.dataframe_checks import (
    _check_contains_na,
    _check_X_matches_training_df,
    check_X,
)
from feature_engine.variable_handling import find_or_check_datetime_variables
from feature_engine.variable_handling._init_parameter_checks import (
    _check_init_parameter_variables,
)

_example = """
    >>> import pandas as pd
    >>> from feature_engine.datetime import DatetimeSubtraction
    >>> X = pd.DataFrame({
    >>>     "date1": ["2022-09-18", "2022-10-27", "2022-12-24"],
    >>>     "date2": ["2022-08-18", "2022-08-27", "2022-06-24"]})
    >>> dtf = DatetimeSubtraction(variables=["date1"], reference=["date2"])
    >>> dtf.fit(X)
    >>> dtf.transform(X)
            date1       date2  date1_sub_date2
    0  2022-09-18  2022-08-18             31.0
    1  2022-10-27  2022-08-27             61.0
    2  2022-12-24  2022-06-24            183.0
        """.rstrip()

@Substitution(
    missing_values=_missing_values_docstring,
    feature_names_in_=_feature_names_in_docstring,
    n_features_in_=_n_features_in_docstring,
    fit=_fit_not_learn_docstring,
    transform=_transform_creation_docstring,
    fit_transform=_fit_transform_docstring,
    example=_example,
)
class DatetimeSubtraction(BaseCreation):
    """
    DatetimeSubtraction() applies datetime subtraction between a group of datetime
    variables and one or more datetime features, adding the resulting variables to the
    dataframe.

    DatetimeSubtraction() works with variables cast as datetime or object. It subtracts
    the variables listed in the parameter `reference` from those listed in the
    parameter `variables`.

    More details in the :ref:`User Guide <datetime_subtraction>`.

    Parameters
    ----------
    variables: list
        The list of datetime variables that the reference variables will be subtracted
        from (left side of the subtraction operation).

    reference: list
        The list of datetime reference variables that will be subtracted from
        `variables` (right side of the subtraction operation).

    new_variables_names: list, default=None
        Names of the new variables. You have the option to pass a list with the names
        you'd like to assing to the new variables. If `None`, the transformer will
        assign arbitrary names.

    output_unit: string, default='D'
        The string representation of the output unit of the datetime differences.
        The default is `D` for day. This parameter is passed to `numpy.timedelta64`.
        Other possible values are  `Y` for year, `M` for month,  `W` for week,
        `h` for hour, `m` for minute, `s` for second, `ms` for millisecond,
        `us` or `μs` for microsecond, `ns` for nanosecond, `ps` for picosecond,
        `fs` for femtosecond and `as` for attosecond.

    {missing_values}

    drop_original: bool, default="False"
        If `True`, the variables listed in `variables` and `reference` will be dropped
        from the dataframe after the computation of the new features.

    dayfirst: bool, default="False"
        Specify a date parse order if arg is str or is list-like. If True, parses
        dates with the day first, e.g. 10/11/12 is parsed as 2012-11-10. Same as in
        `pandas.to_datetime`.

    yearfirst: bool, default="False"
        Specify a date parse order if arg is str or is list-like.
        Same as in `pandas.to_datetime`.

        - If True parses dates with the year first, e.g. 10/11/12 is parsed as
          2010-11-12.
        - If both dayfirst and yearfirst are True, yearfirst is preceded.

    utc: bool, default=None
        Return UTC DatetimeIndex if True (converting any tz-aware datetime.datetime
        objects as well). Same as in `pandas.to_datetime`.

    format: str, default None
        The strftime to parse time, e.g. "%d/%m/%Y". Check pandas `to_datetime()` for
        more information on choices. If you have variables with different formats pass
        “mixed”, to infer the format for each element individually. This is risky,
        and you should probably use it along with dayfirst, according to pandas'
        documentation.

    Attributes
    ----------
    variables_:
        The list with datetime variables from which the variables in `reference` will
        be substracted. It is created after the transformer corroborates that the
        variables in `variables` are, or can be parsed to datetime.

    reference_:
        The list with the datetime variables that will be subtracted from `variables_`.
        It is created after the transformer corroborates that the variables in
        `reference` are, or can be parsed to datetime.

    {feature_names_in_}

    {n_features_in_}

    Methods
    -------
    {fit}

    {fit_transform}

    {transform}

    Examples
    --------

    {example}
    """

    def __init__(
        self,
        variables: Union[None, int, str, List[Union[str, int]]],
        reference: Union[None, int, str, List[Union[str, int]]],
        new_variables_names: Union[None, List[str], str] = None,
        output_unit: str = "D",
        missing_values: str = "ignore",
        drop_original: bool = False,
        dayfirst: bool = False,
        yearfirst: bool = False,
        utc: Union[None, bool] = None,
        format: Union[None, str] = None,
    ) -> None:

        valid_output_units = {
            "D",
            "Y",
            "M",
            "W",
            "h",
            "m",
            "s",
            "ms",
            "us",
            "μs",
            "ns",
            "ps",
            "fs",
            "as",
        }

        if not isinstance(output_unit, str) or output_unit not in valid_output_units:
            raise ValueError(
                f"output_unit accepts the following values: "
                f"{valid_output_units}. Got {output_unit} instead."
            )

        if new_variables_names is not None:
            if (
                not isinstance(new_variables_names, list)
                or not all(isinstance(var, str) for var in new_variables_names)
                or len(set(new_variables_names)) != len(new_variables_names)
            ):
                raise ValueError(
                    "new_variable_names should be None or a list of unique strings. "
                    f"Got {new_variables_names} instead."
                )

        super().__init__(missing_values, drop_original)
        self.variables = _check_init_parameter_variables(variables)
        self.reference = _check_init_parameter_variables(reference)
        self.new_variables_names = new_variables_names
        self.output_unit = output_unit
        self.dayfirst = dayfirst
        self.yearfirst = yearfirst
        self.utc = utc
        self.format = format

    def fit(self, X: pd.DataFrame, y: Optional[pd.Series] = None):
        """
        This transformer does not learn any parameter.

        Parameters
        ----------
        X: pandas dataframe of shape = [n_samples, n_features]
            The training input samples. Can be the entire dataframe, not just the
            variables to transform.

        y: pandas Series, or np.array. Default=None.
            It is not needed in this transformer. You can pass y or None.
        """
        # Common checks and attributes
        X = check_X(X)

        # check variables are datetime
        self.reference_ = find_or_check_datetime_variables(X, self.reference)
        self.variables_ = find_or_check_datetime_variables(X, self.variables)

        if self.new_variables_names is not None:
            if len(self.new_variables_names) != len(self.variables_) * len(
                self.reference_
            ):
                raise ValueError(
                    f"{len(self.variables_) * len(self.reference_)} new variables will "
                    f"be created but only {len(self.new_variables_names)} new variable "
                    f"names were provided. Please check the variables list and try "
                    f"again."
                )

        # check if dataset contains na
        if self.missing_values == "raise":
            _check_contains_na(X, self.variables_ + self.reference_)

        # save input features
        self.feature_names_in_ = X.columns.tolist()

        # save train set shape
        self.n_features_in_ = X.shape[1]

        return self

    def transform(self, X: pd.DataFrame) -> pd.DataFrame:
        """
        Add new features.

        Parameters
        ----------
        X: pandas dataframe of shape = [n_samples, n_features]
            The data to transform.

        Returns
        -------
        X_new: Pandas dataframe
            The input dataframe plus the new variables.
        """

        # Check method fit has been called
        check_is_fitted(self)

        # check that input is a dataframe
        X = check_X(X)

        # Check if input data contains same number of columns as dataframe used to fit.
        _check_X_matches_training_df(X, self.n_features_in_)

        if self.missing_values == "raise":
            _check_contains_na(X, self.variables_ + self.reference_)

        # reorder variables to match train set
        X = X[self.feature_names_in_]

        X_dt = self._to_datetime(X)

        new_features = self._sub(X_dt)

        X = pd.concat([X, new_features], axis=1)

        if self.drop_original:
            X = X.drop(
                columns=set(self.variables_ + self.reference_),
            )

        return X

    def _to_datetime(self, X: pd.DataFrame):
        """covert variables to datetime."""
        # convert datetime variables
        datetime_df = pd.concat(
            [
                pd.to_datetime(
                    X[variable],
                    dayfirst=self.dayfirst,
                    yearfirst=self.yearfirst,
                    utc=self.utc,
                    format=self.format,
                )
                for variable in set(self.variables_ + self.reference_)
            ],
            axis=1,
        )

        non_dt_columns = datetime_df.columns[~datetime_df.apply(is_datetime)].tolist()

        if non_dt_columns:
            raise ValueError(
                "ValueError: variable(s) "
                + (len(non_dt_columns) * "{} ").format(*non_dt_columns)
                + "could not be converted to datetime. Try setting utc=True"
            )
        return datetime_df

    def _sub(self, dt_df: pd.DataFrame):
        """make datetime subtraction"""
        new_df = pd.DataFrame()
        for reference in self.reference_:
            new_varnames = [f"{var}_sub_{reference}" for var in self.variables_]
            new_df[new_varnames] = (
                dt_df[self.variables_]
                .sub(dt_df[reference], axis=0)
                .div(np.timedelta64(1, self.output_unit).astype("timedelta64[ns]"))
            )

        if self.new_variables_names is not None:
            new_df.columns = self.new_variables_names

        return new_df

    def _get_new_features_name(self) -> List:
        """Return names of the created features."""
        if self.new_variables_names is not None:
            feature_names = self.new_variables_names
        else:
            feature_names = [
                f"{var}_sub_{reference}"
                for reference in self.reference_
                for var in self.variables_
            ]
        return feature_names


import matplotlib
matplotlib.use('Agg')
import pandas as pd

import seaborn as sns
import matplotlib.pyplot as plt

FIGURE_FOLDER = 'figures/'
EXTENSION = '.png'

def features_values():
    raw_data = pd.read_csv('models/seirhcd/2020_05_10/features.csv')
    raw_data['Date'] = pd.to_datetime(raw_data['Date'])

    return raw_data

FEATURES_VALUES = features_values()

def color_palette(data, hue):
    n_colors = 1 if hue == None else len(data[hue].unique())
    return sns.color_palette("cubehelix", n_colors=n_colors)

def lineplot(data, name, x, y, y_label, x_label='', hue=None, y_lim=None, fig_size=(6,4), legend_pos='best', style=None, show_error=False, **kwargs):
    fig = plt.figure(figsize=fig_size)
    sns.set(style="white", color_codes=True, font_scale=1.5)

    palette = color_palette(data, hue)

    g = sns.lineplot(x=x, y=y, hue=hue, data=data, palette=palette, legend="full", style=style, **kwargs)

    fig.tight_layout()

    if not legend_pos:
        g.legend_.remove()
    elif hue:
        handles, labels = g.get_legend_handles_labels()
        plt.legend(loc='best', prop={'size': 15}, handles=handles[1:], labels=labels[1:])

    plt.ylabel(y_label, fontsize=15)
    plt.xlabel(x_label, fontsize=15)
    plt.xticks(rotation=45)
    plt.ticklabel_format(style='plain', axis='y',useOffset=False)

    if y_lim != None and len(y_lim) == 2:
        plt.ylim(y_lim)

    if show_error:
        error_band(data, x, hue)

    plt.savefig('figures/' + name + EXTENSION, dpi=300, bbox_inches='tight')
    plt.close('all')

def error_band(data, x, hue):
    ax = plt.gca()

    valid_labels = data[hue].unique()

    for line in ax.lines:
        if not line.get_label() in valid_labels:
            continue

        x_values = data.loc[data[hue] == line.get_label()][x].values
        y_min = data.loc[data[hue] == line.get_label()]['Min'].values
        y_max = data.loc[data[hue] == line.get_label()]['Max'].values

        ax.fill_between(x_values, y_min, y_max, color=line.get_color(), alpha=0.2, linewidth=0.0)


'''

menu class

GGJ GMU 2014, Candy Herder / Crushing Candy into Jam Team
Nathan McClain
Brendon Fuhs
David Masad

'''
from pygame import *
import sys

class Menu(object):
    def __init__(self, screen, text = "paused", on_key=None):
        '''
        Create a new menu.

        Args:
            screen: Game main screen object to draw on
            text: Text to display; default is "paused"
            on_key: Optional function to call when any key is pressed while in
                    the menu. If None, just exits the menu
        '''

        self.screen = screen
        self.on_key = on_key
        if type(text) is str:
            self.text = [text]
        else:
            self.text = text

        self.font = font.SysFont("monospace", 24)

    def menu_loop(self):
        self.screen.blit(self.display(), (300, 100))
        display.flip()

        while True:
            for ev in event.get():
                if ev.type == QUIT:
                    sys.exit(0)
                if ev.type == KEYDOWN:
                    if self.on_key == None:
                        return
                    else:
                        self.on_key()

    def display(self):
        base_img = Surface((600,600))
        for i, text in enumerate(self.text):
            menu_text = self.font.render(text, 1, (255,255,0))
            base_img.blit(menu_text, (100, 100 + 20 * i))
        return base_img

class SplashScreen(Menu):
    '''
    Splash screen; like a menu, but displays a graphic instead of text
    '''

    def __init__(self, screen, image_path, on_key=None):
        self.screen = screen
        self.on_key = on_key
        self.image = image.load(image_path).convert_alpha()
        self.image = transform.smoothscale(self.image, (1200,800))

    def display(self):
        return self.image

    def menu_loop(self):
        self.screen.blit(self.display(), (0, 0))
        display.flip()

        while True:
            for ev in event.get():
                if ev.type == QUIT:
                    sys.exit(0)
                if ev.type == KEYDOWN:
                    if self.on_key == None:
                        return
                    else:
                        self.on_key()


# This file was adapted from https://github.com/lukecavabarrett/pna

from __future__ import division
from __future__ import print_function

import argparse
import os
import sys
import time
from types import SimpleNamespace
import wandb
import numpy as np
import torch
import torch.optim as optim
import numpy.random as npr
from torch_geometric.data import DataLoader
from models.model_multi_task import SMP
from multi_task_utils.util import load_dataset, to_torch_geom, specific_loss_torch_geom

log_loss_tasks = ["log_shortest_path", "log_eccentricity", "log_laplacian",
                  "log_connected", "log_diameter", "log_radius"]

def build_arg_parser():
    """
    :return:    argparse.ArgumentParser() filled with the standard arguments for a training session.
                    Might need to be enhanced for some models.
    """
    parser = argparse.ArgumentParser()

    parser.add_argument('--data', type=str, default='./data/multitask_dataset.pkl', help='Data path.')
    parser.add_argument('--gpu', type=int, help='Id of the GPU')
    parser.add_argument('--no-cuda', action='store_true', default=False, help='Disables CUDA training.')
    parser.add_argument('--only_nodes', action='store_true', default=False, help='Evaluate only nodes labels.')
    parser.add_argument('--only_graph', action='store_true', default=False, help='Evaluate only graph labels.')
    parser.add_argument('--seed', type=int, default=42, help='Random seed.')
    parser.add_argument('--epochs', type=int, default=3000, help='Number of epochs to train.')
    parser.add_argument('--lr', type=float, default=0.001, help='Initial learning rate.')
    parser.add_argument('--weight_decay', type=float, default=1e-6, help='Weight decay (L2 loss on parameters).')
    parser.add_argument('--patience', type=int, default=1000, help='Patience')
    parser.add_argument('--loss', type=str, default='mse', help='Loss function to use.')
    parser.add_argument('--print_every', type=int, default=5, help='Print training results every')
    return parser

def execute_train(gnn_args, args):
    """
    :param gnn_args: the description of the model to be trained (expressed as arguments for GNN.__init__)
    :param args: the parameters of the training session
    """
    if not os.path.isdir('./saved_models'):
        os.mkdir('./saved_models')
    if args.name is not None:
        save_dir = f'./saved_models/{args.name}'
    else:
        save_dir = f'./saved_models/'
    if args.name is not None and not os.path.isdir(save_dir):
        os.mkdir(save_dir)

    use_cuda = args.gpu is not None and torch.cuda.is_available() and not args.no_cuda
    if use_cuda:
        device = torch.device("cuda:" + str(args.gpu))
        torch.cuda.set_device(args.gpu)
        os.environ['CUDA_VISIBLE_DEVICES'] = str(args.gpu)
    else:
        device = "cpu"
    args.device = device
    args.kwargs = {'num_workers': 1, 'pin_memory': True} if use_cuda else {}
    print('Using device:', device)

    np.random.seed(args.seed)
    torch.manual_seed(args.seed)
    if use_cuda:
        torch.cuda.manual_seed(args.seed)

    # load data
    adj, features, node_labels, graph_labels = load_dataset(args.data, args.loss, args.only_nodes, args.only_graph,
                                                            print_baseline=True)
    print("Processing torch geometric data")
    graphs = to_torch_geom(adj, features, node_labels, graph_labels, device, args.debug)
    train_loaders = [DataLoader(given_size, args.batch_size, shuffle=True) for given_size in graphs['train']]
    batch_sizes = {'train': args.batch_size, 'val': 128, 'test': 256}
    val_loaders = [DataLoader(given_size, 128) for given_size in graphs['val']]
    test_loaders = [DataLoader(given_size, 256) for given_size in graphs['test']]
    print("Data loaders created")
    # model and optimizer
    gnn_args = SimpleNamespace(**gnn_args)

    gnn_args.num_input_features = features['train'][0].shape[2]
    gnn_args.nodes_out = 3
    gnn_args.graph_out = 3
    model = SMP(**vars(gnn_args)).to(device)
    optimizer = optim.Adam(model.parameters(), lr=args.lr, weight_decay=args.weight_decay)
    scheduler = torch.optim.lr_scheduler.StepLR(optimizer,
                                                step_size=50,
                                                gamma=0.92)

    pytorch_total_params = sum(p.numel() for p in model.parameters() if p.requires_grad)
    print("Total params", pytorch_total_params)

    if args.load_from_epoch != -1:
        checkpoint = torch.load(os.path.join(save_dir, f'{args.load_from_epoch}.pkl'))
        model.load_state_dict(checkpoint['model_state_dict'])
        optimizer.load_state_dict(checkpoint['optimizer_state_dict'])
        epoch = checkpoint['epoch']
    else:
        epoch = 0

    def train(epoch):
        """ Execute a single epoch of the training loop
        epoch (int): the number of the epoch being performed (0-indexed)."""
        t = time.time()

        # 1. Train
        nan_counts = 0
        model.train()
        total_train_loss_per_task = 0
        npr.shuffle(train_loaders)
        for i, loader in enumerate(train_loaders):
            for j, data in enumerate(loader):
                # Optimization
                optimizer.zero_grad()
                output = model(data.to(device))
                train_loss_per_task = specific_loss_torch_geom(output, (data.pos, data.y), data.batch, args.batch_size)
                loss_train = torch.mean(train_loss_per_task)
                if torch.isnan(loss_train):
                    print(f"Warning: loss was nan at epoch {epoch} and batch {i}{j}.")
                    nan_counts += 1
                    if nan_counts < 20:
                        continue
                    else:
                        raise ValueError(f"Too many NaNs. Stopping training at epoch {epoch}. Best epoch: {best_epoch}")
                loss_train.backward()
                torch.nn.utils.clip_grad_norm_(model.parameters(), args.clip)
                optimizer.step()
                # Compute metrics
                total_train_loss_per_task += train_loss_per_task / len(loader)
        total_train_loss_per_task /= len(train_loaders)
        train_log_loss_per_task = torch.log10(total_train_loss_per_task).data.cpu().numpy()
        train_loss = torch.mean(total_train_loss_per_task).data.item()

        # validation epoch
        model.eval()
        val_loss_per_task = 0
        for loader in val_loaders:
            for i, data in enumerate(loader):
                if i > 0:
                    print("Warning: not all the batch was loaded at once. It will lead to incorrect results.")
                output = model(data.to(device))
                batch_loss_per_task = specific_loss_torch_geom(output, (data.pos, data.y), data.batch, batch_sizes['val'])
                val_loss_per_task += batch_loss_per_task.detach() / len(val_loaders)

        val_log_loss_per_task = torch.log10(val_loss_per_task).data.cpu().numpy()
        val_log_loss = torch.mean(val_loss_per_task).item()

        if epoch % args.print_every == 0:
            print('Epoch: {:04d}'.format(epoch + 1),
                  'loss.train: {:.4f}'.format(train_loss),
                  'log.loss.val: {:.4f}'.format(val_log_loss),
                  'time: {:.4f}s'.format(time.time() - t))
            print(f'train loss per task (log10 scale): {train_log_loss_per_task}')
            print(f'val loss per task (log10 scale): {val_log_loss_per_task}')
            sys.stdout.flush()
            if args.wandb:
                wandb_dict = {"Epoch": epoch, "Duration": time.time() - t, "Train loss": train_loss,
                              "Val log loss": val_log_loss}
                for loss, tr, val in zip(log_loss_tasks, train_log_loss_per_task, val_log_loss_per_task):
                    wandb_dict[loss + 'tr'] = tr
                    wandb_dict[loss + 'val'] = val
                wandb.log(wandb_dict)

        return val_log_loss

    def compute_test():
        """
        Evaluate the current model on all the sets of the dataset, printing results.
        This procedure is destructive on datasets.
        """
        model.eval()
        sets = list(features.keys())
        for dset, loaders in zip(sets, [train_loaders, val_loaders, test_loaders]):
            final_specific_loss = 0
            final_total_loss = 0
            for loader in loaders:
                loader_total_loss = 0
                loader_specific_loss = 0
                for data in loader:
                    output = model(data.to(device))
                    specific_loss = specific_loss_torch_geom(output, (data.pos, data.y),
                                                             data.batch, batch_sizes[dset]).detach()
                    loader_specific_loss += specific_loss
                    loader_total_loss += torch.mean(specific_loss)
                # Average the loss over each loader
                loader_specific_loss /= len(loader)
                loader_total_loss /= len(loader)
                # Average the loss over the different loaders
                final_specific_loss += loader_specific_loss / len(loaders)
                final_total_loss += loader_total_loss / len(loaders)
                del output, loader_specific_loss

            print("Test set results ", dset, ": loss= {:.4f}".format(final_total_loss))
            print(dset, ": ", final_specific_loss)
            print("Results in log scale", np.log10(final_specific_loss.detach().cpu()),
                  np.log10(final_total_loss.detach().cpu().numpy()))
        if args.wandb:
            wandb.run.summary["test results"] = np.log10(final_specific_loss.detach().cpu())
        # free unnecessary data

        final_specific_numpy = np.log10(final_specific_loss.detach().cpu())
        del final_total_loss, final_specific_loss
        torch.cuda.empty_cache()
        return final_specific_numpy

    sys.stdout.flush()
    # Train model
    t_total = time.time()
    loss_values = []
    bad_counter = 0
    best = args.epochs + 1
    best_epoch = -1

    sys.stdout.flush()

    while epoch < args.epochs:
        epoch += 1

        loss_values.append(train(epoch))
        scheduler.step()
        if epoch % 100 == 0:
            print("Results on the test set:")
            results_test = compute_test()
            print('Test set results', results_test)
            print(f"Saving checkpoint at epoch {epoch}")
            torch.save({
                'epoch': epoch,
                'model_state_dict': model.state_dict(),
                'optimizer_state_dict': optimizer.state_dict(),
            }, os.path.join(save_dir, f'{epoch}.pkl'))

        if loss_values[-1] < best:
            # save current model
            if loss_values[-1] < best:
                print(f"New best validation error at epoch {epoch}")
            else:
                print(f"Saving checkpoint at epoch {epoch}")
            torch.save({
                'epoch': epoch,
                'model_state_dict': model.state_dict(),
                'optimizer_state_dict': optimizer.state_dict(),
                }, os.path.join(save_dir, f'{epoch}.pkl'))
            # remove previous model
            if best_epoch >= 0:
                f_name = os.path.join(save_dir, f'{best_epoch}.pkl')
                if os.path.isfile(f_name):
                    os.remove(f_name)
            # update training variables
            best = loss_values[-1]
            best_epoch = epoch
            bad_counter = 0
        else:
            bad_counter += 1

        if bad_counter == args.patience:
            print('Early stop at epoch {} (no improvement in last {} epochs)'.format(epoch + 1, bad_counter))
            break

    print("Optimization Finished!")
    print("Total time elapsed: {:.4f}s".format(time.time() - t_total))

    # Restore best model
    print('Loading {}th epoch'.format(best_epoch + 1))
    checkpoint = torch.load(os.path.join(save_dir, f'{best_epoch}.pkl'))
    model.load_state_dict(checkpoint['model_state_dict'])

    # Testing
    print("Results on the test set:")
    results_test = compute_test()
    print('Test set results', results_test)


# 1. 使用 knn 拟合 digits, 绘制 n_neighbors = 1-31 的 train_score 以及 test_score 的 cross_validation curve.
import joblib as jb
from sklearn.datasets import load_digits
from sklearn import metrics
model = jb.load('knnb3')
digits_data = load_digits()
X = digits_data.data
y = digits_data.target
model.fit(X,y)
y_pred = model.predict(X)
score = metrics.accuracy_score(y,y_pred)
print(score)


# copy the matrix first
# check maximum length of side of square
# find the maximum length and return the area as answer
class Solution:
    def maximalSquare(self, matrix: List[List[str]]) -> int:
        if not matrix:
            return 0
        m , n = len(matrix), len(matrix[0])
        dp = [[ 0 if matrix[i][j] == '0' else 1 for j in range(0, n)] for i in range(0, m)]

        for i in range(1, m):
            for j in range(1, n):
                if matrix[i][j] == '1':
                    dp[i][j] = min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) + 1
                else:
                    dp[i][j] = 0

        res = max(max(row) for row in dp)
        return res ** 2

6_dynamic programming/medium/221. Maximal Square.py


import numpy as np
from scipy.stats import norm

def synthesize_crosscurve(sample_nums=2000, z_list=None):
    u = lambda z: np.pi*(0.6+1.8*norm.cdf(z))
    f1 = lambda u: (1./np.sqrt(2))*(np.cos(u)/((np.sin(u))**2 + 1.))
    f2 = lambda u: (np.sqrt(2)) * (np.cos(u) * np.sin(u))/((np.sin(u))**2 + 1.)

    if z_list is None: z_list = np.random.normal(0,1,sample_nums)
    assert len(z_list) == sample_nums, "number of z_list should equal to sample_nums"

    u_list = u(z_list)
    f1_list = f1(u_list) + np.random.normal(0, np.sqrt(0.02), sample_nums)
    f2_list = f2(u_list) + np.random.normal(0, np.sqrt(0.02), sample_nums)
    return np.vstack([f1_list, f2_list]).T

def synthesize_threeclusters(sample_nums=2000, z_list=None):
    u = lambda z: (2*np.pi)/(1.+np.exp(-0.5*np.pi*z))
    t = lambda u: 2*np.tanh(10*u - 20*np.floor(u/2.) -10.) + 4.*np.floor(u/2.) + 2
    f1 = lambda t: np.cos(t)
    f2 = lambda t: np.sin(t)

    if z_list is None: z_list = np.random.normal(0,1,sample_nums)
    assert len(z_list) == sample_nums, "number of z_list should equal to sample_nums"

    u_list = u(z_list)
    t_list = t(u_list)
    f1_list = f1(t_list) + np.random.normal(0, np.sqrt(0.2), sample_nums)
    f2_list = f2(t_list) + np.random.normal(0, np.sqrt(0.2), sample_nums)
    return np.vstack([f1_list, f2_list]).T


from dataclasses import dataclass
from typing import *
import numpy as np
import itertools
import re
import time

import fire

@dataclass
class Point:
    x: int
    y: int

@dataclass
class Line:
    l: Point
    r: Point

def main(
        #infile: str='test_input.txt',
        infile: str = 'input.txt',
):
    print('hi!')

    lines = []
    with open(infile, 'r') as f:
        for l in f.readlines():
            l, r = l.split('->')
            p1 = l.strip().split(',')
            p1 = Point(int(p1[0]), int(p1[1]))
            p2 = r.strip().split(',')
            p2 = Point(int(p2[0]), int(p2[1]))
            lines.append(Line(p1, p2))

    # print(lines)

    max_x = max(max(line.l.x, line.r.x) for line in lines) + 1
    max_y = max(max(line.l.y, line.r.y) for line in lines) + 1

    print(max_x, max_y)
    arr = np.zeros((max_y, max_x), dtype=np.int32)
    t0 = time.time()
    for line in lines:
        if line.l.x == line.r.x:
            y0 = min(line.l.y, line.r.y)
            y1 = max(line.l.y, line.r.y)
            for j in range((y1-y0)+1):
                arr[y0+j, line.l.x] += 1
        elif line.l.y == line.r.y:
            x0 = min(line.l.x, line.r.x)
            x1 = max(line.l.x, line.r.x)
            for j in range((x1-x0)+1):
                arr[line.l.y, x0+j] += 1
        else:
            # Diagonal
            x0, y0 = line.l.x, line.l.y
            x1, y1 = line.r.x, line.r.y

            if x0 < x1:
                dx = 1
            else:
                dx = -1
            if y0 < y1:
                dy = 1
            else:
                dy = -1

            for j in range(abs(x1-x0)+1):
                arr[y0+j*dy, x0+j*dx] += 1

    print(f'1: {(arr>1).sum()}', time.time() - t0, 's')

if __name__ == '__main__':
    fire.Fire(main)


# -*- coding: utf-8 -*-
# UTF-8 encoding when using korean
N = int(raw_input())
answer = 0
for number in range(N):
	num = list(str(number))
	for idx in num:
		if idx == '3' or idx == '6' or idx == '9':
			answer += 1
print(answer)


import sqlite3
import csv
import os.path

#EXAMPLE OF HOW TO USE THIS CLASS#
# import compawdreDB as db
#
#
# d = db.DB('compawdre.csv')
#
# conn = d.get_connection()
# select_all = "SELECT * FROM breed"
# rows = conn.execute(select_all).fetchall()
#
# # Output to the console screen
# for r in rows:
#     print(r)

class DB:
    def __init__(self, file):

        self.connection = None

        if not os.path.exists(file):
            raise Exception("File does not exist. Please enter a valid filename")

        with open(file, newline='') as f:
            reader = csv.reader(f)
            data = list(reader)

            a = data[0]
            b = ['id','name','image_url','hypoallergenic','breed_restriction','weight','energy','trainable','territorial','age']

            if not a == b:
                raise Exception('''Headers do not match.
                Headers should be
                id,name,image_url,hypoallergenic,breed_restriction,weight,energy,
                trainable,territorial,age''')
            elif len(data[1]) != 10:
                raise Exception("Innacurate number of columns for one or more records")

        file = open(file)

        contents = csv.reader(file)
        print("CSV loaded")

        conn = sqlite3.connect("compawdre.db")
        print("Database connected.")

        cursor = conn.cursor()

        # Create a table in the database.
        print("\nCreating a table in the ComPawdre database")
        cursor.execute('''CREATE TABLE breed
                 (ID            INT      PRIMARY KEY     NOT NULL,
                 NAME           TEXT                     NOT NULL,
                 IMAGE_URL      TEXT                     NOT NULL,
                 HYPOALLERGENIC BOOLEAN                  NOT NULL,
                 BREED_RESTRICTION BOOLEAN               NOT NULL,
                 WEIGHT         TEXT                     NOT NULL,
                 ENERGY         INT                      NOT NULL,
                 TRAINABLE      INT                      NOT NULL,
                 TERRITORIAL    INT                      NOT NULL,
                 AGE            TEXT                     NOT NULL);''')
        print("\nTable created.")

        insert_records = "INSERT INTO breed (ID,NAME,IMAGE_URL,HYPOALLERGENIC,BREED_RESTRICTION,WEIGHT,ENERGY,TRAINABLE,TERRITORIAL,AGE) \
              VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"

        print("\nAdding some records to the table")
        cursor.executemany(insert_records, contents)

        select_all = "SELECT * FROM breed"
        rows = cursor.execute(select_all).fetchall()

        # Output to the console screen
        for r in rows:
            print(r)

        conn.commit()

        print("Operations done successfully!")
        conn.close()

    def get_connection(self):
        if not self.connection:
            self.connection = sqlite3.connect("compawdre.db")
        return self.connection


custom_imports = dict(imports=['custom_modules'], allow_failed_imports=False)
# model settings
model = dict(
    type='Recognizer3D',
    backbone=dict(type='I3D',
                  init_cfg=dict(type='Pretrained',
                                checkpoint='https://github.com/hassony2/kinetics_i3d_pytorch/raw/master/model/model_flow.pth'),
                  modality='flow'),
    data_preprocessor=dict(
        type='ActionDataPreprocessor',
        mean=[123.675, 116.28, 103.53],
        std=[58.395, 57.12, 57.375],
        format_shape='NCHW'))

# dataset settings
dataset_type = 'RawframeDataset'
data_root_val = 'my_data/thumos14/rawframes/val'
ann_file_val = 'my_data/thumos14/annotations/mmaction/thumos14_val_flow_list.txt'

test_pipeline = [
    dict(type='UntrimmedSampleFrames', clip_len=16, frame_interval=1, clip_interval=4),
    dict(type='RawFrameDecode', io_backend='disk'),
    dict(type='Resize', scale=(224, 224), keep_ratio=False),
    # dict(type='Resize', scale=(-1, 256)),
    # dict(type='CenterCrop', crop_size=256),
    dict(type='FormatShape', input_format='NCHW'),
    dict(type='PackActionInputs')
]

test_dataloader = dict(
    batch_size=1,
    num_workers=8,
    persistent_workers=True,
    sampler=dict(type='DefaultSampler', shuffle=False),
    dataset=dict(
        type=dataset_type,
        ann_file=ann_file_val,
        data_prefix=dict(img=data_root_val),
        pipeline=test_pipeline,
        test_mode=True))

# default settings
test_cfg = dict(type='TestLoop')
default_scope = 'mmaction'

default_hooks = dict(
    runtime_info=dict(type='RuntimeInfoHook'),
    timer=dict(type='IterTimerHook'),
    logger=dict(type='LoggerHook', interval=20, ignore_last=False),
    param_scheduler=dict(type='ParamSchedulerHook'),
    checkpoint=dict(type='CheckpointHook', interval=1, save_best='auto'),
    sampler_seed=dict(type='DistSamplerSeedHook'),
    sync_buffers=dict(type='SyncBuffersHook'))

env_cfg = dict(
    cudnn_benchmark=False,
    mp_cfg=dict(mp_start_method='fork', opencv_num_threads=0),
    dist_cfg=dict(backend='nccl'))

log_processor = dict(type='LogProcessor', window_size=20, by_epoch=True)

vis_backends = [dict(type='LocalVisBackend')]
visualizer = dict(type='ActionVisualizer', vis_backends=vis_backends)

log_level = 'INFO'
load_from = None
resume = False
# PYTHONPATH='.':$PYTHONPATH mim run mmaction2 clip_feature_extraction
# configs/feature_extraction/new_i3d_16x1x4_k400_thumos14_flow.py checkpoints/r3d_sony/model_flow_backbone-prefix.pth flow_clip_feat --long-video-mode


import bpy
from . import preferences as P
from enum import Enum

LM_ASSET_COLLECTION = "Assets_Collection"
LM_COMPATIBLE_MESH_FORMAT = {".fbx":(bpy.ops.import_scene.fbx, {'filter_glob':'*.fbx;', 'axis_forward':'-Z', 'axis_up':'Y'}),
								".obj":(bpy.ops.import_scene.obj, {'filter_glob':'*.obj;*.mtl', 'axis_forward':'-Z', 'axis_up':'Y'})}
LM_COMPATIBLE_EXPORT_FORMAT = ['MESH']
LM_COMPATIBLE_TEXTURE_FORMAT = {".png":(),
								".tga":(),
								".psd":()}

LM_OUTPUT_EXTENSION = {'BMP':'.bmp',
						'IRIS':'.iris',
						'PNG':'.png',
						'JPEG':'.jpg',
						'JPEG2000':'.jpg',
						'TARGA':'.tga',
						'TARGA_RAW':'.tga',
						'CINEON':'.cin',
						'DPX':'.dpx',
						'OPEN_EXR_MULTILAYER':'.exr',
						'OPEN_EXR':'.exr',
						'HDR':'.exr',
						'TIFF':'.tif'}

LM_FINAL_COMPOSITE_FOLDER_NAME = '00_Final_Composite'
LM_FINAL_COMPOSITE_SUFFIX = '_final_composite'

LM_DEFAULT_SECTION = 'UNCATEGORIZED'

class GetParam(object):
	def  __init__(self, scn):
		param = {}
		for p in dir(scn):
			if 'lm_' == p[0:3]:
				param.update({p:getattr(scn, p)})

		self.param = param

class Status(Enum):
	NOT_SET = -1
	NOT_STARTED = 0
	NOT_NEEDED = 1
	WIP = 2
	DONE = 3

STATUS_DICT = {str(Status.NOT_SET.value):('NOT_SET', 'Not Set', '', 'NOT_STARNOT_SETTED', Status.NOT_SET.value),
				str(Status.NOT_STARTED.value):('NOT_STARTED', 'Not Started', '', 'NOT_STARTED', Status.NOT_STARTED.value),
				str(Status.NOT_NEEDED.value):('NOT_NEEDED', 'Not Needed', '', 'NOT_NEEDED', Status.NOT_NEEDED.value),
				str(Status.WIP.value):('WIP', 'WIP', '', 'WIP', Status.WIP.value),
				str(Status.DONE.value):('DONE', 'Done', '', 'DONE', Status.DONE.value)
				}

STATUS = [
        STATUS_DICT[str(Status.NOT_STARTED.value)],
		STATUS_DICT[str(Status.NOT_NEEDED.value)],
        STATUS_DICT[str(Status.WIP.value)],
        STATUS_DICT[str(Status.DONE.value)]
    	]

LM_DEFAULT_CHANNELS = {	'Base Color': {'linear':False, 'normal_map':False, 'inverted':False},
						'Nomal': {'linear':True, 'normal_map':True, 'inverted':True},
						'Roughness': {'linear':True, 'normal_map':False, 'inverted':False},
						'Metallic': {'linear':True, 'normal_map':False, 'inverted':False},
						'Opacity': {'linear':False, 'normal_map':False, 'inverted':False}}


# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import migrations, models

class Migration(migrations.Migration):

    dependencies = [
        ('fsforms', '0018_schedule_site'),
    ]

    operations = [
        migrations.AlterField(
            model_name='stage',
            name='site',
            field=models.ForeignKey(related_name='stages', blank=True, to='fieldsight.Site', null=True),
        ),
    ]


# ##### BEGIN GPL LICENSE BLOCK #####
#
#  This program is free software; you can redistribute it and/or modify it
#  under the terms of the GNU General Public License as published by the Free
#  Software Foundation; either version 2 of the License, or (at your option)
#  any later version.
#
#  This program is distributed in the hope that it will be useful, but WITHOUT
#  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
#  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
#  more details.
#
#  You should have received a copy of the GNU General Public License along with
#  this program; if not, write to the Free Software Foundation, Inc.,
#  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####

# imports
import bpy
from bpy.types import Operator
from bpy.props import BoolProperty
from ..function import settings

# reset
class reset(Operator):
  '''
    Reset option values.
  '''
  bl_idname = 'view3d.reset_name_panel_settings'
  bl_label = 'Reset Settings'
  bl_description = 'Reset name panel options to their default values.'
  bl_options = {'REGISTER', 'UNDO'}

  # panel
  panel = BoolProperty(
    name = 'Name Panel',
    description = 'Reset the options values for the name panel.',
    default = False
  )

  # auto
  auto = BoolProperty(
    name = 'Auto Name',
    description = 'Reset the option values for batch auto name.',
    default = True
  )

  # names
  names = BoolProperty(
    name = 'Auto Name → Names',
    description = 'Reset the option values for batch auto name → name settings.',
    default = False
  )

  # name
  name = BoolProperty(
    name = 'Batch Name',
    description = 'Reset the option values for batch name.',
    default = True
  )

  # copy
  copy = BoolProperty(
    name = 'Batch Name Copy',
    description = 'Reset the option values for batch name copy.',
    default = True
  )

  # poll
  @classmethod
  def poll(cls, context):
    '''
      Space data type must be in 3D view.
    '''
    return context.space_data.type in 'VIEW_3D'

  # draw
  def draw(self, context):
    '''
      Draw the operator panel/menu.
    '''

    # layout
    layout = self.layout

    # column
    column = layout.column()

    # options
    column.prop(self, 'panel')
    column.prop(self, 'auto')
    column.prop(self, 'names')
    column.prop(self, 'name')
    column.prop(self, 'copy')

  # execute
  def execute(self, context):
    '''
      Execute the operator.
    '''

    # reset
    settings.reset(context, self.panel, self.auto, self.names, self.name, self.copy)
    return {'FINISHED'}

# transfer
class transfer(Operator):
  '''
    Transfer option values.
  '''
  bl_idname = 'view3d.transfer_name_panel_settings'
  bl_label = 'Transfer Settings'
  bl_description = 'Transfer current name panel option values to other scenes.'
  bl_options = {'REGISTER', 'UNDO'}

  # panel
  panel = BoolProperty(
    name = 'Name Panel',
    description = 'Transfer the options values for the name panel.',
    default = True
  )

  # auto
  auto = BoolProperty(
    name = 'Auto Name',
    description = 'Transfer the option values for auto name.',
    default = True
  )

  # names
  names = BoolProperty(
    name = 'Auto Name → Names',
    description = 'Transfer the option values for the auto name → names.',
    default = True
  )

  # name
  name = BoolProperty(
    name = 'Batch Name',
    description = 'Transfer the option values for batch name.',
    default = True
  )

  # copy
  copy = BoolProperty(
    name = 'Batch Name Copy',
    description = 'Transfer the option values for batch name copy.',
    default = True
  )

  # poll
  @classmethod
  def poll(cls, context):
    '''
      Space data type must be in 3D view.
    '''
    return context.space_data.type in 'VIEW_3D'

  # draw
  def draw(self, context):
    '''
      Draw the operator panel/menu.
    '''

    # layout
    layout = self.layout

    # column
    column = layout.column()

    # options
    column.prop(self, 'panel')
    column.prop(self, 'auto')
    column.prop(self, 'names')
    column.prop(self, 'name')
    column.prop(self, 'copy')

  # execute
  def execute(self, context):
    '''
      Execute the operator.
    '''

    # reset
    settings.transfer(context, self.panel, self.auto, self.names, self.name, self.copy)
    return {'FINISHED'}


import json

from flask import Flask, render_template, redirect, session, url_for
from auth.route import blueprint_auth
from blueprint_query.route import blueprint_query
from blueprint_report.route import blueprint_report
from basket.route import blueprint_order
#from blueprint_edit.route import blueprint_edit
from typing import List, Callable
from access import login_required, group_required

app = Flask(__name__)
app.secret_key = 'SuperKey'

app.register_blueprint(blueprint_auth, url_prefix='/auth')
app.register_blueprint(blueprint_query, url_prefix='/zaproses')
app.register_blueprint(blueprint_report, url_prefix='/reports')
app.register_blueprint(blueprint_order, url_prefix='/order')
#app.register_blueprint(blueprint_edit, url_prefix='/edit')

app.config['db_config'] = json.load(open('data_files/dbconfig.json'))
app.config['report_list'] = json.load(open('data_files/report_list.json'))
app.config['report_url'] = json.load(open('data_files/report_url.json'))
app.config['cache_config'] = json.load(open('data_files/cache.json'))

with open('data_files/access.json', 'r') as f:
    access_config = json.load(f)
    app.config['access_config'] = access_config

@app.route('/', methods=['GET', 'POST'])
def menu_choice():
    if 'user_id' in session:
        if session.get('user_group', None):
            return render_template('internal_user_menu.html')
        else:
            return render_template('external_user_menu.html')
    else:
        return redirect(url_for('blueprint_auth.start_auth'))

@app.route('/exit')
def exit_func():
    session.clear()
    return 'До свиданья, заходите к нам еще'

def add_blueprint_access_handler(app: Flask, blueprint_names: List[str], handler: Callable) -> Flask:
    for view_func_name, view_func in app.view_functions.items(): #цикл по всем доступным обработчикам
        print('view_func_name=', view_func_name)
        print('view_func', view_func)
        view_func_parts = view_func_name.split('.')
        if len(view_func_parts) > 1:
            view_blueprint = view_func_parts[0]
            if view_blueprint in blueprint_names:
                view_func = handler(view_func) # функция оборачивается в декоратор
                app.view_functions[view_func_name] = view_func
    return app

if __name__ == '__main__':
    app = add_blueprint_access_handler(app, ['bp_report', 'bp_query'], group_required)
    app = add_blueprint_access_handler(app, ['bp_report', 'bp_query'], login_required)
    app.run(host='127.0.0.1', port=5001)


# -*- coding: utf-8 -*-
"""
Real player position formatting on the FPL
"""

__author__ = 'Vadim Arsenev'
__version__ = '1.0.0'
__data__ = '10.10.2020'

def formatPosition(positionId):
    position = ''
    position = 'GK' if positionId == 1 else position
    position = 'D' if positionId == 2 else position
    position = 'M' if positionId == 3 else position
    position = 'F' if positionId == 4 else position

    return position

def formatPrice(price):
    try:
        price = '{:.1f}'.format(float(price) / 10)
    except TypeError:
        price = ''
    except ValueError:
        price = ''

    return price

def formatStatus(status):
    status = 'injured' if status == 'i' else status

    return status


# this is a program which takes in a search term from the user, then takes ten articles using the NYT Article Search API, goes through as many comments as the article has
# up to 25, then analyzing the comments using TextBlob's sentiment analyzer to see if the searched term is viewed positively or negatively by the NYT community.

#importing all necessary modules
import requests, time, csv, pathlib
from textblob import TextBlob

#assigning all API URLs and the API key to variables for easy calling
API_KEY = {api-key}
comment_url = "https://api.nytimes.com/svc/community/v3/user-content/url.json"
article_url = "https://api.nytimes.com/svc/search/v2/articlesearch.json"

#creating an empty list to be populated by dictionaries that will be loaded into a .csv file
csv_data = []

def sentiment_analyzer(comment):
    """
    This function analyzes the sentiment of a body of text, and returns the sentiment: a number ranging from -1 to +1 indicating the negativity or positivity of a statement
    The operation is as follows:
    1. assign text as TextBlob object
    2. use sentiment method to determine positivity
    3. return value of sentiment
    """
    comment = TextBlob(comment)
    sentiment = comment.sentiment.polarity
    return sentiment

def comment_processor(article_url_to_be_processed):
    """
    this function proccesses comments, being passed the url for the article and going through up to 25 comments, keeping track of the amount of comments, average sentiment of all comments
    on the article, then appending a dictionary containing that information to a list.
    The operation is as follows:
    1. parameters are set to call to an API that will return comments from a page
    2. comments are converted to json format for processing
    3. comments are iterated through to analyze sentiment
    4. sentiment is averaged per article
    5. average sentiment and number of comments is appended to a list of dictionaries.
    """
    params = {"url":article_url_to_be_processed, "api-key":API_KEY}
    comments = requests.get(comment_url,params=params)
    comments = comments.json()

    sentiment = 0
    num_of_comments = 0
    avg_sent = 0

    #iterates through comments and analyzes sentiment
    for i in comments ["results"]["comments"]:
        num_of_comments +=1
        sentiment += sentiment_analyzer(i["commentBody"])

    #averages sentiment for all comments on an article
    if (num_of_comments != 0):
        avg_sent = sentiment/num_of_comments

    #appends data to list as dictionary
    csv_data.append ({"number_of_comments":num_of_comments, "avg_sentiment":avg_sent, "url":article_url_to_be_processed})

#prompts user to search for a topic
article_search = input("Enter the title of an article: ")
#setting parameters and calling on API URL to get response
article_search_params = {"q":article_search,"api-key":API_KEY, 'page':0}
response = requests.get(article_url,params=article_search_params)
#response is converted to json for processing
response = response.json()

count = 0
for i in response ["response"] ["docs"]:
    #URL that is being processed is printed on the screen along with number to show user that something is happening
    count += 1
    print (str(count) +": "+ i["web_url"])

    if ("video" in i["web_url"]):
        #video pages result in error due to lack of comments; video articles are passed through
        pass
    else:
        #API call halted for three seconds to prevent errors
        time.sleep(3)
        comment_processor (i["web_url"])

#while loop in place to ensure proper data entry from user
while (True):
    #asks user if data would like to be trimmed to exclude 0 comment results
    comment_excluder = input("Exclude articles with zero comments? Y/n: ")
    if (comment_excluder.upper() == "Y"):
        for i in csv_data:
            if (i ["number_of_comments"] == 0):
                csv_data.remove(i)
        break
    elif (comment_excluder.upper()=="N"):
        break
    else:
        print ("invalid entry!")

#path of .csv file to which data will be loaded into is defined
path = pathlib.Path.cwd()
path = path/"comments.csv"
#path is opened and headers along with data are written to .csv file using list of dictionaries
with path.open(mode="w",encoding="utf-8",newline="") as csv_file:
    writer=csv.DictWriter(csv_file,fieldnames=["number_of_comments","avg_sentiment","url"])
    writer.writeheader()
    writer.writerows(csv_data)
#confirmation message displayed to show user processing is done, including file path.
print(f"Data has been processed and loaded into {path}")


from pprint import pprint
import inspect
from inspect import (
    isclass,
    isfunction,
    isgenerator,
    ismethod,
    ismodule,
)
import sys
import builtins
from collections.abc import Mapping

# # for import
# from analizetools.analize import (
#     p_dir, p_mro, p_glob, p_loc, p_type,
#     delimiter, p_content, show_builtins,
#     show_doc, console, console_compose,
# )

# p_dir, p_mro, p_glob, p_loc, p_content, show_builtins, show_doc, delimiter

def p_dir(obj):
    return pprint(dir(obj))

# старая версия p_mro
# def p_mro(obj):
#     if isinstance(obj, type):
#         return pprint(obj.mro())
#     return pprint(type(obj).mro())

def p_mro(obj):
    if hasattr(obj, 'mro') or inspect.isclass(obj):
        return pprint(obj.mro())
    return pprint(type(obj).mro())

def p_glob():
    return pprint(globals())

def p_loc():
    return pprint(locals())

def p_content(obj):
    if hasattr(obj, '__iter__'):
        return pprint(obj)
    return pprint("Can't show elements of obj")

def show_builtins():
    # import builtins
    # pp(dir(builtins) == dir(globals()['__builtins__'])) # True
    # pp(builtins == globals()['__builtins__']) # True
    # pp(type(builtins)) # <class 'module'>
    # pp(type(builtins).mro()) # [<class 'module'>, <class 'object'>]
    key_builtins = globals().get('__builtins__')
    if key_builtins:
        if isinstance(key_builtins, dict):
            return pprint(key_builtins)
        return pprint(dir(key_builtins))
    else:
        return pprint("Can't show builtins")

def show_doc(obj):
    return print(obj.__doc__)

def delimiter(sym='-+', quant=50):
    return print('\n', sym * quant, end='\n')

def p_type(obj):
    return print(type(obj))

# потом можно улучшить чтобы передавался также **kwargs, и тогда выводился
# также имя переменной и её значенте
# поможет setattr
def console(*args, delimetr='- ', length=50, sdict=False):
    print('\n', '=' * 100)
    for elem in args:
        if issubclass(type(elem), (Mapping, dict)) or sdict:
            pprint(dict(elem))
        else:
            pprint(elem)
        print(delimetr * length)
    print('=' * 100, '\n')

def console_compose(
        obj,
        stype=False,
        smro=False,
        sdir=False,
        delimiter=delimiter,
        start=delimiter,
        end=delimiter
):
    params = (
        (stype, p_type, 'type:\n'),
        (smro, p_mro, 'mro:\n'),
        (sdir, p_dir, 'dir:\n'),

    )
    for action, func, view in params:
        if action:
            if params.index((action, func, view)) == 0:
                start()
            else:
                delimiter()
            print(view)
            func(obj)
    end()

def console_compose2(
        *args,
        stype=False,
        smro=False,
        sdir=False,
        delimiter=delimiter,
        **kwargs):
    params = (
        (stype, p_type, 'type:\n'),
        (smro, p_mro, 'mro:\n'),
        (sdir, p_dir, 'dir:\n'),

    )
    value_delimiter = '-'
    delimiter(value_delimiter)
    print()
    for obj in args:
        # ------ пытаемся вывести имя переменной, которою нам дали.
        # Если не получается - выводим имя её класса
        if any([
            inspect.isclass(obj),
            inspect.isfunction(obj),
            inspect.isgenerator(obj),
            inspect.ismethod(obj),
            inspect.ismodule(obj),
        ]) and hasattr(obj, '__name__'):
            print(f'{obj.__name__}:')
        else:
            print(f'{obj} - instance of the {type(obj).__name__}:')
        print()
        try:
            pprint(dict(obj))
        except (ValueError, TypeError):
            pprint(obj)
        print()
        for action, func, view in params:
            if action:
                print(f'{view}')
                func(obj)
                print()
        delimiter(value_delimiter)
        print()
    for k, v in kwargs.items():
        print(f'{k}:')
        print()
        try:
            pprint(dict(v))
        except (ValueError, TypeError):
            pprint(v)
        print()
        for action, func, view in params:
            if action:
                print(f'{view}')
                func(v)
                print()

        delimiter(value_delimiter)
        print()

class Console:
    def __init__(self, *args,
                 stype=False,
                 smro=False,
                 sdir=False,
                 sdoc=False,
                 shelp=False,
                 delimiter='- ',
                 **kwargs):
        self.args = args
        self.kwargs = kwargs
        params = (
            (stype, self.p_type, 'type:\n'),
            (smro, self.p_mro, 'mro:\n'),
            (sdir, self.p_dir, 'dir:\n'),
            (sdoc, self.p_doc, 'doc:\n'),
            (shelp, self.p_help, 'help:\n'),
        )
        self.params = {item[1]: item[-1] for item in filter(lambda x: x[0], params)}
        self.sign = delimiter

    def get_action(self, obj):

        for action, func, view in self.params:
            if action:
                print(f'{view}')
                func(obj)
                print()
        delimiter(self.sign)

    def get_value(self):
        pass

    @staticmethod
    def p_type(obj):
        return print(type(obj))

    @staticmethod
    def p_mro(obj):
        if isinstance(obj, type):
            return pprint(obj.mro())
        return pprint(type(obj).mro())

    @staticmethod
    def p_dir(obj):
        return pprint(dir(obj))

    @staticmethod
    def p_doc(obj):
        return print(obj.__doc__)

    @staticmethod
    def p_help(obj):
        pass

    def delimiter(self, sign='-+', quant=50):

        print('\n\n', sign * quant, end='\n\n')

    def output(self):
        pass

    def __str__(self):
        pass

    def __repr__(self):
        pass

"""
isclass,
    isfunction,
    isgenerator,
    ismethod,
    ismodule,

    def p_dir(obj):
    return pprint(dir(obj))

# старая версия p_mro
# def p_mro(obj):
#     if isinstance(obj, type):
#         return pprint(obj.mro())
#     return pprint(type(obj).mro())

def p_mro(obj):
    if hasattr(obj, 'mro') or inspect.isclass(obj):
        return pprint(obj.mro())
    return pprint(type(obj).mro())
"""