import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns

from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error, r2_score

from sklearn.pipeline import Pipeline
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.compose import ColumnTransformer

from sklearn import tree
from sklearn.metrics import confusion_matrix, classification_report

pd.set_option('max_columns', None)
pd.options.display.width = None
data = sns.load_dataset('titanic')

# ******************************************* section 01 - Logistic regression
data = data.drop(['who', 'adult_male', 'embark_town', 'alive', 'class', 'alone'], axis='columns')
X = data.drop(['survived'], axis='columns')
y = data['survived']

# cleaning data
numeric_features = ["age", "fare"]
numeric_transformer = Pipeline(steps=[("imputer", SimpleImputer(strategy="median")),
                                      ("scaler", StandardScaler())])

categorical_features = ["embarked", "sex", "deck"]
categorical_transformer = Pipeline(steps=[("imputer", SimpleImputer(strategy="constant")),
                                          ("ohe", OneHotEncoder(handle_unknown="ignore"))])

preprocessor = ColumnTransformer(transformers=[('num', numeric_transformer, numeric_features),
                                               ("cat", categorical_transformer, categorical_features)])

x_train, x_test, y_train, y_test = train_test_split(X, y, test_size=0.20, random_state=42)

# training
clf = Pipeline(steps=[("preprocessor", preprocessor),
                      ("classifier", LogisticRegression())])
fit_model = clf.fit(x_train, y_train)
score = clf.score(x_test, y_test)
y_pred = clf.predict(x_test)

# print('score:', score)
# print('mean squared error:', mean_squared_error(y_test, y_pred))
# print('r2 score:', r2_score(y_test, y_pred))

# ******************************************************* section 02 - tiping
sns.set_theme()
tips = sns.load_dataset('tips')
tips['ratio'] = tips['tip'] / tips['total_bill']
mean = tips.groupby('sex')['ratio'].mean()

sns.lmplot(data=tips, x="total_bill", y="ratio", hue='sex')
sns.relplot(data=tips, x="total_bill", y="ratio", hue='sex')
plt.axhline(mean['Male'], 0, 50)
plt.axhline(mean['Female'], 0, 50, color='orange')
plt.show()

# ************************************************ section 03 - Decision tree
data = sns.load_dataset('titanic')
data_2 = data.copy()
# cleaning data
data = data.drop(['who', 'adult_male', 'embark_town', 'alive', 'class', 'alone'], axis='columns')
print(data)
data = pd.concat([data, pd.get_dummies(data["sex"]),
                  pd.get_dummies(data["embarked"]),
                  pd.get_dummies(data["deck"])], axis=1)
data = data.drop(['sex', 'embarked', 'deck'], axis='columns')
data = data.fillna(method='bfill')
print(data)
x = data.drop(['survived'], axis='columns')
y = data['survived']

# training
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.20, random_state=42)
clf = tree.DecisionTreeClassifier().fit(x_train, y_train)
fig, axes = plt.subplots(dpi=300)
tree.plot_tree(clf, feature_names=list(data),
               class_names=["survived", "died"],
               filled=True)

print(classification_report(y_test, clf.predict(x_test)))
# ********************** another aproach
x = data_2.drop(['survived'], axis='columns')
y = data_2['survived']

numeric_features = ["age", "fare"]
numeric_transformer = Pipeline(steps=[("imputer", SimpleImputer(strategy="mean")),
                                      ("scaler", StandardScaler())])

categorical_features = ["embarked", "sex", "deck"]
categorical_transformer = Pipeline(steps=[("imputer", SimpleImputer(strategy="constant")),
                                          ("ohe", OneHotEncoder(handle_unknown="ignore"))])

preprocessor = ColumnTransformer(transformers=[('num', numeric_transformer, numeric_features),
                                               ("cat", categorical_transformer, categorical_features)])
# training
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.20, random_state=42)
clf = Pipeline(steps=[("preprocessor", preprocessor),
                      ("classifier", tree.DecisionTreeClassifier())])
clf.fit(x_train, y_train)
print(classification_report(y_test, clf.predict(x_test)))


from PIL import Image

# read in the image
image = Image.open('apple.jpg')

# display the image in its original perspective
image.show()

# flip the image on the vertical axis (mirror)
flip = image.transpose(Image.FLIP_LEFT_RIGHT)
flip.show()

# flip the image on the horizontal axis (upside down)
flip = image.transpose(Image.FLIP_TOP_BOTTOM)
flip.show()


#!/usr/bin/python3

import os
import sys
import requests
import msgpackrpc
import hashlib
import boto3
import time
import subprocess
import socket

def hash(str):
        print('HASH')
        return int(hashlib.md5(str.encode()).hexdigest(), 16) & ((1 << 32) - 1)

# get instances' id from suto-scaling group
autoscaling_client = boto3.client('autoscaling', region_name='eu-central-1')
response = autoscaling_client.describe_auto_scaling_groups(
        AutoScalingGroupNames=[
        'fuhming1468',
        'fuhming'
    ]
)
instances = response['AutoScalingGroups'][0]['Instances']
size = len(instances)

print(f'group size : {size}')
instance_ids = [i['InstanceId'] for i in instances]
print(instance_ids)

# get instances' ip
instance_ips = []
ec2_client = boto3.client('ec2', region_name='eu-central-1')
for i in instances:
    ip = ec2_client.describe_instances(
        InstanceIds = [
            i["InstanceId"]
        ]
    )['Reservations'][0]['Instances'][0]['PublicIpAddress']
    instance_ips.append(ip)

size = len(instance_ips)
print(f'group size : {size}')
print(instance_ips)


import json
import urllib.request, urllib.parse, urllib.error
from urllib.request import urlopen
import ssl

# Ignore SSL certificate errors
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE

# extracting & treating data from url
url = input('Enter-')
java = urllib.request.urlopen(url,context=ctx)
data = java.read().decode()

# creating dictionary by using json
js = json.loads(data)

# extracting & creating a list x from js
x = js['comments']

# extracting dictionary items embedded in a list
new_list = [i["count"] for i in x]

# adding the numbers
print("Sum:",sum(new_list))


from serialization.ng_parse_module_base import NgParseModuleBase

# 利用反射获取 NgParseModuleBase 的所有子类，并且实例化
# NgParseModuleBase 的子类要被装载到当前目录的 __init__.py 中

def create_parse_modules():
    module_lits = NgParseModuleBase.__subclasses__()
    serialization_model = __import__("serialization")

    parse_modules = []

    def match_and_parse(key, config):
        for module in parse_modules:
            if module.match_key(key):
                return module.to_data(config)
        return False

    for module in module_lits:
        subclass = getattr(serialization_model, module.__name__)
        sub_obj = subclass()
        parse_modules.append(sub_obj)
        sub_obj.set_match_and_parse(match_and_parse)

    return match_and_parse


def check_char(number):
    bits = "{0:08b}".format(number)
    if int(bits[0]) == sum(map(int, bits[1:])) % 2:
        return number & 0x7f

def translate_line(line: str) -> str:
    ascii_codes = map(int, line.split())
    checked_values = [check_char(n) for n in ascii_codes]
    return "".join(chr(val) for val in checked_values if val)

if __name__ == '__main__':
    print(translate_line('65 238 236 225 46'))


import numpy as np

class LR(object):
    def __init__(self, X, Y, init_w, init_b, alpha=1, l=0.01):
        self.w = init_w
        self.b = init_b
        self.X_unnorm = X
        self.X, self.X_mean, self.X_std = self.normalize(self.X_unnorm, gen_stats=True)
        self.Y = Y
        self.m = X.shape[1]
        self.alpha = alpha
        self.l = l # lambda

    def normalize(self, X_unnorm, gen_stats=False):
        if gen_stats:
            X_mean = np.mean(X_unnorm, axis=1)[:,np.newaxis] # column vector
            X_std = np.std(X_unnorm, axis=1)[:,np.newaxis]
        else:
            X_mean = self.X_mean
            X_std = self.X_std
        X = (X_unnorm - X_mean) / X_std
        return X, X_mean, X_std

    def J(self, w, b, X=None, Y=None, regularize=False):
        if not X or not Y:
            X, Y = self.X, self.Y
            m = self.m
        else:
            m = X.shape[1]
        A, _ = self.__predict(X, w, b)
        if regularize:
            # print(f'w shape: {w.shape}, b is: {b}, X.shape: {X.shape}, y.shape: {y.shape}, m is: {m}, a.shape is: {a.shape}')
            l = self.l
            reg_term = l*np.dot(w.T, w) / (2*m)
            result = -(np.dot(Y, np.log(A).T) + np.dot((1-Y), np.log(1-A).T)) / m + reg_term
        else:
            result = -(np.dot(Y, np.log(A).T) + np.dot((1-Y), np.log(1-A).T)) / m
        # print(type(result))
        # print(result.shape)
        return np.asscalar(result)

    def sigmoid(self, Z):
        return np.reciprocal((1 + np.exp(-Z)))

    def __predict(self, X, w, b):
        # w = self.w
        # b = self.b
        Z = np.dot(w.T, X) + b
        A = self.sigmoid(Z)
        return A, Z

    def predict(self, X, normalize=True):
        if normalize:
            X, X_mean, X_std = self.normalize(X)
        return self.__predict(X, self.w, self.b)

    def grad(self):
        A, Z = self.__predict(self.X, self.w, self.b)
        dZ = A - self.Y
        reg_term = self.l*self.w
        dw = (np.dot(self.X, dZ.T) + reg_term) / self.m
        db = np.sum(dZ) / self.m
        return dw, db

    def backprop_numcheck(self, iterations=1):
        init_w = self.w
        init_b = self.b
        for i in range(iterations):
            print(f'[{i}] ', end='')
            dw, db = self.grad()
            print(f'Gradient calculated')
            ndw, ndb = self.num_grad()
            diff_dw = dw - ndw
            diff_db = db - ndb
            max_diff = max(np.max(diff_dw), diff_db)
            # print(db, ndb)
            # print(np.c_[dw, ndw])
            print(f'[{i:03}] Numerical Check, max dw/db diff  = {max_diff}')
            self.w -=  self.alpha*ndw
            self.b -=  self.alpha*ndb
        self.w = init_w
        self.b = init_b

    def backprop(self, iterations=1):
        for i in range(iterations):
            dw, db = self.grad()
            self.w -=  self.alpha*dw
            self.b -=  self.alpha*db

    def num_grad(self):
        w = self.w
        b = self.b
        # print(f'w.shape is {w.shape}')
        epsilon = 1e-4
        perturb_w = np.zeros((w.shape[0], 1))
        # print(perturb_w.shape)
        dw = np.zeros((w.shape[0],1))
        b = 0
        for i in range(w.shape[0]):
            perturb_w[i] = epsilon
            # print(f'w.shape is {w.shape}')
            # print(f'perturb_w.shape is {perturb_w.shape}')
            # print(f'(w - perturb_w).shape is {(w - perturb_w).shape}')
            loss1 = self.J(w - perturb_w, b, regularize=True)
            loss2 = self.J(w + perturb_w, b, regularize=True)
            # print(f'perturb w [{i}]')
            # print(f'loss1 {loss1}')
            # print(f'loss2 {loss2}')
            dw[i] = (loss2 - loss1) / (2*epsilon)
            perturb_w[i] = 0
        b_loss1 = self.J(w, b - epsilon)
        b_loss2 = self.J(w, b + epsilon)
        db = (b_loss2 - b_loss1) / (2*epsilon)
        return dw, db

    def accuracy(self, X, y):
        a, z = self.predict(X)
        h = np.array(a >= 0.5, dtype=np.int)
        accuracy_vector = np.array(h == y, dtype=np.int)
        #show = np.column_stack((h,y,accuracy_vector))
        #print(show, show.shape)
        return np.mean(accuracy_vector)

    def train(self, iterations=10000, min_J_diff=0.1):
        pass

if __name__ == '__main__':
    from testdatapoints import set_seed, labeled_two_classPoints
    from plot2d import Plot2D
    set_seed(142)
    datapoints = labeled_two_classPoints(Aweight=2, Bweight=1,
                                         Aamount=500, Bamount=500,
                                         scale=5)
    plot = Plot2D((5,5))

    rows    = datapoints.shape[0]
    columns = datapoints.shape[1]

    X = datapoints[:,:2]
    X = X.T
    Y = datapoints[:,2]
    Y = Y.reshape(1,np.size(Y))
    print(f'Y shape: {Y.shape}')
    w = np.zeros((X.shape[0],1)) #np.random.randn(X.shape[0],1)        #(3072, 1)
    b = 0
    model = LR(X,Y,w,b, alpha=3)

    predictor_func = lambda X: model.predict(X)[0]

    plot.plot_labeled_data(datapoints)

    model.backprop_numcheck(iterations=10)
    accuracy = model.accuracy(model.X, model.Y)
    print(f'Training accuracy: {accuracy}')

    # for i in range(1000):
        # model.backprop(iterations=1)
        # cost = model.J(model.w, model.b)
        # accuracy = model.accuracy(model.X, model.y)
        # print(f'[{i:04}] Cost is: {cost:.6f}, Training accuracy: {accuracy}')
        # plot.plot_decision_surface(predictor_func)
        # plot.add_line_cost_func(cost,1)
        #
        # plot.pause(0.01)


class Item:
    """An item we sell at our store."""

    def __init__(self, name, price):
        self.name = name
        self.price = price

def cents_changer(Item, new_cents):
    old_price = Item.price
    if new_cents > .99:
        Item.price = int(Item.price) + new_cents/100
    else:
        Item.price = int(Item.price) + new_cents

    print (f'You have changed the price of {Item.name}s from ${old_price} to ${Item.price}!')

item1 = Item('book', 5.51)
item2 = Item('pencil', 1.22)

cents_changer(item1, 99)


"""
The Goldberg formula for computing spin-weighted spherical harmonics is implemented here.
  (https://aip.scitation.org/doi/10.1063/1.1705135)
Wikipedia also has an article on Spin-Weighted Spherical Hamronics:
  (https://en.wikipedia.org/w/index.php?title=Spin-weighted_spherical_harmonics&oldid=853425244)

Authors: Brandon Clark
         Zachariah B. Etienne
         zachetie **at** gmail **dot* com
"""
from typing import cast, Dict
import sympy as sp  # SymPy: The Python computer algebra package upon which NRPy+ depends

from nrpy.helpers.cached_functions import cached_simplify

def Y(
    s: int,
    l: int,
    m: int,
    th: sp.Symbol,
    ph: sp.Symbol,
    GenerateMathematicaCode: bool = False,
) -> sp.Expr:
    """
    Compute the spin-weighted spherical harmonics using the Goldberg formula.
    Refer to https://aip.scitation.org/doi/10.1063/1.1705135 and Wikipedia's article on
    Spin-weighted spherical harmonics:
    https://en.wikipedia.org/w/index.php?title=Spin-weighted_spherical_harmonics&oldid=853425244

    :param s: Spin weight of the spherical harmonic.
    :param l: Degree of the spherical harmonic.
    :param m: Order of the spherical harmonic.
    :param th: Theta symbol.
    :param ph: Phi symbol.
    :param GenerateMathematicaCode: Boolean to control whether to generate code compatible with Mathematica.

    :return: Expression for the spin-weighted spherical harmonic.
    """
    Sum: sp.Expr = sp.sympify(0)
    # Not sympifying -1 causes SymPy to revert to double-precision arithmetic
    negative_one = sp.sympify(-1)
    for r in range(l - s + 1):
        if GenerateMathematicaCode:
            # Mathematica needs expression to be in terms of cotangent, so that code validation below
            #    yields identity with existing Mathematica notebook on spin-weighted spherical harmonics.
            Sum += (
                sp.binomial(l - s, r)
                * sp.binomial(l + s, r + s - m)
                * negative_one ** (l - r - s)
                * sp.exp(sp.I * m * ph)
                * sp.cot(th / 2) ** (2 * r + s - m)
            )
        else:
            # SymPy C code generation cannot handle the cotangent function, so define cot(th/2) as 1/tan(th/2):
            Sum += (
                sp.binomial(l - s, r)
                * sp.binomial(l + s, r + s - m)
                * negative_one ** (l - r - s)
                * sp.exp(sp.I * m * ph)
                / sp.tan(th / 2) ** (2 * r + s - m)
            )
    return cast(
        sp.Expr,
        sp.sqrt(
            sp.factorial(l + m)
            * sp.factorial(l - m)
            * (2 * l + 1)
            / (4 * sp.pi * sp.factorial(l + s) * sp.factorial(l - s))
        )
        * cached_simplify(negative_one**m * sp.sin(th / 2) ** (2 * l) * Sum),
    )

if __name__ == "__main__":
    import doctest
    import os
    import sys
    import nrpy.validate_expressions.validate_expressions as ve

    results = doctest.testmod()
    if results.failed > 0:
        print(f"Doctest failed: {results.failed} of {results.attempted} test(s)")
        sys.exit(1)
    else:
        print(f"Doctest passed: All {results.attempted} test(s) passed")

    expr_dict: Dict[str, sp.Expr] = {}
    _th, _ph = sp.symbols("th ph", real=True)
    for _l in range(2, 9):
        for _m in range(-_l, +_l):
            expr_dict[f"Y_{{s=-2, l={_l}, m={_m}}}"] = Y(-2, _l, _m, _th, _ph)
    results_dict = ve.process_dictionary_of_expressions(
        expr_dict, fixed_mpfs_for_free_symbols=True
    )
    ve.compare_or_generate_trusted_results(
        os.path.abspath(__file__),
        os.getcwd(),
        # File basename. If this is set to "trusted_module_test1", then
        #   trusted results_dict will be stored in tests/trusted_module_test1.py
        f"{os.path.splitext(os.path.basename(__file__))[0]}",
        results_dict,
    )


from math import log10
import re

import edrlog
from edmodule import EDResistances

EDRLOG = edrlog.EDRLog()

class EDHullReinforcementPackage(object):
    def __init__(self):
        # TODO make this a child of EDModule, reflect powerdraw etc.
        self.armour = 0
        self.resistances = EDResistances()
        self.enabled = True

    def update_from(self, module):
        engineering = module.get("Engineering", {})
        modifiers = engineering.get("Modifiers", [])
        for m in modifiers:
            if m.get("Label", "") == "DefenceModifierHealthAddition" and "Value" in m:
                self.armour = m["Value"]

            if m.get("Label", "") == "ThermicResistance" and "Value" in m:
                self.resistances.thermal = m["Value"] / 100.0

            if m.get("Label", "") == "KineticResistance" and "Value" in m:
                self.resistances.kinetic = m["Value"] / 100.0

            if m.get("Label", "") == "ExplosiveResistance" and "Value" in m:
                self.resistances.explosive = m["Value"] / 100.0

class EDGuardianHullReinforcementPackage(object):
    def __init__(self):
        self.armour = 0
        self.resistances = EDResistances(0.02, 0.0, 0.0, 0.05)
        self.enabled = True # TODO take into account actual state, although this might always be true?

class EDMetaAlloyHullReinforcementPackage(object):
    def __init__(self):
        self.armour = 0
        self.resistances = EDResistances(0.0, 0.0, 0.0, 0.03)
        self.enabled = True

class EDHullBulkhead(object):
    def __init__(self):
        self.armour = 0
        self.armour_multiplier = 1.0
        self.hull_resistances = EDResistances()

    def update_from(self, module):
        engineering = module.get("Engineering", {})
        modifiers = engineering.get("Modifiers", [])
        for m in modifiers:
            # TODO
            if m.get("Label", "") == "DefenceModifierHealthMultiplier" and "Value" in m:
                self.armour_multiplier = m["Value"]/100.0

            if m.get("Label", "") == "ThermicResistance" and "Value" in m:
                self.hull_resistances.thermal = m["Value"] / 100.0

            if m.get("Label", "") == "KineticResistance" and "Value" in m:
                self.hull_resistances.kinetic = m["Value"] / 100.0

            if m.get("Label", "") == "ExplosiveResistance" and "Value" in m:
                self.hull_resistances.explosive = m["Value"] / 100.0

    def strength(self, base_strength):
        if base_strength == 0:
            return 0

        hull_strength = base_strength * (1.0 + self.armour_multiplier)
        return hull_strength

class EDHrp5D(EDHullReinforcementPackage):
    def __init__(self):
        super(EDHrp5D, self).__init__()
        self.armour = 390
        self.resistances = EDResistances(0.025, 0.025, 0.025)

class EDHrp5E(EDHullReinforcementPackage):
    def __init__(self):
        super(EDHrp5E, self).__init__()
        self.armour = 360
        self.resistances = EDResistances(0.025, 0.025, 0.025)

class EDHrp4D(EDHullReinforcementPackage):
    def __init__(self):
        super(EDHrp4D, self).__init__()
        self.armour = 330
        self.resistances = EDResistances(0.02, 0.02, 0.02)

class EDHrp4E(EDHullReinforcementPackage):
    def __init__(self):
        super(EDHrp4E, self).__init__()
        self.armour = 300
        self.resistances = EDResistances(0.02, 0.02, 0.02)

class EDHrp3D(EDHullReinforcementPackage):
    def __init__(self):
        super(EDHrp3D, self).__init__()
        self.armour = 260
        self.resistances = EDResistances(0.015, 0.015, 0.015)

class EDHrp3E(EDHullReinforcementPackage):
    def __init__(self):
        super(EDHrp3E, self).__init__()
        self.armour = 230
        self.resistances = EDResistances(0.015, 0.015, 0.015)

class EDHrp2D(EDHullReinforcementPackage):
    def __init__(self):
        super(EDHrp2D, self).__init__()
        self.armour = 190
        self.resistances = EDResistances(0.01, 0.01, 0.01)

class EDHrp2E(EDHullReinforcementPackage):
    def __init__(self):
        super(EDHrp2E, self).__init__()
        self.armour = 150
        self.resistances = EDResistances(0.01, 0.01, 0.01)

class EDHrp1D(EDHullReinforcementPackage):
    def __init__(self):
        super(EDHrp1D, self).__init__()
        self.armour = 110
        self.resistances = EDResistances(0.005, 0.005, 0.005)

class EDHrp1E(EDHullReinforcementPackage):
    def __init__(self):
        super(EDHrp1E, self).__init__()
        self.armour = 80
        self.resistances = EDResistances(0.005, 0.005, 0.005)

class EDGhrp5D(EDGuardianHullReinforcementPackage):
    def __init__(self):
        super(EDGhrp5D, self).__init__()
        self.armour = 488

class EDGhrp5E(EDGuardianHullReinforcementPackage):
    def __init__(self):
        super(EDGhrp5E, self).__init__()
        self.armour = 450

class EDGhrp4D(EDGuardianHullReinforcementPackage):
    def __init__(self):
        super(EDGhrp4D, self).__init__()
        self.armour = 413

class EDGhrp4E(EDGuardianHullReinforcementPackage):
    def __init__(self):
        super(EDGhrp4E, self).__init__()
        self.armour = 375

class EDGhrp3D(EDGuardianHullReinforcementPackage):
    def __init__(self):
        super(EDGhrp3D, self).__init__()
        self.armour = 325

class EDGhrp3E(EDGuardianHullReinforcementPackage):
    def __init__(self):
        super(EDGhrp3E, self).__init__()
        self.armour = 288

class EDGhrp2D(EDGuardianHullReinforcementPackage):
    def __init__(self):
        super(EDGhrp2D, self).__init__()
        self.armour = 238

class EDGhrp2E(EDGuardianHullReinforcementPackage):
    def __init__(self):
        super(EDGhrp2E, self).__init__()
        self.armour = 188

class EDGhrp1D(EDGuardianHullReinforcementPackage):
    def __init__(self):
        super(EDGhrp1D, self).__init__()
        self.armour = 138

class EDGhrp1E(EDGuardianHullReinforcementPackage):
    def __init__(self):
        super(EDGhrp1E, self).__init__()
        self.armour = 100

class EDMhrp5D(EDMetaAlloyHullReinforcementPackage):
    def __init__(self):
        super(EDMhrp5D, self).__init__()
        self.armour = 351

class EDMhrp5E(EDMetaAlloyHullReinforcementPackage):
    def __init__(self):
        super(EDMhrp5E, self).__init__()
        self.armour = 324

class EDMhrp4D(EDMetaAlloyHullReinforcementPackage):
    def __init__(self):
        super(EDMhrp4D, self).__init__()
        self.armour = 297

class EDMhrp4E(EDMetaAlloyHullReinforcementPackage):
    def __init__(self):
        super(EDMhrp4E, self).__init__()
        self.armour = 270

class EDMhrp3D(EDMetaAlloyHullReinforcementPackage):
    def __init__(self):
        super(EDMhrp3D, self).__init__()
        self.armour = 234

class EDMhrp3E(EDMetaAlloyHullReinforcementPackage):
    def __init__(self):
        super(EDMhrp3E, self).__init__()
        self.armour = 207

class EDMhrp2D(EDMetaAlloyHullReinforcementPackage):
    def __init__(self):
        super(EDMhrp2D, self).__init__()
        self.armour = 171

class EDMhrp2E(EDMetaAlloyHullReinforcementPackage):
    def __init__(self):
        super(EDMhrp2E, self).__init__()
        self.armour = 135

class EDMhrp1D(EDMetaAlloyHullReinforcementPackage):
    def __init__(self):
        super(EDMhrp1D, self).__init__()
        self.armour = 99

class EDMhrp1E(EDMetaAlloyHullReinforcementPackage):
    def __init__(self):
        super(EDMhrp1E, self).__init__()
        self.armour = 72

class EDLightweightAlloyHull(EDHullBulkhead):
    def __init__(self):
        super(EDLightweightAlloyHull, self).__init__()
        self.armour_multiplier = 0.8
        self.resistances = EDResistances(0, -0.2, -0.4)

class EDReinforcedAlloyHull(EDHullBulkhead):
    def __init__(self):
        super(EDReinforcedAlloyHull, self).__init__()
        self.armour_multiplier = 1.52
        self.resistances = EDResistances(0, -0.2, -0.4)

class EDMilitaryGradeCompositeHull(EDHullBulkhead):
    def __init__(self):
        super(EDMilitaryGradeCompositeHull, self).__init__()
        self.armour_multiplier = 2.5
        self.resistances = EDResistances(0, -0.2, -0.4)

class EDMirroredSurfaceCompositeHull(EDHullBulkhead):
    def __init__(self):
        super(EDMirroredSurfaceCompositeHull, self).__init__()
        self.armour_multiplier = 2.5
        self.resistances = EDResistances(0.5, -0.75, -0.5)

class EDReactiveSurfaceCompositeHull(EDHullBulkhead):
    def __init__(self):
        super(EDReactiveSurfaceCompositeHull, self).__init__()
        self.armour_multiplier = 2.5
        # TODO
        self.resistances = EDResistances(-0.4, 0.2, 0.25)

class EDHullFactory(object):
    __module_classes = {
        "grade1": EDLightweightAlloyHull,
        "grade2": EDReinforcedAlloyHull,
        "grade3": EDMilitaryGradeCompositeHull,
        "mirrored": EDMirroredSurfaceCompositeHull,
        "reactive": EDReactiveSurfaceCompositeHull,
        "hullreinforcement_size5_class1": EDHrp5E,
        "hullreinforcement_size5_class2": EDHrp5D,
        "hullreinforcement_size4_class1": EDHrp4E,
        "hullreinforcement_size4_class2": EDHrp4D,
        "hullreinforcement_size3_class1": EDHrp3E,
        "hullreinforcement_size3_class2": EDHrp3D,
        "hullreinforcement_size2_class1": EDHrp2E,
        "hullreinforcement_size2_class2": EDHrp2D,
        "hullreinforcement_size1_class1": EDHrp1E,
        "hullreinforcement_size1_class2": EDHrp1D,
    }

    @staticmethod
    def normalize_module_name(name):
        normalized = name.lower()

        # suffix _name or _name; is not used in loadout or afmurepair events
        if normalized.endswith(u"_name"):
            useless_suffix_length = len(u"_name")
            normalized = normalized[:-useless_suffix_length]
        elif normalized.endswith(u"_name;"):
            useless_suffix_length = len(u"_name;")
            normalized = normalized[:-useless_suffix_length]

        if normalized.startswith(u"$"):
            normalized = normalized[1:]

        if normalized.startswith(u"int_"):
            normalized = normalized[4:]

        m = re.match(r'^.*_armour_(.*)$', normalized)
        if m:
            normalized = m.group(1)

        return normalized

    @staticmethod
    def from_internal_name(internal_name):
        cname = EDHullFactory.normalize_module_name(internal_name)
        if cname in EDHullFactory.__module_classes:
            hull = EDHullFactory.__module_classes[cname]()
            return hull
        return None

    @staticmethod
    def default_armour():
        return EDLightweightAlloyHull()

    @staticmethod
    def from_module(module):
        internal_name = module.get("Item", "N/A")
        cname = EDHullFactory.normalize_module_name(internal_name)
        if cname in EDHullFactory.__module_classes:
            hull = EDHullFactory.__module_classes[cname]()
            hull.update_from(module)
            return hull
        return None


# -*- coding:utf-8 -*-
"""
Environment variables settings.

This file also serves as template of un-tracked file .env, run:
    python env_settings.py > .env

When being imported, all variables listed in this file will be checked
from os.environ, an EnvironmentError will be raised if the policy
"_IF_ENV_MISS" is set to "raise" (the default).

"""

import os
import sys
import warnings

# quote sign used in generated template .env file
_QUOTE_SIGN = '\''
# what to do if variable not in environment: raise, warn, ignore
_IF_ENV_MISS = 'raise'
# whether override existing variable from os with values from .env file
_OVERRIDE_IF_EXIST = True
# whether add "export " prefix to template .env file
_USE_PREFIX_EXPORT = True

# all variables parsed from the .env file when being imported
_ALL_PARSED = {}

DEBUG = False
LOG_LEVEL = 'INFO'
TIME_ZONE = 'Asia/Shanghai'

SECRET_DATABASE_URL = 'sqlite:///dev.db'
SECRET_EMAIL_URL = 'smtp://user@domain.com:pass@smtp.example.com:465/?ssl=True'

SECRET_KEY = '{{ secret_key }}'

def _parse(dir_, vars_):
    from utils import dotenv
    if not os.path.exists('.env'):
        warnings.warn(
            '.env file not found in working directory, searching parents',
            UserWarning)
    dotenv.read_dotenv(dotenv.find_dotenv(), override=_OVERRIDE_IF_EXIST)
    absent = []
    for var in dir_:
        if var.isupper() and not var.startswith('_'):
            if var not in os.environ:
                absent.append(var)
            else:
                value = os.getenv(var)
                if isinstance(eval(var), bool):
                    value = value.lower() in ('true', 'yes', 'on')
                _ALL_PARSED[var] = value
    if absent:
        msg = 'miss environment variables: %s' % ', '.join(absent)
        if _IF_ENV_MISS == 'raise':
            raise EnvironmentError(msg)
        elif _IF_ENV_MISS == 'warn':
            warnings.warn(msg, UserWarning)
        else:
            pass
    vars_.update(_ALL_PARSED)

if __name__ == '__main__':
    if len(sys.argv) == 2 and sys.argv[1] == 'check':
        from pprint import pprint
        _parse(dir(), vars())
        pprint(_ALL_PARSED)
        raise SystemExit(0)

    # generate template content for .env file
    print('# See env_settings.py for more details about env variables.')
    for _var in dir():
        if _var.isupper() and not _var.startswith('_'):
            print('{3}{0}={1}{2}{1}'.format(
                _var, _QUOTE_SIGN, str(eval(_var)),
                'export ' if _USE_PREFIX_EXPORT else ''))
else:
    # source and check variables from .env file
    _parse(dir(), vars())


from matplotlib import pyplot
import csv
import pandas as pd
import numpy as np

data = pd.read_csv(r'F:\\GitHub\\MAS_PROJECT\\01_DATA\\D01_Population\\02_International Migrants and Refugees.csv')
df = pd.DataFrame(data, columns=['CODE','NAME','YEAR','SERIES','VALUE'])

def question_a():
    continents = ['Europe', 'Asia', 'Africa', 'Oceania', 'Northern America', 'South America']
    condition = ['International migrant stock: Both sexes (% total population)']
    result = df.loc[df['YEAR'] == 2019]
    result_final = result.loc[result['SERIES'].isin(condition)]
    result_final_1 = result_final.loc[result_final['NAME'].isin(continents)]

    graph_name = result_final_1['NAME']
    graph_value = result_final_1['VALUE']

    pyplot.plot(graph_name,graph_value,color='green')
    pyplot.xticks(rotation = 45)
    pyplot.legend(['Both sexs'])
    pyplot.ylim(0,40)

    pyplot.show()
    pyplot.savefig('F:\\GitHub\\MAS_PROJECT\\03_RESULT\\R01_Population\\02_InternationalMigrants_and_Refugees\\question_a.png')

def question_b():
    code_condition = [ 9, 155, 39, 154, 151, 150, 145, 34, 35, 30, 143, 142, 5,13, 29, 419, 21, 11,18,17,14,202,15,2]
    condition = ['International migrant stock: Both sexes (% total population)']
    result = df.loc[df['YEAR'] == 2019]
    result_final = result.loc[result['SERIES'].isin(condition)]
    show_result = result_final.sort_values(by='VALUE', ascending=False)
    #Chưa thế tìm ra cách để tên chéo như trong Docs mà BA yêu cầu
    graph_name = show_result['NAME'].head(10)
    graph_value = show_result['VALUE'].head(10)
    #Nếu present sử dụng Pycharm thì đạt lại size để có thể có output rõ hơn
    #pyplot.figure(figsize=(14.00, 8.0))
    pyplot.plot(graph_name,graph_value)
    pyplot.xlabel("Name")
    pyplot.ylabel("Value")
    pyplot.xticks(rotation=45)
    pyplot.show()

    pyplot.savefig('F:\\GitHub\\MAS_PROJECT\\03_RESULT\\R01_Population\\02_InternationalMigrants_and_Refugees\\question_b.png')

def question_c():

    year = [2005, 2010, 2015, 2019]

    male = ['International migrant stock: Male (% total Population)']
    female = ['International migrant stock: Female (% total Population)']

    result = df.loc[df['CODE'] == 704]
    male_graph = result.loc[result['SERIES'].isin(male)]
    female_graph = result.loc[result['SERIES'].isin(female)]

    male_value = male_graph['VALUE']
    female_value = female_graph['VALUE']

    #pyplot.figure(figsize=(1920,1080))
    pyplot.xticks(year)
    pyplot.plot(year,male_value , color = 'blue')
    pyplot.plot(year,female_value , color = 'red')
    pyplot.xlabel("Year")
    pyplot.ylabel("Value")
    pyplot.ylim(0,0.2)
    pyplot.savefig('F:\\GitHub\\MAS_PROJECT\\03_RESULT\\R01_Population\\02_InternationalMigrants_and_Refugees\\question_c.png')

    pyplot.show()

question_a()


def mirror_int(n):
    n = str(n)
    return int(n[::-1])

count = 0
for i in range(1000000):
    base_10_mirror = mirror_int(i)
    base_2 = format(i, 'b')
    base_2_mirror = mirror_int(base_2)
    if int(base_2) == base_2_mirror and i == base_10_mirror:
        count += i

print(count)


"""Add a Text Note to Legend Components.
author: Konstantin (https://github.com/nodatasheet)
"""

from pyrevit import DB, UI, forms, revit, script
from legend_utils import LegendComponent

def get_first_text_style():
    # type: () -> DB.TextNoteType
    """Gets first found Text Note Type in current document"""
    first_text_style = DB.FilteredElementCollector(doc)\
        .OfClass(DB.TextNoteType)\
        .FirstElement()
    if first_text_style is not None:
        return first_text_style

app = revit.HOST_APP.app
doc = revit.doc  # type: DB.Document
uidoc = revit.uidoc  # type: UI.Document
uiapp = revit.HOST_APP.uiapp
selection = revit.get_selection()
config = script.get_config()

legcomp_sources = [elem for elem in selection.elements
                   if LegendComponent.is_of_legcomp_cat(elem)]

text_note_offset_value = 500 / 304.5

if legcomp_sources:
    ask_use_selection = forms.alert(
        'Use currently selected Legend Components?',
        cancel=True)
    if not ask_use_selection:
        legcomp_sources = []

if not legcomp_sources:
    legcomp_cat = LegendComponent.get_legcomp_cat(doc)
    if legcomp_cat:
        pick_message = 'Select Legend Components and press "Finish"'
        with forms.WarningBar(title=pick_message):
            picked_elems = revit.pick_elements_by_category(legcomp_cat)
            if picked_elems:
                legcomp_sources = picked_elems
                selection.clear()
    else:
        forms.alert('There is no Legend Components in this Project')

common_param_names = set()
legcomps = []  # type: list[LegendComponent]

if legcomp_sources:
    for lg in legcomp_sources:
        legcomp = LegendComponent(lg)
        legcomps.append(legcomp)
        param_names = legcomp.wrapped_type.param_names
        if common_param_names:
            common_param_names.intersection_update(param_names)
        else:
            common_param_names.update(param_names)

picked_param = None
if legcomp_sources and common_param_names:
    switch_opt_1 = 'Disable units (otherwise same as in Units settings)'
    ask_pick_param = forms.CommandSwitchWindow.show(
        sorted(common_param_names),
        message='Pick Parameter which value will be used in Text Note',
        switches=[switch_opt_1],
        config={switch_opt_1: {'background': '#7997f7'}}
    )
    if ask_pick_param:
        picked_param = ask_pick_param[0]

with revit.Transaction('Add Text to Legend Components'):
    if picked_param:
        text_note_opts = DB.TextNoteOptions()
        text_note_opts.TypeId = get_first_text_style().Id
        text_note_opts.HorizontalAlignment = DB.HorizontalTextAlignment.Center
        for legcomp in legcomps:
            param = legcomp.wrapped_type.lookup_wrapped_param(picked_param)
            if ask_pick_param[1][switch_opt_1]:
                param_value = param.get_value_as_unitless_string(doc)
            else:
                param_value = param.get_value_as_string()

            if param_value is not None and len(param_value) > 0:
                legcomp_bottom = legcomp.location \
                    - DB.XYZ(0, legcomp.height / 2, 0)
                text_note = DB.TextNote.Create(
                    doc,
                    legcomp.owner_view_id,
                    legcomp_bottom - DB.XYZ(0, text_note_offset_value, 0),
                    param_value,
                    text_note_opts
                )


from random import randint

scores = {"Computer": 0, "Player": 0}

class Game_board:
    """
    Main Game board class. Sets board sise, number of ships,
    the players name and board type
    has methos for printing board, guesses,
    adding shhips and checking all ships have sunk.
    """
    def __init__(self, size, num_ships, name, type):
        self.size = size
        self.board = [["." for x in range(size)] for y in range(size)]
        self.num_ships = num_ships
        self.name = name
        self.type = type
        self.ships = []
        self.guesses = []

    def print(self):
        for row in self.board:
            print(" ".join(row))

    def guess(self, x, y):
        self.guesses.append((x, y))
        self.board[x][y] = "x"

        if (x, y) in self.ships:
            self.board[x][y] = "*"
            return "Hit!"

        else:
            return "Miss!"

    def add_ship(self, x, y, type="computer"):
        if len(self.ships) >= self.num_ships:
            print("Error: you cannot add any more ships!")
        else:
            self.ships.append((x, y))
            if self.type == "Player":
                self.board[x][y] = "@"

    def all_ships_sunk(self):
        return all(ship in self.guesses for ship in self.ships)

def random_point(board):
    """
    helper function to randomise cords on the game board
    """
    x = randint(0, board.size - 1)
    y = randint(0, board.size - 1)
    return (x, y)

def populate_board(board):
    """
    function to place ships at random points on the board
    """
    while len(board.ships) < board.num_ships:
        x, y = random_point(board)
        board.add_ship(x, y)

def valid_coordinates(board, row, col):
    """
    function to check if coordinates are within the game board
    and have not been already guessed.
    """
    if (row, col) not in board.guesses:
        global result
        result = board.guess(row, col)
        if result == "Hit!":
            print(result)
            return True
        else:
            print(result)
            return False
    elif (row, col) in board.guesses:
        print(f"You have alredy guessed {row} and {col}!")
        make_guess(board)
    return result

def make_guess(board):
    """
    function to guess ship coords if the board
    is a computer board asks for user input
    else picks random point on board
    """
    add_score = False

    if board.type == "Computer":
        while True:
            try:
                row, col = int(input("Enter Row: ")), int(input("Enter Colum: "))
                if row > (board.size - 1) or col > (board.size - 1):
                    raise ValueError
                break
            except ValueError:
                print(f"Invalid Input. Please enter number in the rage of 0 to {board.size - 1}.")

    elif board.type == "Player":
        row, col = random_point(board)
    if valid_coordinates(board, row, col):
        add_score = True
    return add_score

def play_game(computer_board, player_board):
    """
    function to handle game flow or loop handles playing turn
    and prints info to show whats happening and
    handles win condition
    """
    while True:

        print(f"{player_board.name}'s Board")
        player_board.print()
        print("_" * 60)
        print(f"{computer_board.name}'s Board")
        computer_board.print()

        print(f"{player_board.name}'s turn")
        print("_" * 60)
        if make_guess(computer_board):
            scores["Player"] += 1
        if computer_board.all_ships_sunk():
            print(f"{player_board.name} Wins!!")
            print("Final Scores:")
            print("Player:", scores["Player"], "Computer:", scores["Computer"])
            game_start()

        print("_" * 60)
        print(f"{computer_board.name}'s turn")
        print("_" * 60)
        if make_guess(player_board):
            scores["Computer"] += 1
        if player_board.all_ships_sunk():
            print(f"{computer_board.name} Wins!!")
            print("Final Scores:")
            print("Player:", scores["Player"], "Computer:", scores["Computer"])
            game_start()

        print("_" * 60)
        print("Scores:")
        print(f"{player_board.name}", scores["Player"])
        print(f"{computer_board.name}", scores["Computer"])

def game_start():
    """
    function to handle game setup and start game with welcome message.
    """
    size = 5
    num_ships = 3
    scores["computer"] = 0
    scores["player"] = 0
    print("_" * 60)
    print("Welcome to BattleShips")
    print(f"Board Size: {size}. Number of ships: {num_ships}")
    print(" Top left corner is row: 0, col: 0")
    print("_" * 60)
    player_name = input("Please enter your name:\n")
    print("_" * 60)

    computer_board = Game_board(size, num_ships, "Computer", type="Computer")
    player_board = Game_board(size, num_ships, player_name, type="Player")

    for _ in range(num_ships):
        populate_board(player_board)
        populate_board(computer_board)
    play_game(computer_board, player_board)

game_start()


from flask import Flask, request, make_response, redirect, abort
from flask.ext.script import Manager

app = Flask(__name__)
manager = Manager(app)

@app.route('/')
def index():
    user_agent = request.headers.get('User-Agent')
    response = make_response('
This document carries a cookie!
')
    response.set_cookie('answer', '42')
    return response

@app.route('/redir')
def redir():
    return redirect('http://www.google.com')

@app.route('/user/<name>')
def user(name):
    return '
Hello, %s!
' % name

@app.route('/num/<int:id>')
def num(id):
    user = load_user(id)
    # if not suer:
    #     abort(404)
    return '
Your id is %d
' % id

if(__name__) == '__main__':
    manager.run()


import sys

mdFileName = sys.argv[1]
balScriptName = mdFileName.strip().split(".")[0] + ".bal"

mdFilePath = 'components/home-page/bal-action/action-bbe/' + mdFileName

with open(mdFilePath, 'r') as md:
    md_content = md.readlines()

action_bbe = open(balScriptName , 'a')
for line in md_content:
    if "```" not in line:
        action_bbe.write(line)
action_bbe.close()


# -*- coding: utf-8 -*-
"""
Created on Mon Nov 23 09:13:04 2020

@author: Collabcap
"""

import os
ma_pos=os.getcwd()
output_path = os.path.join(ma_pos,"json")

import pymongo
from pymongo import MongoClient

import json
import numpy as np
import pandas as pd

import swifter

import argparse

import codecs
import re

import unicodedata

from stop_words import get_stop_words

import warnings
warnings.simplefilter('ignore', UserWarning)

import time

import logging
logging.basicConfig(format='%(asctime)s %(levelname)s:%(message)s', level=logging.INFO, datefmt='%m/%d/%Y %I:%M:%S %p')

#####################"

from multiprocessing import Pool, current_process

########################################"

DF = pd.ExcelFile( "list_mot_niv5.xlsx" )
tab_naf_code = pd.read_csv( "naf2008_5_niveaux.csv")

list_code_naf_niv5 = tab_naf_code.NIV5.str.replace(".","").tolist()
tab_naf_code["NIV5"] = list_code_naf_niv5
tab_naf_code["niveau5"] = list_code_naf_niv5
tab_naf_code["niveau4"] = tab_naf_code.niveau5.apply(lambda x : x[0:4])
tab_naf_code["niveau3"] = tab_naf_code.niveau5.apply(lambda x : x[0:3])
tab_naf_code["niveau2"] = tab_naf_code.niveau5.apply(lambda x : x[0:2])

###################################"

#writer = pd.ExcelWriter( "list_mot_niv4.xlsx" , engine='xlsxwriter')

writer = pd.ExcelWriter( "list_mot_niv4.xlsx" , engine='xlsxwriter')
print("niveau 4")

print(tab_naf_code.loc[0] )
list_etudie = tab_naf_code["niveau4"].unique().tolist()

for niv4 in list_etudie :
    logging.info(niv4)
    DF_temp = pd.DataFrame(None,columns = ["word","occurence"])
    list_niveau5 = tab_naf_code[ tab_naf_code.niveau4 == niv4]["niveau5"].tolist()
    for niv5 in list_niveau5 :
        temp = DF.parse( niv5 )
        DF_temp = DF_temp.append(temp )
    DF_excel = DF_temp.groupby( [ "word"] ).sum()
    DF_excel = DF_excel.sort_values(by = ['occurence'], ascending=False )
    DF_excel.to_excel(writer, sheet_name= niv4 , index = True)
    for column in DF_excel:
                column_length = max(DF_excel[column].astype(str).map(len).max(), len(column)) #ajusté a la plus grande cellue
                col_idx = DF_excel.columns.get_loc(column)
                writer.sheets[ niv4 ].set_column(col_idx, col_idx, min(column_length,30) )
writer.save()

writer = pd.ExcelWriter( "list_mot_niv3.xlsx" , engine='xlsxwriter')
print("niveau 3")

list_etudie = tab_naf_code["niveau3"].unique().tolist()

for niv3 in list_etudie :
    logging.info(niv3)
    DF_temp = pd.DataFrame(None,columns = ["word","occurence"])
    list_niveau5 = tab_naf_code[ tab_naf_code.niveau3 == niv3]["niveau5"].tolist()
    for niv5 in list_niveau5 :
        temp = DF.parse( niv5 )
        DF_temp = DF_temp.append(temp )
    DF_excel = DF_temp.groupby( [ "word"] ).sum()
    DF_excel = DF_excel.sort_values(by = ['occurence'], ascending=False )
    DF_excel.to_excel(writer, sheet_name= niv3 , index = True)
    for column in DF_excel:
                column_length = max(DF_excel[column].astype(str).map(len).max(), len(column)) #ajusté a la plus grande cellue
                col_idx = DF_excel.columns.get_loc(column)
                writer.sheets[ niv3 ].set_column(col_idx, col_idx, min(column_length,30) )
writer.save()

writer = pd.ExcelWriter( "list_mot_niv2.xlsx" , engine='xlsxwriter')

print("niveau 2")

list_etudie = tab_naf_code["niveau2"].unique().tolist()

for niv2 in list_etudie :
    logging.info(niv3)
    DF_temp = pd.DataFrame(None,columns = ["word","occurence"])
    list_niveau5 = tab_naf_code[ tab_naf_code.niveau2 == niv2]["niveau5"].tolist()
    for niv5 in list_niveau5 :
        temp = DF.parse( niv5 )
        DF_temp = DF_temp.append(temp )
    DF_excel = DF_temp.groupby( [ "word"] ).sum()
    DF_excel = DF_excel.sort_values(by = ['occurence'], ascending=False )
    DF_excel.to_excel(writer, sheet_name= niv2 , index = True)
    for column in DF_excel:
                column_length = max(DF_excel[column].astype(str).map(len).max(), len(column)) #ajusté a la plus grande cellue
                col_idx = DF_excel.columns.get_loc(column)
                writer.sheets[ niv2 ].set_column(col_idx, col_idx, min(column_length,30) )
writer.save()


import re
import pickle

from collections import defaultdict, Counter
from nltk.corpus import stopwords
from nltk.tokenize import word_tokenize, sent_tokenize
import pandas as pd
from sklearn import preprocessing
from fkscore import fkscore
import numpy as np

'''
Interaction Dynamics utils
'''
# refined_sample = pickle.load(open('samples/interaction_dynamics_sample.pkl', mode='rb'))

# returns all comment authors that received a delta
def deltas(submission):
    delta_authors = []
    id_map = {}
    for comment in submission['comments']:
        if 'author' in comment.keys():
            id_map[comment['id']] = comment['author']
            if comment['author'] == 'DeltaBot':
                author = re.search(r"(?<=\/u\/).+(?=\.)", comment['body'])
                if author is not None:
                    delta_authors.append(author.group(0))
    return delta_authors

# sorts all comments in a submission by creation time
def sort_comments(submission):
    comments = []
    for comment in submission['comments']:
        if 'created' in comment.keys() and 'author' in comment.keys():
            comments.append(comment)
    return sorted(comments, key= lambda comment: comment['created'])

# counts the number of comments made by each challenger
def num_author_comments(submission):
    id_map = {}
    op = submission['author']
    for comment in submission['comments']:
        if 'author' in comment.keys():
            id_map[comment['id']] = comment['author']
    author_comment_map = defaultdict(int)
    for comment in submission['comments']:
        if 'author' in comment.keys():
            if comment['author'] not in ['DeltaBot', op]:
                author_comment_map[comment['author']] += 1
    return author_comment_map

# counts the length of back-and-forths between challenger and op
def op_challenger_chain_counts(submission):
    id_map = {}
    op = submission['author']
    for comment in submission['comments']:
        if 'author' in comment.keys():
            id_map[comment['id']] = comment['author']
    op_chal_chains = defaultdict(int)
    for comment in submission['comments']:
        if 'author' in comment.keys() and comment['replies']:
            for reply_id in comment['replies']['data']['children']:
                if reply_id in id_map.keys():
                    if id_map[reply_id] == op:
                        op_chal_chains[comment['author']] += 1
                    elif comment['author'] == op:
                        op_chal_chains[id_map[reply_id]] += 1
    return op_chal_chains

'''
Language Indicator utils
'''
stop_words = set(stopwords.words('english'))

# simple implementation of jaccard score and other measures for two lists
def jaccard(A, O):
    set1 = set(A)
    set2 = set(O)
    return len(set1.intersection(set2))/len(set1.union(set2))

def common_words(A, O):
    return len(set(A).intersection(set(O)))

def reply_fraction(A, O):
    set1 = set(A)
    set2 = set(O)
    return len(set1.intersection(set2))/len(set1)

def op_fraction(A, O):
    set1 = set(A)
    set2 = set(O)
    return len(set1.intersection(set2))/len(set2)

# tokenizing and cleaning of comments text, replacing quotes and links with special tokens
def tokenize(comment):
    comment = comment.replace('>', 'QUOTE')
    comment = re.sub(r'http\S+', 'LINK', comment)
    comment = comment.replace('(LINK', 'LINK')
    tokens = word_tokenize(comment)
    return tokens
# identity function (just return)
def id(obj):
    return obj
# function to remove stop words from tokenized
def remove_stop_words(tokens):
    return [word for word in tokens if word.lower() not in stop_words]
# function to only retrieve the stopw ords from tokenized
def only_stop_words(tokens):
    return [word for word in tokens if word.lower() in stop_words]
# separate a root-path unit into root reply and full path
def separate(rooted_path_unit):
    return rooted_path_unit['comments'][0]['body'], '\n\n'.join([comment['body'] for comment in rooted_path_unit['comments']])

interplay_features = ['# common ', 'jaccard ', 'op frac ', 'reply frac ']
interplay_bases = ['all', 'content', 'stop']
interplay_cols = []
for feature in interplay_features:
    for base in interplay_bases:
        interplay_cols.append(feature + base)
INTERPLAY_COLS = interplay_cols

# load VAD and concreteness csv as pd, keep the mean columns for each word
CONCRETENESS = pd.read_csv('docs/concreteness.csv')[['Word', 'Rating.Mean']]
VAD = pd.read_csv('docs/VAD.csv')[['Word', 'V.Mean.Sum', 'A.Mean.Sum', 'D.Mean.Sum']]

ARG_COLS = ['# indefinite articles', '# definite articles', '# 1st person pronouns', '# 1st person plural pronouns',
            '# 2nd person pronouns', '# of links', '# of quotes', '# questions',
            'V', 'A', 'D', 'C',
            '# of sentences', '# of paragraphs', 'Flesch-Kincaid Readability']

def word_count(tokens):
    return len([w for w in tokens if w.isalnum()])

# return info for word category-based features in tokenized
def word_category_info(tokens):
    quote_link_counter = Counter(tokens)
    num_links = quote_link_counter['LINK']
    num_quotes = quote_link_counter['QUOTE']
    lowered = [token.lower() for token in tokens]
    counter = Counter(lowered)
    features_map = {'# indefinite articles':['a', 'an'], '# definite articles': ['the'], '# 1st person pronouns': ['i', 'me', 'my', 'mine', 'myself'],
                    '# 1st person plural pronouns': ['us', 'we', 'ours', 'ourselves', 'our'],
                    '# 2nd person pronouns': ['you', 'your', 'yours', 'yourself', 'yourselves'], '# questions': ['?']}

    count_map = {feature:sum([counter[token] for token in value]) for feature, value in features_map.items()}
    count_map['# of links'] = num_links
    count_map['# of quotes'] = num_quotes
    return count_map

# returns average V,A,D,C for content words in tokenized passage
def word_score_info(tokens):
    results = {feature:0.0 for feature in ['V', 'A', 'D','C']}
    tokens = remove_stop_words(tokens)
    lowered_tokens = [token.lower() for token in tokens]
    new_length = word_count(lowered_tokens)
    for token in lowered_tokens:
        if token in VAD['Word'].values:
            results['V'] += VAD.loc[VAD['Word'] == token, 'V.Mean.Sum'].item()
            results['A'] += VAD.loc[VAD['Word'] == token, 'A.Mean.Sum'].item()
            results['D'] += VAD.loc[VAD['Word'] == token, 'D.Mean.Sum'].item()
        if token in CONCRETENESS['Word'].values:
            results['C'] += CONCRETENESS.loc[CONCRETENESS['Word'] == token, 'Rating.Mean'].item()
    return {key:value/new_length for key, value in results.items()}

def num_sentences(text):
    return len(sent_tokenize(text))

def num_paragraphs(text):
    return len(text.split('\n\n'))

def flesch_kincaid_score(text):
    return fkscore(text).score['readability']

# entire text information for comments
def entire_text_features(text):
    results = {}
    results['# of sentences'] = num_sentences(text)
    results['# of paragraphs'] = num_paragraphs(text)
    results['Flesch-Kincaid Readability'] = flesch_kincaid_score(text)
    return results

def quarters(text):
    tokens = tokenize(text)
    return [list(array) for array in np.array_split(tokens, 4)]

# Persuaion utils

# CMV posts insert a footer at the end of the post, remove it and add title to the body of post
def remove_footer(submission):
    lines = [line for line in submission['selftext'].splitlines()
             if not line.lstrip().startswith('>') and not line.lstrip().startswith('_____')
             and "edit" not in " ".join(line.lower().split())
            ]
    return submission['title'] + "\n\n" + "\n".join(lines)

def remove_CMV(text):
    return text.replace('CMV:', '', 1)


import numpy as np
def sigmoid(Z):
    A = 1/(1+np.exp(-Z))
    cache = Z
    return A, cache

def dSigmoid(dA, cache):
    Z = cache
    s = 1/(1+np.exp(-Z))
    dZ = dA * s * (1-s)
    assert (dZ.shape == Z.shape)
    return dZ

def ReLU(Z):
    A = np.maximum(0,Z)
    assert(A.shape == Z.shape)
    cache = Z
    return A, cache
def dReLU(dA, cache):
    Z = cache
    dZ = np.array(dA, copy=True)
    dZ[Z <= 0] = 0
    assert (dZ.shape == Z.shape)
    return dZ

def softmax(Z):
    e_Z = np.exp(Z - np.max(Z,  axis=0))
    A = e_Z / e_Z.sum(axis = 0)
    return A, Z


from collections import defaultdict

listOflists=[['a', 'b'], ['a', 'c']]

inv_indx = defaultdict(list)
for idx, text in enumerate(listOflists):
    for word in text:
        inv_indx[word].append(idx)

print(inv_indx.keys(),inv_indx.values())


#  -*-  coding: utf-8  -*-
class Solution:
    def maxArea(self, height) -> int:
        left_i = 0
        left_v = -1

        n = len(height)
        max_area = 0

        while left_i < n:
            if height[left_i] <= left_v:
                left_i += 1
                continue
            left_v = height[left_i]
            # find the max right bound
            right_i = n - 1
            right_v = -1
            while right_i >= 0:
                if height[right_i] <= right_v:
                    right_i -= 1
                    continue
                area = min(height[right_i], left_v) * (right_i - left_i)
                max_area = max(area, max_area)
                if height[right_i] >= left_v:
                    break

                right_v = height[right_i]
                right_i -= 1
            left_i += 1

        return max_area


class Solution:
    def toLowerCase(self, s: str) -> str:
        newStr = ""
        for char in s:
            # If char is ASCII Upper
            if ord(char) >= 65 and ord(char) <= 90:
                newStr += chr(ord(char) + 32)

            else:
                newStr += char

        return newStr


import spacy
import tkinter as tk

class Redactor(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Text Redactor")

        self.entry = tk.Text(self, width=50, height=10, wrap="word")
        self.entry.pack(pady=20)

        self.redact_button = tk.Button(self, text="Redact", command=self.redact_text)
        self.redact_button.pack()

        options = tk.Frame(self)
        self.variables = {}
        entities = [
            "PERSON", "NORP", "FAC", "ORG", "GPE", "LOC", "PRODUCT", "EVENT", "WORK_OF_ART",
            "LAW", "LANGUAGE", "DATE", "TIME", "PERCENT", "MONEY", "QUANTITY", "ORDINAL", "CARDINAL"]

        cols = 4

        for i, entity in enumerate(entities):
            # Create a BooleanVar for each entity
            self.variables[entity] = tk.BooleanVar()

            # Create a Checkbutton for each entity, positioned in a grid
            tk.Checkbutton(options, text=entity, variable=self.variables[entity]).grid(row=i // cols, column=i % cols)  # This will distribute the buttons in a grid layout

        self.variable_all = tk.BooleanVar()
        tk.Checkbutton(options, text="All", command=self.trigger_all, variable=self.variable_all)
        options.pack()

        self.result_label = tk.Label(self, text="Redacted Text will appear here.", wraplength=500)
        self.result_label.pack(pady=20)

    def trigger_all(self):
        value = self.variable_all.get()
        print(value)
        for entity, var in self.variables.items():
            var.set(value)

    def redact_text(self):
        text = self.entry.get("1.0", "end-1c")
        redacted_text, unredacted_items = self.redact_names(text)
        self.result_label['text'] = redacted_text
        with open('log.txt', 'w+') as f:
            f.write("Potential Classifications Errors:\n")
            for line in unredacted_items:
                f.write(line + "\n")

            f.write("In Text:\n")
            f.write(redacted_text)

    def redact_names(self, text):
        nlp = spacy.load("en_core_web_sm")
        doc = nlp(text)
        redacted_sentence = text
        unredacted_items = []
        for ent in doc.ents:
            if self.variables[ent.label_].get():
                redacted_sentence = redacted_sentence.replace(ent.text, '[REDACTED]')
            else:
                unredacted_items.append(ent.text)
        print()
        return redacted_sentence, unredacted_items

if __name__ == "__main__":
    redactor_app = Redactor()
    redactor_app.mainloop()


import pandas as pd
from matplotlib import pyplot as plt

plt.style.use('fivethirtyeight')

data = pd.read_csv('sodataage.csv')
ids = data['Respondent']
ages = data['Age']

bins = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]

plt.hist(ages, bins=bins, edgecolor='black', log=True)

median_age = 29
color = '#e5ae37'

plt.axvline(median_age, color=color, label='Median Age', linewidth=2.5)       # 'plt.axvline' stands for 'access vertical line'

plt.legend()

plt.xlabel('Ages')
plt.ylabel('Total Respondent')
plt.title('Respondent Ages')

plt.tight_layout()
plt.show()


def datoValidoRep(plantilla):
    dato = ''
    while dato == '':
        try:
            dato = int(input(plantilla))
        except ValueError:
            dato = ''
    return dato

mes = datoValidoRep('Ingresa el numero de mes: ')

if mes == 1:
    strmes = 'Enero'
elif mes == 2:
    strmes = 'Febrero'
elif mes == 3:
    strmes = 'Marzo'
elif mes == 4:
    strmes = 'Abril'
elif mes == 5:
    strmes = 'Mayo'
elif mes == 6:
    strmes = 'Junio'
elif mes == 7:
    strmes = 'Julio'
elif mes == 8:
    strmes = 'Agosto'
elif mes == 9:
    strmes = 'Septiembre'
elif mes == 10:
    strmes = 'Octubre'
elif mes == 11:
    strmes = 'Noviembre'
elif mes == 12:
    strmes = 'Diciembre'

print(' El mes {} es {}'.format(mes,strmes))


#!/usr/bin/python3
"""Write csv file where rows from an input file matching specified criteria are split into multiple rows based on rows
and matching criteria in another input file.

Sometimes you need to clarify the details of a particular transaction using data from another source.

The script takes one required argument:
filter=Path to a csv file containing the columns: matching column a, matching regex a, comparison column a, comparison
column b, destination column(s) a, source column(s) b
split_source=Path to a csv file with data to use for performing split operation.

The script takes the following optional arguments:
input=Path to a csv file containing the designated input columns.
output=Path to write the output csv file. This file will be overwritten without warning if it exists.
"""
import csv
import argparse
import re
import sys
from copy import deepcopy

author = 'brian.k.smith@gmail.com'

parser = argparse.ArgumentParser(description='Split rows where a column matches a regex based on values in'
                                             ' second input.')
parser.add_argument('filter', help='Path to csv filter file with columns: matching column a, matching regex a,'
                                   'comparison column a, comparison column b, '
                                   'destination columns a (semicolon separated list), '
                                   'source columns b (semicolon separated list, order matching destinations),'
                                   'currency column a (column where the split values should add up to original)')
parser.add_argument('split', help='Secondary input file that contains data to use to split rows in primary.')
parser.add_argument('--add_imbalance', help='Correct for differences between actual and expected currency by adding an'
                                            'imbalance transaction.', action='store_true')
parser.add_argument('--input', help='Path to csv input file with column(s) to examine.'
                                    ' Defaults to stdin.')
parser.add_argument('--output', help='Path to csv output file. This file will be overwritten if it exists. Defaults'
                                     ' to stdout.')

args = parser.parse_args()

currency_regex = re.compile('\$?\s*(-?\d+\.\d+)')

# Take care of any default setup needed
close_input = True
if args.input is None:
    close_input = False
    args.input = 0
close_output = True
if args.output is None:
    close_output = False
    args.output = 1

# Open required files
# noinspection PyTypeChecker
with open(args.input, newline='', encoding='UTF-8', closefd=close_input) as input_file,\
        open(args.split, newline='') as split_file,\
        open(args.filter, newline='') as filter_file,\
        open(args.output, mode='w', newline='', closefd=close_output) as output_file:
    in_reader = csv.reader(input_file)
    filter_reader = csv.reader(filter_file, )
    split_reader = csv.reader(split_file)
    out_writer = csv.writer(output_file)
    # Set up filters map
    filters = []
    filter_headers = next(filter_reader)
    for filter_row in filter_reader:
        filt = {"a_match_col": int(filter_row[0]),
                "a_match_regex": re.compile(filter_row[1]),
                "a_comp_col": int(filter_row[2]),
                "b_comp_col": int(filter_row[3]),
                "a_dest_col": list(map(int, filter_row[4].split(';'))),
                "b_source_col": list(map(int, filter_row[5].split(';'))),
                "a_currency_col": int(filter_row[6])}
        filters.append(filt)
    # Set up split data map. Index by comparison column: list of lists containing the values from all of the
    # file B source columns
    split_data = {}
    split_headers = next(split_reader)
    for row in split_reader:
        for filt in filters:
            if row[filt["b_comp_col"]]:
                if row[filt["b_comp_col"]] not in split_data:
                    split_data[row[filt["b_comp_col"]]] = []
                data_list = []
                for col in filt["b_source_col"]:
                    data_list.append(row[col])
                split_data[row[filt["b_comp_col"]]].append(data_list)
    # Set up output file with input headers
    output_headers = next(in_reader)
    out_writer.writerow(output_headers)
    # Iterate through input
    row_count = 0
    for row in in_reader:
        row_count += 1
        out_row = deepcopy(row)
        row_split = False
        for filt in filters:
            match = filt["a_match_regex"].search(row[filt["a_match_col"]])
            if match:
                original_currency = float(row[filt["a_currency_col"]])
                split_currency = 0.0
                for key in split_data:
                    if row[filt["a_comp_col"]] == key:
                        for d_list in split_data[key]:
                            split_row = deepcopy(out_row)
                            col_count = 0
                            while col_count < len(filt["a_dest_col"]):
                                dest_col = filt["a_dest_col"][col_count]
                                if dest_col == filt["a_currency_col"]:
                                    match = currency_regex.match(d_list[col_count])
                                    split_string = match.group(1)
                                    split_row[dest_col] = split_string
                                    split_currency += float(split_string)
                                else:
                                    split_row[dest_col] = d_list[col_count]
                                col_count += 1
                            out_writer.writerow(split_row)
                            row_split = True
                if row_split and abs(original_currency - split_currency) > 0.001:
                    if args.add_imbalance:
                        imba_row = deepcopy(out_row)
                        col_count = 0
                        while col_count < len(filt["a_dest_col"]):
                            dest_col = filt["a_dest_col"][col_count]
                            if dest_col == filt["a_currency_col"]:
                                imba = original_currency - split_currency
                                split_row[dest_col] = "{:0.2f}".format(imba)
                            else:
                                split_row[dest_col] = "IMBALANCE"
                            col_count += 1
                        out_writer.writerow(split_row)
                    else:
                        print("ERROR: Sum of currency in split rows (${:.2f}) does not equal starting currency"
                              "(${:.2f}) at row {:d} ({})!"
                              .format(split_currency, original_currency, row_count, ",".join(row)), file=sys.stderr)
        if not row_split:
            out_writer.writerow(out_row)


"""
models.py
Contains models for the coinex API
"""

from decimal import *
import coinex_api
from datetime import datetime

# set the decimal precision to 8
getcontext().prec = 8

class Balance:
    """
    A container for a balance of a given currency
    Attributes:
        currency: the Currency
        amount: a Decimal, the amount of currency
    Balance.get_own() : get a list of all own balances
    """

    next_id = 0

    def __init__(self, currency, amount, held=Decimal(0)):
        """
        Create a new Balance object.
        currency: either a currency object or an id
        amount: the amount, either a numeric or a string that parses to numeric
        held: an optional Decimal of how much is being held
        """
        self.held = Decimal(held)
        self.id = Balance.next_id
        Balance.next_id += 1
        if isinstance(currency, int):
            cur = Currency.get(currency)
            if cur is None:
                raise ValueError("currency id was not valid")
            self.currency = cur
        elif isinstance(currency, Currency):
            self.currency = currency
        else:
            raise ValueError(
                "currency was not valid, should be int or Currency"
            )
        self.amount = Decimal(amount)

    def __eq__(self, other):
        return isinstance(other, Balance) and other.id == self.id

    def __ne__(self, other):
        return not self.__eq__(other)

    @classmethod
    def get_own(cls):
        """
        Get all own balances
        """
        bals = coinex_api.balances()
        ret = []
        for bal in bals:
            curr = Currency.get(bal['currency_id'])
            amt = Decimal(bal['amount']) / pow(10, 8)
            held = Decimal(bal['held']) / pow(10, 8)
            b = Balance(curr, amt, held=held)
            ret.append(b)
            registry.put(b)
        return ret

class Currency:
    """
    A container for a currency
    Attributes:
        id: the currency ID
        abbreviation: the short name (ie 'BTC')
        name: the long name (ie 'Bitcoin')
    Currency.get(id_)  : get a currency that corresponds with the given ID
    Currency.get_all() : get all currencies available
    """

    _loaded = False

    def __init__(self, currency_id, abbreviation, name):
        self.id = int(currency_id)
        self.abbreviation = str(abbreviation)
        self.name = str(name)

    def __eq__(self, other):
        return isinstance(other, Currency) and other.id == self.id

    def __ne__(self, other):
        return not (self.__eq__(other))

    @classmethod
    def _refresh(cls):
        """
        Refresh all currencies, reloading from the API
        """
        registry.delete_all(cls)
        curs = coinex_api.currencies()
        for cur in curs:
            curncy = Currency(cur['id'], cur['name'], cur['desc'])
            registry.put(curncy)
        cls._loaded = True

    @classmethod
    def get(cls, id_):
        if not cls._loaded:
            cls._refresh()
        id_ = int(id_)
        return registry.get(Currency, id_)

    @classmethod
    def get_all(cls):
        """
        Returns a generator for all objects
        """
        if not cls._loaded:
            cls._refresh()
        return registry.get_all(Currency)

class Exchange:
    """
    A container for an exchange
    Attributes:
        id: the trade_pair_id
        from_currency: the Currency from which this trades (ie Bitcoin)
        to_currency: the Currency to which this trades (ie Mooncoin)
        get_orders() : get a list of all orders
        get_recent_trades() : get a list of recently executed trades
    Exchange.get(int_): get the Exchange for this ID
    Exchange.get_all(): get all Exchanges available
    """

    _loaded = False

    def __init__(self, trade_pair_id, from_currency, to_currency):
        """
        Construct a new exchange.
        from_currency: the Currency from which this is being transferred,
                       or the id of it
        to_currency: the currency to which this is being transferred,
                     or the id of it
        orders: a list of orders made on this exchange
        """
        self.id = int(trade_pair_id)

        if isinstance(from_currency, int):
            cur = Currency.get(from_currency)
            if cur is None:
                raise ValueError("The from id is invalid")
            self.from_currency = cur
        elif isinstance(from_currency, Currency):
            self.from_currency = from_currency
        else:
            raise ValueError("The from_currency was invalid")

        if isinstance(to_currency, int):
            cur = Currency.get(to_currency)
            if cur is None:
                raise ValueError("The to id is invalid")
        elif isinstance(to_currency, Currency):
            self.to_currency = to_currency
        else:
            raise ValueError("The to_currency was invalid")

    def get_orders(self):
        """
        Load / get all orders for the current exchange
        """
        # remove old ones if needed
        ords = coinex_api.orders(self.id)
        ret = []
        for order in ords:
            o = Order(API_resp=order)
            registry.put(o)
            ret.append(o)
        return ret

    def get_recent_trades(self):
        """
        Load / get all recent trades for this exchange
        """
        ords = coinex_api.last_trades(self.id)
        ret = []
        for order in ords:
            o = Order(API_resp=order)
            registry.put(o)
            ret.append(o)
        return ret

    def get_highest_bid(self):
        """
        Get order of the highest price that someone is bidding
        (willing to buy for)
        """
        ords = self.get_orders()
        ords = [ordr for ordr in ords if ordr.bid is True]
        best = max(ords, key=lambda x: x.rate)
        return best

    def get_lowest_ask(self):
        """
        Get order of the lowest price that someone is asking
        (willing to sell for)
        """
        ords = self.get_orders()
        ords = [ordr for ordr in ords if ordr.bid is False]
        best = min(ords, key=lambda x: x.rate)
        return best

    def get_best_offer(self, target_cur):
        """
        Get the best offer (order) for the given currency.
        NOTE: this may be highest bid or lowest ask
        """
        if target_cur == self.to_currency:
            return self.get_lowest_ask()
        elif target_cur == self.from_currency:
            return self.get_highest_bid()
        raise ValueError(
            'Unsupported currency for this exchange ' +
            target_cur.abbreviation
        )

    @classmethod
    def _refresh(cls):
        """
        Refresh the registry's exchanges
        """
        if (cls._loaded):
            registry.delete_all(Exchange)
        excs = coinex_api.trade_pairs()
        for exc in excs:
            exchange = Exchange(
                exc['id'],
                Currency.get(exc['market_id']),
                Currency.get(exc['currency_id'])
            )
            registry.put(exchange)

        cls._loaded = True

    @classmethod
    def get(cls, id_):
        if not cls._loaded:
            cls._refresh()
        return registry.get(Exchange, id_)

    @classmethod
    def get_all(cls):
        if not cls._loaded:
            cls._refresh()
        return registry.get_all(Exchange)

class Order:
    """
    A container for an order
    Attributes:
        order_id: the order id
        exchange: the Exchange for this order
        bid: true if this is bid(buy), false for ask(sell)
        rate: Decimal rate at from_currency per to_currency
        amount: the amount of this Order
        filled: the amount of this order that has been filled
        cancelled: true if this order is cancelled
        complete: true if this order is completed
    Order.get_own() : get all own orders
    """

    def __init__(self,
                 API_resp=None,
                 order_id=None,
                 exchange=None,
                 bid=None,
                 amount=None,
                 filled=None,
                 cancelled=None,
                 complete=None,
                 rate=None,
                 created_at=None,
                 completed_at=None):
        """
        Construct a new order
        NOTE: either pass the response from coinex_api into API_resp or
        manually add each property
        """
        if API_resp is not None:
            order = API_resp
            self.id = order['id']
            self.exchange = Exchange.get(API_resp['trade_pair_id'])
            self.amount = Decimal(order['amount']) / pow(10, 8)
            self.rate = Decimal(order['rate']) / pow(10, 8)
            self.bid = order['bid']
            # if this is a pending order do this
            if 'filled' in order:
                self.filled = Decimal(order['filled']) / pow(10, 8)
                self.cancelled = order['cancelled']
                self.complete = order['complete']
                self.created_at = datetime.strptime(
                    order['created_at'],
                    '%Y-%m-%dT%H:%M:%S.%fZ'
                )
                self.complete_at = None
            # else this order was already done, has some different keys
            else:
                self.filled = self.amount
                self.cancelled = False
                self.complete = True
                self.created_at = None
                self.completed_at = datetime.strptime(
                    order['created_at'],
                    '%Y-%m-%dT%H:%M:%S.%fZ'
                )
        else:
            self.id = int(order_id)
            self.exchange = exchange
            self.bid = bool(bid)
            self.amount = amount
            self.rate = Decimal(rate)
            self.filled = filled
            self.cancelled = cancelled
            self.complete = complete
            self.created_at = created_at
            self.completed_at = completed_at

    @classmethod
    def get_own(cls):
        """
        Get all own orders
        """
        ords = coinex_api.open_orders()
        ret = []
        for ordr in ords:
            exc = Exchange.get(ordr['trade_pair_id'])
            amt = Decimal(ordr['amount']) / pow(10, 8)
            rate = Decimal(ordr['rate']) / pow(10, 8)
            ret.append(
                Order(
                    API_resp=ordr
                )
            )
        return ret

    def get_compliment(self, transac_fee=Decimal('0.002'), max_amt=None):
        """
        Get the compliment for this order which, when submitted,
        will fulfill the other order.
        """
        amt = (self.amount - self.filled) / Decimal(1 - transac_fee)
        if max_amt is not None:
            amt = min(max_amt, amt)
        other = Order(
            order_id=-1,
            exchange=self.exchange,
            amount=amt,
            bid=not self.bid,
            rate=self.rate
        )
        return other

    def submit(self):
        """
        Submit this order to the coinex api.
        Resets this object's properties to reflect
        the new ones reported by coinex_api, and
        also returns the parsed JSON returned by coinex
        """
        ordr = coinex_api.submit_order(
            trade_pair_id=self.exchange.id,
            amount=self.amount,
            bid=self.bid,
            rate=self.rate
        )
        self.__init__(API_resp=ordr)
        return ordr

class Wallet:
    """
    A container to represent total currency held
    """

    next_id = 0

    def __init__(self):
        self.id = Wallet.next_id
        Wallet.next_id += 1

    @classmethod
    def get_balances(cls):
        return Balance.get_own()

    @classmethod
    def get_orders(cls):
        return Order.get_own()

class Registry:
    """
    Maintains a registry of all models
    """

    def __init__(self):
        self._dct = {}

    def get(self, model, id_):
        """
        Get a model from the registry by ID
        model: the class of model to get
        id_: the id of the model to get
        """
        if model in self._dct and id_ in self._dct[model]:
            return self._dct[model][id_]
        else:
            return None

    def get_all(self, cls):
        """
        returns a list for all the objects in the registry
        """
        ret = []
        dct = self._dct[cls]
        if dct is not None:
            for key in dct:
                ret.append(dct[key])
        return ret

    def put(self, model):
        """
        Put a model into the registry
        """
        cls = model.__class__
        if not (cls in self._dct):
            self._dct[cls] = {}
        self._dct[cls][model.id] = model

    def delete(self, obj, model=None):
        """
        Delete from the registry
        obj: either int, the object's id, or the model itself
        model: if an int supplied, this is the class of the model to delete
        returns the model that was deleted, or null if none was found
        """
        if isinstance(obj, int):
            if model in self._dct:
                if obj in self._dct[model]:
                    ret = self._dct[model][obj]
                    self._dct[model][obj] = None
                    return ret
        else:
            cls = obj.__class__
            if cls in self._dct:
                if obj.id in self._dct[cls]:
                    ret = self._dct[cls][obj.id]
                    self._dct[cls][obj.id] = None
                    return ret
        return None

    def delete_all(self, cls):
        """
        Delete all of a certain class from the registry
        cls: the class to remove
        """
        self._dct[cls] = {}

registry = Registry()


"""
Functions for pruning or expanding the sample space of a distribution.

This can be important when calculating meet and join random variables. It
is also important for the calculations of various PID quantities.
"""

from dit.samplespace import ScalarSampleSpace, SampleSpace, CartesianProduct

__all__ = (
    'expanded_samplespace',
    'pruned_samplespace',
)

def pruned_samplespace(d, sample_space=None):
    """
    Returns a new distribution with pruned sample space.

    The pruning is such that zero probability outcomes are removed.

    Parameters
    ----------
    d : distribution
        The distribution used to create the pruned distribution.

    sample_space : set
        A list of outcomes with zero probability that should be kept in the
        sample space. If `None`, then all outcomes with zero probability
        will be removed.

    Returns
    -------
    pd : distribution
        The distribution with a pruned sample space.

    """
    if sample_space is None:
        sample_space = []

    keep = set(sample_space)
    outcomes = []
    pmf = []
    for o, p in d.zipped(mode='atoms'):
        if not d.ops.is_null_exact(p) or o in keep:
            outcomes.append(o)
            pmf.append(p)

    if d.is_joint():
        sample_space = SampleSpace(outcomes)
    else:
        sample_space = ScalarSampleSpace(outcomes)
    pd = d.__class__(outcomes, pmf,
                     sample_space=sample_space, base=d.get_base())
    return pd

def expanded_samplespace(d, alphabets=None, union=True):
    """
    Returns a new distribution with an expanded sample space.

    Expand the sample space so that it is the Cartesian product of the
    alphabets for each random variable. Note, only the effective alphabet of
    each random variable is used. So if one index in an outcome only has the
    value 1, then its alphabet is `[1]`, and not `[0, 1]` for example.

    Parameters
    ----------
    d : distribution
        The distribution used to create the pruned distribution.

    alphabets : list
        A list of alphabets, with length equal to the outcome length in `d`.
        Each alphabet specifies the alphabet to be used for a single index
        random variable. The sample space of the new distribution will be the
        Cartesian product of these alphabets.

    union : bool
        If True, then the alphabet for each random variable is unioned.
        The unioned alphabet is then used for each random variable.

    Returns
    -------
    ed : distribution
        The distribution with an expanded sample space.

    Notes
    -----
    The default constructor for Distribution will create a Cartesian product
    sample space if not sample space is provided.

    """
    joint = d.is_joint()

    if alphabets is None:
        # Note, we sort the alphabets now, so we are possibly changing the
        # order of the original sample space.
        alphabets = list(map(sorted, d.alphabet))
    elif joint and len(alphabets) != d.outcome_length():
        L = len(alphabets)
        raise Exception("You need to provide {0} alphabets".format(L))

    if joint and union:
        alphabet = set.union(*map(set, alphabets))
        alphabet = sorted(alphabet)
        alphabets = [alphabet] * len(alphabets)

    if joint:
        sample_space = CartesianProduct(alphabets, d._product)
    else:
        sample_space = ScalarSampleSpace(alphabets)

    ed = d.__class__(d.outcomes, d.pmf,
                     sample_space=sample_space, base=d.get_base())
    return ed


from shapely.geometry import Point
import folium

class Roadmap():

    def __init__(self, dataset_str):
        # xypygamexy

        self.dataset_str = dataset_str
        self.map_props = get_map_props()

        self.lower_left = get_map_props()[dataset_str]['lower_left']
        self.upper_right = get_map_props()[dataset_str]['upper_right']

        try:  # movingpandas
            from movingpandas.geometry_utils import measure_distance_geodesic
            self.max_dis_y = measure_distance_geodesic(Point(self.lower_left[0], self.lower_left[1]),
                                                  Point(self.upper_right[0], self.lower_left[1]))
            self.max_dis_x = measure_distance_geodesic(Point(self.lower_left[0], self.lower_left[1]),
                                                  Point(self.lower_left[0], self.upper_right[1]))
            # print(f'max_x = {self.max_dis_x}, max_y = {self.max_dis_y}')
        except:
            # hardcode
            if dataset_str == 'NCSU':
                self.max_dis_y = 3255.4913305859623
                self.max_dis_x = 2718.3945272795013
            elif dataset_str == 'purdue':
                self.max_dis_y = 1671.8995666382975
                self.max_dis_x = 1221.4710883988212
            elif dataset_str == 'KAIST':
                self.max_dis_y = 2100.207579392558
                self.max_dis_x = 2174.930950809533

    def lonlat2pygamexy(self, lon, lat):
        '''
        pygamexy.
        yx
        np.array
        '''

        x = - self.max_dis_x * (lat - self.upper_right[1]) / (self.upper_right[1] - self.lower_left[1])
        y = self.max_dis_y * (lon - self.lower_left[0]) / (self.upper_right[0] - self.lower_left[0])
        return x, y

    def pygamexy2lonlat(self, x, y):
        lon = y * (self.upper_right[0] - self.lower_left[0]) / self.max_dis_y + self.lower_left[0]
        lat = - x * (self.upper_right[1] - self.lower_left[1]) / self.max_dis_x + self.upper_right[1]
        return lon, lat

def get_map_props():
    map_props = {
        'NCSU':
            {
                'lower_left': [-78.6988, 35.7651],  # lon, lat
                'upper_right': [-78.6628, 35.7896]
            },
        'purdue':
            {
                'lower_left': [-86.93, 40.4203],
                'upper_right': [-86.9103, 40.4313]
            },
        'KAIST':
            {
                'lower_left': [127.3475, 36.3597],
                'upper_right': [127.3709, 36.3793]
            }
    }
    return map_props

def traj_to_timestamped_geojson(index, trajectory, num_uav, num_agent, color, only_UVs=False):  # indextrajindexenum

    point_gdf = trajectory.df.copy()
    point_gdf["previous_geometry"] = point_gdf["geometry"].shift()
    point_gdf["time"] = point_gdf.index  # datetimeindex
    point_gdf["previous_time"] = point_gdf["time"].shift()

    features = []
    # for Point in GeoJSON type
    for _, row in point_gdf.iterrows():
        if only_UVs and index >= num_agent: break
        corrent_point_coordinates = [row["geometry"].xy[0][0], row["geometry"].xy[1][0]]
        current_time = [row["time"].isoformat()]

        # ra = {'uav': 3, 'car': 5, 'human': 0.5}  #
        ra = {'uav': 5, 'car': 7, 'human': 2}  #
        op = {'uav': 1, 'car': 1, 'human': 1}  # opacity0.2

        if index < num_uav:  # UAV
            radius, opacity = ra['uav'], op['uav']
        elif num_uav <= index < num_agent:  # CAR
            radius, opacity = ra['car'], op['car']
        else:  # human
            radius, opacity = ra['human'], op['human']

        # for Point in GeoJSON type  (Temporally Deprecated)
        features.append(  #
            {
                "type": "Feature",
                "geometry": {
                    "type": "Point",
                    "coordinates": corrent_point_coordinates,
                },
                "properties": {
                    "times": current_time,
                    "icon": 'circle',  # point
                    "iconstyle": {
                        'fillColor': color,
                        'fillOpacity': opacity,  #
                        'stroke': 'true',
                        'radius': radius,
                        'weight': 1,
                    },
                    "style": {  # line
                        "color": color,
                        "opacity": opacity
                    },
                    "code": 11,

                },
            }
        )
    return features

def folium_draw_circle(map, pos, color, radius, weight):  #
    folium.vector_layers.Circle(
        location=pos,  #
        radius=radius,  #  m
        color=color,  #
        # fill=True,  #
        # fill_color='#%02X%02X%02X' % (0, 0, 0),  #
        # fillOpacity=1,  # Fill opacity
        weight=weight  #
    ).add_to(map)

def folium_draw_CircleMarker(map, pos, color, radius):  #
    folium.CircleMarker(
        location=pos,
        radius=radius,
        color=color,
        stroke=False,
        fill=True,
        fill_opacity=1,
        opacity=1,
        popup="{} ".format(radius),
        tooltip=str(pos),
    ).add_to(map)

def get_border(ur, lf):
    upper_left = [lf[0], ur[1]]
    upper_right = [ur[0], ur[1]]
    lower_right = [ur[0], lf[1]]
    lower_left = [lf[0], lf[1]]

    coordinates = [
        upper_left,
        upper_right,
        lower_right,
        lower_left,
        upper_left
    ]

    geo_json = {"type": "FeatureCollection",
                "properties": {
                    "lower_left": lower_left,
                    "upper_right": upper_right
                },
                "features": []}

    grid_feature = {
        "type": "Feature",
        "geometry": {
            "type": "Polygon",
            "coordinates": [coordinates],
        }
    }

    geo_json["features"].append(grid_feature)

    return geo_json


# -*- encoding:utf-8 -*-

"""
here we prepare the dataset in form of .pkl files
"""

from __future__ import print_function

import numpy as np
from keras.preprocessing.text import Tokenizer
from keras.preprocessing.sequence import pad_sequences
import pickle
import pandas as pd
import re
np.random.seed(1337)
import sys

# transforms a csv file to pkl

def clean_text(text):
    text = text.lower()
    text = text.replace("\r","")
    text = text.replace("\n","")
    text = text.strip()
    return text

def load_data(filename):
    rows = pd.read_csv(filename, keep_default_na=False)
    sequences = []

    for i in range(rows.shape[0]):
        text = rows.loc[i].ReviewText
        if text != "":
            sequences.append(clean_text(text))
    return sequences

def main():

    embedding_file = sys.argv[1]
    param_file = sys.argv[2]
    input_file = sys.argv[3]

    # loading the data
    sequences = load_data(input_file)
    print("Data loaded")

    #tokenizer = Tokenizer()
    tokenizer = Tokenizer(5000) # we keep the 5000 most frequent words of our vocabulary

    tokenizer.fit_on_texts(sequences)

    #MAX_SEQUENCE_LENGTH = max([len(seq) for seq in sequences])
    #print(MAX_SEQUENCE_LENGTH)
    MAX_SEQUENCE_LENGTH = 100 # we keep the last 100 words of every sentence

    #MAX_NB_WORDS = len(tokenizer.word_index) + 1
    MAX_NB_WORDS = 5000

    word_index = tokenizer.word_index

    print("MAX_SEQUENCE_LENGTH: {}".format(MAX_SEQUENCE_LENGTH))
    print("MAX_NB_WORDS: {}".format(MAX_NB_WORDS))

    sequences = tokenizer.texts_to_sequences(sequences)
    sequences = pad_sequences(sequences, maxlen=MAX_SEQUENCE_LENGTH)

    # loading the embedding file

    print('Now indexing word vectors...')

    embeddings_index = {}
    f = open(embedding_file, 'r')
    for line in f:
        values = line.split()
        word = values[0]
        try:
            coefs = np.asarray(values[1:], dtype='float32')
        except ValueError:
            continue
        embeddings_index[word] = coefs
    f.close()

    embedding_size = len(embeddings_index.values()[0])

    maximum = max(max(v) for v in embeddings_index.values()) # we'll use the max value of the embeddings to normalize every word embedding vector

    print("Now constructing embedding matrix...")

    num_words = min(MAX_NB_WORDS, len(word_index))
    embedding_matrix = np.zeros((num_words , embedding_size))
    for word, i in word_index.items():
        if i >= MAX_NB_WORDS:
            continue
        embedding_vector = embeddings_index.get(word)

        if embedding_vector is not None:
            # we normalize word embedding vectors
            embedding_matrix[i] = [float(x)/maximum for x in embedding_vector] #normalize the embedding_vector
        else:
            embedding_matrix[i] = np.random.normal(-0.25, 0.25, embedding_size)

    # we need to represent every input sequence using word embeddings
    temp = np.zeros((sequences.shape[0], MAX_SEQUENCE_LENGTH, embedding_size))
    for i in range(sequences.shape[0]):
        # for each sequence
        for j in range(MAX_SEQUENCE_LENGTH):
            # for each word of the sequence, get it embedding vector from the embedding matrix
            temp[i][j] = embedding_matrix[sequences[i][j]]

    sequences = temp
    print(sequences.shape)

    print("Now dumping")
    pickle.dump(sequences, open(input_file + ".pkl", "wb"))

if __name__ == '__main__':
    main()


# Problem Number 392

class Solution:
    def isSubsequence(self, s: str, t: str) -> bool:
        LEFT_BOUND, RIGHT_BOUND= len(s),len(t)
        ptr1=ptr2=0

        while ptr1<LEFT_BOUND and ptr2<RIGHT_BOUND:
            if s[ptr1]==t[ptr2]:
                ptr1 +=1
            ptr2 +=1
        return ptr1==LEFT_BOUND

################## Solution 2 Using Greedy Algorithm i.e Divide and conquer #######################################
class Solution:
    def isSubsequence(self, s: str, t: str) -> bool:
        LEFT_BOUND, RIGHT_BOUND= len(s),len(t)

        def rec_isSubsequence(left_index, right_index) -> bool:
            if left_index==LEFT_BOUND:
                return True
            if right_index==RIGHT_BOUND:
                return False
            if s[left_index]==t[right_index]:
                left_index +=1
            right_index +=1

            return rec_isSubsequence(left_index, right_index)

        return rec_isSubsequence(0,0)


import math

def intersection(l1, l2):
    l1 = set(l1)
    l2 = set(l2)
    return [value for value in l2 if value in l1]

def man_dist(point):
    return abs(point[0]) + abs(point[1])

def pt1(input):
    wire1 = []
    wire2 = []
    for wire, moves in zip((wire1, wire2), (input[0], input[1])):
        x = 0
        y = 0
        dx = 0
        dy = 0
        for move in moves.split(","):
            if move[0] == "D":
                dx = 0
                dy = -1
            elif move[0] == "U":
                dx = 0
                dy = 1
            elif move[0] == "R":
                dx = 1
                dy = 0
            elif move[0] == "L":
                dx = -1
                dy = 0
            for i in range(int(move[1:])):
                x += dx
                y += dy
                wire.append((x, y))
    points = intersection(wire1, wire2)
    dist = man_dist(points[0])
    for point in points[1:]:
        dist = min(dist, man_dist(point))
    return dist

def pt2(input):
    wire1 = {}
    wire2 = {}
    # wire {(x,y) : dist}
    for wire, moves in zip((wire1, wire2), (input[0], input[1])):
        x = 0
        y = 0
        dx = 0
        dy = 0
        steps = 0
        for move in moves.split(","):
            if move[0] == "D":
                dx = 0
                dy = -1
            elif move[0] == "U":
                dx = 0
                dy = 1
            elif move[0] == "R":
                dx = 1
                dy = 0
            elif move[0] == "L":
                dx = -1
                dy = 0
            for i in range(int(move[1:])):
                x += dx
                y += dy
                steps += 1
                wire[(x, y)] = steps

    points = intersection(list(wire1.keys()), list(wire2.keys()))
    length = wire1[points[0]] + wire2[points[0]]
    for point in points[1:]:
        length = min(length, wire1[point] + wire2[point])
    return length

if __name__ == "__main__":
    input = open("../input/03", "r").readlines()
    print(pt1(input))
    print(pt2(input))


class Date:
    def __init__(self, date):
        tmp = date.split('.')
        self.year = int(tmp[0])
        self.month = int(tmp[1])
        self.day = int(tmp[2])
    def __add__(self,t):
        self.month += t
        while self.month > 12:
            self.year += self.month//12
            self.month = self.month%12
        if self.day - 1 <= 0:
            self.day = 28
            if self.month - 1 <= 0:
                self.year -= 1
                self.month += 12
            self.month -= 1
        else:
            self.day -= 1
    def __gt__(self, other):
        print(self, other)
        if self.year > other.year:
            return True
        if self.year == other.year and self.month > other.month:
            return True
        if self.year == other.year and self.month == other.month and self.day > other.day:
            return True
        return False
    def __str__(self):
        return str(self.year) + str(self.month) + str(self.day)

def solution(today, terms, privacies):
    answer = []
    term = {}
    today = Date(today)
    for val in terms:
        k, v = val.split()
        term[k] = int(v)
    for idx, val in enumerate(privacies):
        date, t = val.split()
        date = Date(date)
        date + term[t]
        if today > date:
            answer.append(idx + 1)
    return answer