from main import *
from numpy.linalg import norm
import pytest
from itk import RTK as rtk
import configparser
import numpy as np

def wiki_example_RTK(configFile):
    """
        Simulates a cone-beam illumination of an ellipse.

        Taken from RTK's wiki, see the following page:
        http://wiki.openrtk.org/index.php/SimpleRTK#Testing_SimpleRTK
    """
    # Read the parameters from file
    cfg = configparser.ConfigParser()
    cfg.read(configFile)
    numberOfProjections = cfg.getint('Parameters', 'Nt')
    omega = cfg.getfloat('Parameters', 'omega')
    T = cfg.getfloat('Parameters', 'T')
    firstAngle = 90 - omega * T / 2
    angularArc = omega * T
    sid = cfg.getfloat('Parameters', 'R0')  # source to isocenter distance in mm
    sdd = cfg.getfloat('Parameters', 'sdd')  # source to detector distance in mm
    isox = 0  # X coordinate on the projection image of isocenter
    isoy = 0  # Y coordinate on the projection image of isocenter
    imageSize = cfg.getint('Parameters', 'imageSize')

    # get ellipse parameters
    ellipseDensity = cfg.getfloat('Ellipse', 'density')
    ellipseAngle = cfg.getfloat('Ellipse', 'angle')
    ellipseCenterX = cfg.getfloat('Ellipse', 'x')
    ellipseCenterY = cfg.getfloat('Ellipse', 'y')
    ellipseSemiAxisX = cfg.getfloat('Ellipse', 'a')
    ellipseSemiAxisY = cfg.getfloat('Ellipse', 'b')

    # Defines the RTK geometry object
    geometry = rtk.ThreeDCircularProjectionGeometry()
    for x in range(0, numberOfProjections):
        angle = firstAngle + x * angularArc / (numberOfProjections - 1)
        geometry.AddProjection(sid, sdd, angle, isox, isoy)

    # initialization of 'blank' image
    constantImageSource = rtk.ConstantImageSource()
    sizeOutput = [imageSize, imageSize, numberOfProjections]
    spacing = [1.0, 1.0, 1.0]
    origin = (np.array(sizeOutput) - 1) * np.array(spacing) * -.5
    constantImageSource.SetOrigin(origin)
    constantImageSource.SetSpacing(spacing)
    constantImageSource.SetSize(sizeOutput)
    constantImageSource.SetConstant(0.0)
    source = constantImageSource.Execute()

    rei = rtk.RayEllipsoidIntersectionImageFilter()
    semiprincipalaxis = [ellipseSemiAxisX,
                         ellipseSemiAxisY,
                         ellipseSemiAxisY]
    center = [ellipseCenterX, ellipseCenterY, 0]
    # Set GrayScale value, axes, center...
    rei.SetDensity(ellipseDensity)
    rei.SetAngle(ellipseAngle)
    rei.SetCenter(center)
    rei.SetAxis(semiprincipalaxis)
    rei.SetGeometry(geometry)
    reiImage = rei.Execute(source)

    return rtk.GetArrayFromImage(reiImage[:, imageSize / 2, :])

configFile = 'test.ini'
tol = .01

# simulation by our algorithm
p = Parameters(configFile)
s = Simulator(p)
res = s.run()
DCC = DataConsistencyConditions(res)

# simulation with RTK's example in wiki
projWiki = wiki_example_RTK(configFile)

# difference between the two projections
diff = res.projections - projWiki

## General tests
def test_get_angle():
    """
        The angles start at 90 since we compute the angle with the
        y-axis
    """
    assert p.get_angle(0) == 90

def test_y0():
    """
        :math:`y0` is supposed to be stricly positive
    """
    assert p.y0 > 0

## Testing projection operator

def test_projections_have_proper_dimensions():
    assert res.projections.shape[0] == p.Nt
    assert res.projections.shape[1] == p.imageSize

def test_projections_fits_example_in_wiki_RTK():
    """
        Compare the two projections, in L2 norm
    """
    assert norm(diff) <= tol * norm(projWiki)
    assert norm(diff, 1) <= tol * norm(projWiki, 1)
    assert norm(diff, 2) <= tol * norm(projWiki, 2)
    assert norm(diff, np.inf) <= tol * norm(projWiki, np.inf)

## Testing post-processing

configFile = 'example.ini'
tol = .01

# simulation by our algorithm
p = Parameters(configFile)
s = Simulator(p)
res = s.run()
DCC = DataConsistencyConditions(res)

def test_interpolation_fits_actual_projections():
    """
        The interpolator must fit the actual data
    """
    res.interpolate_projection()

    T = res.projections_interpolator
    t = p.get_time_range()
    phi = p.get_alpha_range()
    Tarray = T(phi, t)

    np.testing.assert_array_almost_equal(Tarray, res.projections)

def test_fanbeam_operator_has_compact_support():
    """
        Because we image a finite object, :math:`T(\phi/2,t)` and
        :math:`T(-\phi/2,t)` are always 0.
    """
    res.interpolate_projection()
    T = res.projections_interpolator

    t = np.linspace(-1000, 1000)

    np.testing.assert_almost_equal(T(np.pi / 2, t).sum(), 0.0)
    np.testing.assert_almost_equal(T(-np.pi / 2, t).sum(), 0.0)

## Testing DCC
def test_lambda_t_0_0():
    """
        When :math:`v = 0` and :math:`x = 0`, one has :math:`\lambda(T/2) = \pi/2`
        and :math:`\lambda(-T/2) = -\pi/2`.
        Moreover, the function is not supposed to raise a warning about
        division by 0.
    """
    lambda_t_0_0 = np.vectorize(lambda t: DCC.lambda_v(t, 0, 0, 0))

    # extreme values
    np.testing.assert_almost_equal(lambda_t_0_0(p.T / 2), np.pi / 2)
    np.testing.assert_almost_equal(lambda_t_0_0(-p.T / 2), -np.pi / 2)

    # elsewhere, compare with theoretical values
    t = np.linspace(-p.T / +.01, p.T / 2 - .01, 1000)
    lambda_theo = np.arctan((p.R0 * np.sin(p.omega * t / 360 * 2 * np.pi)) \
                            / (p.R0 * np.cos(p.omega * t / 360 * 2 * np.pi) - p.y0))
    np.testing.assert_array_almost_equal(lambda_t_0_0(t), lambda_theo)

def test_beta_v2_0():
    """
        When :math:`v_2 = 0`, then :math:`\beta = 0`.
        Here, we test that beta(v1,0) is equal to 0, with a random
        value (strictly positive) for v1.
    """
    from numpy.random import randn
    v1 = np.abs(randn())

    assert DCC.beta(v1, 0) == 0.

def test_beta_raises_exception():
    """
        Assert that method beta in DCC class raises the proper
        exception, ie when denominator is equal to 0.
    """
    v1 = -2 * p.R0 * np.sin(2 * np.pi / 360 * p.omega * p.T / 2) / p.T

    with pytest.raises(ZeroDivisionError) as e_info:
        DCC.beta(v1, p.v2)

def test_virtual_source_position_begin_end():
    """
        By definition, the y-coordinates of the source is supposed
        to be the same when :math:`t=-T/2` and :math:`t=T/2`.
    """
    # y-coordinate of s_v(T/2)
    s_v_2_T_over_2 = DCC.get_virtual_source_position(p.T / 2, p.v, p.v2)[1]

    # y-coordinate of s_v(T/2)
    s_v_2_minus_T_over_2 = DCC.get_virtual_source_position(-p.T / 2, p.v, p.v2)[1]

    np.testing.assert_almost_equal(s_v_2_T_over_2, s_v_2_minus_T_over_2)

def test_simplified_formula_for_y0_prime():
    """
        Test that :math:`s^{(v)}(T/2) = s^{(v)}(-T/2) = R_0 \cos(\omega T/2 + \beta)`
    """
    y0_prime = p.R0 * np.cos(p.omega / 360 * 2 * np.pi * p.T / 2 + DCC.beta(p.v, p.v2))
    # y-coordinate of s_v(T/2)
    s_v_2_T_over_2 = DCC.get_virtual_source_position(p.T / 2, p.v, p.v2)[1]

    # y-coordinate of s_v(T/2)
    s_v_2_minus_T_over_2 = DCC.get_virtual_source_position(-p.T / 2, p.v, p.v2)[1]

    np.testing.assert_almost_equal(y0_prime, s_v_2_minus_T_over_2)
    np.testing.assert_almost_equal(s_v_2_T_over_2, y0_prime)

def test_F_0_0():
    """
        As mentioned in equation (17) of the abstract, when :math:`v=0`
        the function :math:`F` has a simpler formulation

        ..math::
        F^{(0,0)}(t,x) = \frac{x + R_0 \sin(\omega t)}{R0 \cos(\omega t)}
    """
    R0 = p.R0
    omega = p.omega / 360 * 2 * np.pi
    y0 = R0 * np.cos(omega * p.T / 2)

    from numpy.random import randn
    # virtual point, taken randomly
    x = randn()
    # time vector, taken randomly
    t = randn()

    F_theo = (x + R0 * np.sin(omega * t)) / (R0 * np.cos(omega * t) - y0)
    np.testing.assert_almost_equal(DCC.F(t, 0, 0, x), F_theo)

def test_get_virtual_source_position_v_0():
    """
        Test that when :math:`v_1 = v_2 = 0`, one has
        :math:`s^{(v)}(t) = R_0(-\sin(\omega t), \cos(\omega t))`
    """
    from numpy.random import randn
    t = randn()

    s_0_t = DCC.get_virtual_source_position(t, 0, 0)
    omega = p.omega / 360 * 2 * np.pi
    s_theo = p.R0 * np.array((-np.sin(omega * t), np.cos(omega * t)))

    np.testing.assert_almost_equal(s_0_t, s_theo)

def test_get_virtual_source_position_v2_0():
    """
        Test that when :math:`v_2 = 0`, one has
        :math:`s^{(v)}(t) = (-R_0 \sin(\omega t) - (t+T/2) v_1, \
                              R_0 \cos(\omega t))`
    """
    from numpy.random import randn
    t = randn()
    v = randn()
    R0 = p.R0
    omega = p.omega / 360 * 2 * np.pi
    T = p.T

    s_0_t = DCC.get_virtual_source_position(t, v, 0)
    omega = p.omega / 360 * 2 * np.pi

    # we will use here the same code as in previous versions
    Mvt = np.array(((t + p.T / 2) * v, 0))
    s_theo = s.source.get_position(t) - Mvt

    s_theo_analytical = np.array((-R0 * np.sin(omega * t) - \
                                  (t + T / 2) * v, R0 * np.cos(omega * t)))

    np.testing.assert_almost_equal(s_0_t, s_theo)
    np.testing.assert_almost_equal(s_0_t, s_theo_analytical)

def test_get_virtual_points_vector():
    """
        Here, we test that when :math:`v_1 = v_2 = 0`, the virtual points
        :math:`x'` are in fact points between :math:`-R_0\sin(\omega T/2)`
        and :math:`-R_0\sin(\omega T/2)`
    """
    x_prime = DCC.get_virtual_points_vector(0, 0)

    omega = p.omega / 360 * 2 * np.pi
    x_prime_theo = p.R0 * np.linspace(-np.sin(omega * p.T / 2), np.sin(omega * p.T / 2))

    np.testing.assert_almost_equal(x_prime, x_prime_theo)

def test_jacobian_with_old_formulas():
    """
        In some archives, we had the formulas for the jacobian
        when :math:`v_2=0`, so we will use it here.
    """

    # for time, degree of polynom, position: we take random values
    from numpy.random import randint
    n = randint(5)
    from numpy.random import randn
    t = np.abs(randn())
    x = randn()
    v1 = np.abs(randn())
    # important, because the test relies on the fact that v2 = 0
    v2 = 0

    # usual parameters
    R0 = p.R0
    T = p.T
    omega = p.omega / 360 * 2 * np.pi
    y0 = p.y0

    # compute weighting function with DCC class
    jacobian_new = DCC.jacobian(t, v1, v2, x)

    # compute old formula (with previous version of code)
    v = v1  # to be compatible with old notations
    # first, "jacobian"
    num = R0 ** 2 * omega - v * y0 + R0 * np.cos(omega * t) * (v - omega * y0) \
          + R0 * omega * np.sin(omega * t) * (x + (t + T / 2) * v)
    denom = (R0 * np.cos(omega * t) - y0) ** 2
    jacobian_old = num / denom

    np.testing.assert_almost_equal(jacobian_new, jacobian_old)

def test_integrand_with_old_formulas():
    """
        In some archives, we had the formulas for the weighting function
        and the jacobian when :math:`v_2=0`, so we will use it here.
    """

    # for time, degree of polynom, position: we take random values
    from numpy.random import randint
    n = randint(5)
    from numpy.random import randn
    t = np.abs(randn())
    x = randn()
    v1 = np.abs(randn())
    # important, because the test relies on the fact that v2 = 0
    v2 = 0

    # usual parameters
    R0 = p.R0
    T = p.T
    omega = p.omega / 360 * 2 * np.pi
    y0 = R0 * np.cos(omega * T / 2)

    # compute weighting function with DCC class
    weight_new = DCC.W(n, t, v1, v2, x)

    # compute old formula (with previous version of code)
    v = v1  # to be compatible with old notations
    # first, "jacobian"
    num = R0 ** 2 * omega - v * y0 + R0 * np.cos(omega * t) * (v - omega * y0) \
          + R0 * omega * np.sin(omega * t) * (x + (t + T / 2) * v)
    denom = (R0 * np.cos(omega * t) - y0) ** 2
    J_x_t_v = num / denom

    # then, function W_n(t,x)
    s_v_t = DCC.get_virtual_source_position(t, v1, v2)
    from scipy.spatial import distance
    D_x_t = distance.euclidean(s_v_t, (x, y0))
    num = (x + R0 * np.sin(omega * t) + (t + T / 2) * v) ** n
    denom = D_x_t * (R0 * np.cos(omega * t) - y0) ** (n - 1)
    W_n_t_x = num / denom

    weight_old = J_x_t_v * W_n_t_x

    np.testing.assert_almost_equal(weight_old, weight_new)

def test_two_different_formulas_for_weight_function():
    """
        In Theorem 1, the weight function is defined as

        ..math::
        W(t) = \tan^n(\lambda) \cos(\lambda) \partial_t \lambda

        We can also show that

        ..math::
        W(t) = \frac{F(t)^n}{\sqrt{1+F^(t)}} F'(t),

        where :math:`F(t) := \arctan(\lambda)`. This is what
        we will test here.
    """
    # for time, degree of polynom, position, velocity,
    # we take random values
    from numpy.random import randint
    n = randint(5)
    from numpy.random import randn
    t = np.abs(randn())
    x = randn()
    v1 = np.abs(randn())
    v2 = np.abs(randn())

    # usual parameters
    R0 = p.R0
    T = p.T
    omega = p.omega / 360 * 2 * np.pi
    y0 = R0 * np.cos(omega * T / 2)

    # compute weighting function with DCC class
    weight_DCC = DCC.W(n, t, v1, v2, x)

    # compute formula
    F_t_x = DCC.F(t, v1, v2, x)
    diff_t_F = DCC.jacobian(t, v1, v2, x)  # computes F'(t)
    weight_alternative = F_t_x ** n / np.sqrt(1 + F_t_x ** 2) * diff_t_F

    np.testing.assert_almost_equal(weight_DCC, weight_alternative)


import sqlite3
from contextlib import closing
from heroes_app.scrape import scrape_all, scrape_hero
import pandas as pd

DB_LOCATION = "db/heroes.db"
TABLE_NAME = 'heroes'

TABLE_FORMAT = {
    'url_name': 'text',
    'name': 'text',
    'health_points': 'integer',
    'damage_per_attack': 'integer',
    'attack_speed': 'integer',
    'mana': 'integer',
    'damage_per_second': 'float',
    'gold_price': 'integer',
    'attack_range': 'float',
    'hero_type': 'text',
    'release_date': 'text',
}

class DBClass:
    def __init__(self, loc=DB_LOCATION, table_name=TABLE_NAME, table_format=TABLE_FORMAT):
        self.conn = sqlite3.connect(loc)
        self.create_table(table_name, table_format)

    def create_table(self, table_name, table_format: dict):
        format_str = ', '.join([f'{key} {value}' for key, value in table_format.items()])
        self.run_query(sql_str=f"CREATE TABLE IF NOT EXISTS {table_name} ({format_str});")

    def run_query(self, sql_str, *args):
        conn = self.conn
        with closing(conn.cursor()) as cursor:
            result = cursor.execute(sql_str, tuple(args)).fetchall()

            conn.commit()
        return result

    def add_hero_to_db(self, hero_dict: dict, table_name):

        name = hero_dict['name']

        if len(self.get_hero_from_db(name, table_name)) > 0:
            self.run_query(f'DELETE FROM {table_name} WHERE name=?', name)

        keys = tuple([x.replace(' ', '_') for x in hero_dict.keys()])
        vals = tuple(list(hero_dict.values()))

        self.run_query(f'INSERT INTO {table_name} {keys} VALUES {vals};')

    def get_hero_from_db(self, hero_name, table_name):
        hero = self.run_query(f"SELECT * FROM {table_name} WHERE name=?", hero_name)
        return hero

    def get_hero_as_df(self, hero_name, table_name):
        hero = pd.read_sql_query(f"SELECT * FROM {table_name} WHERE name='{hero_name}'", self.conn)
        return hero

    def add_all_heroes(self, n=None, table_name='heroes'):
        all_heroes = scrape_all(n=n)

        for hero_url, hero_info in all_heroes.items():
            hero_info.update({'url_name': hero_url})
            self.add_hero_to_db(hero_info, table_name)

    def add_hero(self, url_name, table_name='heroes'):
        hero_url, hero_info = scrape_hero(url_name)
        hero_info.update({'url_name': url_name})

        self.add_hero_to_db(hero_info, table_name)

    def heroes_to_df(self, table_name='heroes'):
        heroes = pd.read_sql_query(f"SELECT * FROM {table_name}", self.conn)
        return heroes

def update_db():
    dbc = DBClass()
    dbc.add_all_heroes()

def main():
    pass

if __name__ == '__main__':
    main()


from keras.models import load_model
import keras.utils

import sklearn.metrics
from sklearn.svm import SVC
from sklearn.externals import joblib
from sklearn.model_selection import StratifiedShuffleSplit

import numpy as np

import os
import sys

import utils
import plot_utils

def train_svm(path_results, x_data, y_data, args):
	path_params = path_results + "/SVM/Metrics/params_test_" + str(args.step) + ".txt"

	params = eval(open(path_params).read())

	if "gamma" in params:
		classifier = SVC(kernel=params["kernel"], C=params["C"], gamma = params["gamma"],probability = True, max_iter = 10000, class_weight='balanced')

	else:
		classifier = SVC(kernel=params["kernel"], C=params["C"], probability = True, max_iter = 10000, class_weight='balanced')

	spliter = StratifiedShuffleSplit(n_splits=5, test_size=0.2, random_state=19993)
	fold = 0
	for train_index, test_index in spliter.split(x_data, y_data):
		if str(fold) == str(args.fold):
			x_train = x_data[train_index]
			x_test = x_data[test_index]

			y_train = y_data[train_index]
			y_test = y_data[test_index]

			classifier.fit(x_train, y_train)

		fold += 1

	predictions = classifier.predict(x_test)

	print(sklearn.metrics.classification_report(y_test, predictions))

	return classifier

def create_model(path_results, args):
	"""Carga la arquitectura del modelo y los pesos a esta.

	Necesita del path_results que se desee analizar

	"""

	path_model = path_results + "/Models/" + str(args.model) + "_" + str(args.step) + ".h5"
	path_weights = path_results + "/Models/" + str(args.model) + "_" + str(args.step) + "weights.hdf5"

	path_model_aux = path_results + "/Models/" + str(args.model) + "aux_" + str(args.step) + ".h5"
	path_weights_aux = path_results + "/Models/" + str(args.model) + "aux_" + str(args.step) + "weights.hdf5"

	print("path_model", path_model)
	print("path_weights", path_weights)

	model = load_model(path_model)
	model.load_weights(path_weights, by_name=False)

	model_aux = load_model(path_model_aux)
	model_aux.load_weights(path_weights_aux, by_name=False)

	print("Model loaded")

	return model, model_aux

def prepare_data(x_cbfv_data, x_cbfv_signal, args):
	"""Cambia el shape de la senial de entrada para que pueda ser predecida por el modelo.

	"""

	min_cbfv = np.amin(x_cbfv_data)
	max_cbfv = np.amax(x_cbfv_data)

	x_cbfv_normalize = utils.normalize(x_cbfv_data, min_cbfv, max_cbfv)
	x_cbfv_signal_normal = utils.normalize(x_cbfv_signal, min_cbfv, max_cbfv)

	if args.model == "resnet" or args.model == "fcn":
		x_cbfv_data = utils.prepare_data_cnn(x_cbfv_data, args)
		x_cbfv_ready = utils.prepare_data_cnn_signal(x_cbfv_signal_normal, args)

	else:
		x_cbfv_data = utils.prepare_data_lstm(x_cbfv_data, args)
		x_cbfv_ready = utils.prepare_data_lstm_signal(x_cbfv_signal_normal, args)

	return x_cbfv_data, x_cbfv_ready

def generate_invariant_data(path_data, x_cbfv_data, args):

	subjects = os.listdir(path_data)
	print("subjects",subjects)

	for subject in subjects:
		if subject == args.subject:
			#DY subject
			cbfv_signal = utils.read_cbfv_file(path_data + "/" + str(args.subject))
			#cambia frecuencia de muestreo a 0.6
			cbfv_signal = utils.lineal_interpolation(cbfv_signal)
			print("shape pre", cbfv_signal.shape)
			x_cbfv_data, x_cbfv_signal = prepare_data(x_cbfv_data, cbfv_signal, args)

	return x_cbfv_data, x_cbfv_signal

def generate_variant_data(path_data_nc, path_data_hc, x_cbfv_data, args):

	subjects = os.listdir(path_data_nc)
	print("subjects",subjects)

	for subject in subjects:
		if subject == args.subject:
			#DY subject
			cbfv_signal_nc = utils.read_cbfv_file(path_data_nc + "/" + str(args.subject))
			cbfv_signal_hc = utils.read_cbfv_file(path_data_hc + "/" + str(args.subject))

			print("len nc",len(cbfv_signal_nc))
			print("len hc",len(cbfv_signal_hc))

			if args.stick == "1":
				cbfv_signal = np.concatenate((cbfv_signal_nc[(len(cbfv_signal_nc)/2):len(cbfv_signal_nc)], cbfv_signal_hc[0:(len(cbfv_signal_hc)/2)]),axis = 0)
			else:
				cbfv_signal = np.concatenate((cbfv_signal_nc[0:(len(cbfv_signal_nc)/2)], cbfv_signal_hc[(len(cbfv_signal_hc)/2):len(cbfv_signal_hc)]),axis = 0)

			print("len pegada",len(cbfv_signal))

			#cambia frecuencia de muestreo a 0.6
			cbfv_signal = utils.lineal_interpolation(cbfv_signal)
			print("shape pre", cbfv_signal.shape)
			x_cbfv_signal = prepare_data(x_cbfv_data, cbfv_signal, args)

	return x_cbfv_signal

def select_model(path_results):
	path_metrics = path_results + "/Metrics/"

	kappas = []

	for step in range(50, 550, 50):
		with open(path_metrics + "kappa_test_" + str(step) + ".txt") as f:
			kappa = f.readline()
		element = {"kappa": str(kappa),"step": str(step)}
		kappas.append(element)

	seq_kappa = [x["kappa"] for x in kappas]

	steps = []

	for x in kappas:
		if x["kappa"] == max(seq_kappa):
			steps.append(x["step"])

	return min(steps)

def maping(path, path_env):

	#data is in Results/args.mode/args.conjunt/5fold/args.model_numberclass_500epochs_args.train_data_foldi

	#LECTURA DE DATOS PARA PODER PLOTEAR MAPA
	#EXTRACCION DE CARACTERISTICAS GENERALES DE LOS DATOS. NORMALIZACION, BATCH_SEIZE, NUMB_CLASS
	args = utils.get_args()

	#get the path of data to train and validate the model
	train_data_path = path_env + "/" + args.train_dataset_path + "/" + args.mode
	val_data_path = path_env + "/" + args.val_dataset_path + "/" + args.mode

	#root path_save
	path_save = path_env + "/" + args.path_save + "/" + args.mode

	train_dataset = train_data_path + "/" + args.train_data
	val_dataset = val_data_path + "/" + args.val_data

	y_train_real, x_train_abp, x_train_cbfv = utils.read_multivariate_data(train_dataset + '/' + 'signals.txt')
	#read hipercapnia data
	y_val_real, x_val_abp, x_val_cbfv = utils.read_multivariate_data(val_dataset + '/' + 'signals.txt')

	if args.conjunt == "Mix":
		x_cbfv = np.concatenate((x_train_cbfv,x_val_cbfv),axis=0)
	else:
		x_cbfv = x_train_cbfv

	variant_mode = str(args.train_data).split("_")[4]
	print("variant_mode", variant_mode)

	#from data choose batch size
	batch_size = min(x_train_cbfv.shape[0]/10, 16)

	#get the number of classes in the dataset
	nb_classes_train = len(np.unique(y_train_real))
	nb_classes_test = len(np.unique(y_val_real))
	nb_classes = nb_classes_train

	#number of classes in train and test must to be the same.
	assert nb_classes_train == nb_classes_test

	##DESDE ACA INICIA EL TRABAJO DE MAPEO

	path_results = path_env + "/Results/" + str(args.mode) + "/" + str(args.conjunt) + "/5fold/" + str(args.model) + "_" + str(nb_classes) + "class" + "_500epochs_" + str(args.train_data) + "_fold" + str(args.fold)

	print("path_results", path_results)

	print("step pre",args.step)

	step_model = select_model(path_results)
	args.step = step_model

	print("step post",args.step)

	#load trained model
	model, model_aux = create_model(path_results, args)

	#path for data nc and hc
	path_data_nc = path + "/nc_data/"
	path_data_hc = path + "/hc_data/"

	#read invariant signal in nc to predict
	if args.mode == "Invariant":
		x_cbfv_data, signal_to_predict = generate_invariant_data(path_data_nc, x_cbfv, args)
	else:#variant and all
		x_cbfv_data, signal_to_predict = generate_variant_data(path_data_nc, path_data_hc, x_cbfv, args)

	print("signal_to_predict",signal_to_predict.shape)

	#sys.exit("test")

	#predict signal with normal model and model_aux
	model_prediction = model.predict(signal_to_predict, batch_size=batch_size)
	model_aux_prediction = model_aux.predict(signal_to_predict, batch_size=batch_size)
	#feature_space = model_aux.predict(x_cbfv_data, batch_size=batch_size)

	#print("model_aux_prediction",len(model_aux_prediction[0]))

	#CARGAR DATOS TSNE
	#PLOTEAR CON SENIAL NUEVA

	path_features = path_results + "/Weights/" + str(args.step) + ".csv"
	x_data, y_data = utils.read_weights(path_features)

	plot_utils.plot_visualization(path_results, x_data, y_data, variant_mode, nb_classes, model_aux_prediction,args)

	#THIS IS FOR BETTER PREDICTION

	#load svm model
	svm_model = train_svm(path_results, x_data, y_data, args)

	#predict signal with feature extraction of deep model
	prediction_svm = svm_model.predict(model_aux_prediction)
	print("prediction_svm", prediction_svm.shape)
	print("class of prediction", prediction_svm)
	print(prediction_svm[0])

if __name__ == "__main__":
	#example execution
	#python maping.py -m Variant -c Mix -train_data abp_cbfv_nc_4class_variantbi_freq0.6 -val_data abp_cbfv_hc_4class_variantbi_freq0.6 -model resnet -f 1 -step 500 -subject DY0000.txt
	#python maping.py -m Invariant -c Mix -train_data abp_cbfv_nc_2class_freq0.6 -val_data abp_cbfv_hc_2class_freq0.6 -model resnet -f 1 -step 500 -subject DY0000.txt

	path = os.getcwd()
	path_env, path_source = os.path.split(path)

	maping(path, path_env)


from flask import Flask, request

app = Flask(__name__)

@app.route('/', methods=['GET', 'POST'])
def index():
    print('Received request:', request.method, request.url)
    return 'Hello, world!'

if __name__ == '__main__':
    app.run(port=5000)


"""
This is the main entry point to our Python application from PythonSkill.cpp,
where 'robot' is defined so 'import robot' does not fail with ImportError.

The `import robot` bridge from C++ to Python is defined by various Python
wrappers, run once at import time. Please see the `tick` function below for a
bridge from C++ to Python and back to C++ which is run many times at run time.

For example, for the implementation of `robot.TOP_IMAGE_ROWS`,
see the file `VisionDefinitions_wrap.cpp` in the following directory:
@see
https://github.com/UNSWComputing/rUNSWift/tree/master/robot/perception/behaviour/python/wrappers

For info, the following contains the C++ definition of `TOP_IMAGE_ROWS`:
@see
https://github.com/UNSWComputing/rUNSWift/blob/master/robot/perception/vision/VisionDefinitions.hpp
"""
import Simulation  # noqa

from pkgutil import iter_modules
from traceback import format_exc
from importlib import import_module
from os import getenv
from os.path import join
from util import Log
from robot import BehaviourRequest, All
from util.world import World
from util.Global import update_global
from util.TeamStatus import update_team_status
from util.FieldGeometry import update_field_geometry
from util.Timer import update_timer
from util.Sonar import update_sonar
from util.GameStatus import update_game_status
from util.NetworkEar import update_network_ear, get_ear_colour
from util.RemoteStiffener import update_remote_stiffener, get_stiffen_command
from util.ObstacleAvoidance import update_obstacle_avoidance
from util.LedOverride import override_request, reset_led_override
from util.Constants import LEDColour

skill_instance = None
headskill_instance = None

def catch_all(tick):
    def catcher(blackboard):
        try:
            return tick(blackboard)
        except Exception:
            Log.error("Behaviour exception:", exc_info=True)
            raise

    return catcher

def skill_instance_factory(blackboard, skill, behaviour_packages):
    # Load the module and the class we're going to use.
    found_skill = False
    SkillClass = None
    behaviour_root = getenv("BEHAVIOUR_ROOT", "/home/nao/data/behaviours")
    for package in behaviour_packages:
        look_in = join(behaviour_root, "/".join(package))
        seen_modules = [name for _, name, _ in iter_modules([look_in])]
        if skill not in seen_modules:
            Log.info("%s.py was not in %s, skipping import attempt.", skill, look_in)
            continue
        skill_path = "%s.%s" % (".".join(package), skill)
        try:
            skill_module = import_module(skill_path)
            # Access the class so we can do some reflection.
            SkillClass = getattr(skill_module, skill)
            found_skill = True
            Log.info("Successfully imported %s from %s", skill, skill_path)
            break
        except ImportError as e:
            Log.error("%s %s", package, e)
            Log.error(format_exc())

    if not found_skill:
        raise ImportError("Skill: %s not found in behaviour packages %s" % (skill, behaviour_packages))

    new_world = World(blackboard)  # It's a whole new world.
    _skill_instance = SkillClass(world=new_world)

    return _skill_instance

@catch_all
def tick(blackboard):
    """
    This is the main entry point from C++ into our Python behaviours and back.

    More specifically it is the bridge from which C++ calls Python inside
    the runswift executable, and receives a BehaviourRequest back.

    Currently called in `robot/perception/behaviour/python/PythonSkill.cpp`,
    the `PythonSkill::execute()` C++ function, and explicitly the line
    `behaviour_tick(bb)`.

    :param blackboard: The runswift Blackboard, a bunch of things
        stored in global memory.
    :return: A `robot.BehaviourRequest()` instance, defined in C++ inside
        `robot/types/BehaviourRequest.hpp`.
    """
    # Update all blackboard dependent helper modules.
    update_timer(blackboard)
    update_global(blackboard)
    update_team_status(blackboard)
    update_field_geometry(blackboard)
    update_sonar(blackboard)
    update_network_ear(blackboard)
    update_remote_stiffener(blackboard)
    update_game_status(blackboard)
    update_obstacle_avoidance(blackboard)

    reset_led_override()

    global skill_instance
    if not skill_instance:
        behaviour_packages = [["body", "roles"], ["body", "skills"], ["body", "test"]]
        skill_name = blackboard.behaviour.skill
        skill_instance = skill_instance_factory(blackboard, skill_name, behaviour_packages)

    global headskill_instance
    if not headskill_instance:
        head_packages = [["head"]]
        headskill_name = blackboard.behaviour.headskill
        headskill_instance = skill_instance_factory(blackboard, headskill_name, head_packages)

    # On every tick of the perception thread, we update the blackboard,
    # tick the skill, and then return the resulting behaviour request.
    skill_instance.world.update(blackboard)
    skill_instance.world.b_request = BehaviourRequest()
    skill_instance.world.b_request.actions = All()
    skill_instance.tick()
    request = skill_instance.world.b_request

    headskill_instance.world.update(blackboard)
    headskill_instance.world.b_request = request
    headskill_instance.tick()
    request = headskill_instance.world.b_request

    # LED colouring for ball detection
    if len(blackboard.vision.balls) > 0:
        request.actions.leds.rightEye = LEDColour.red
    else:
        request.actions.leds.rightEye = LEDColour.off

    # Override leds as requested by skills
    override_request(request)

    # Get right ear colour depending on network activity
    request.actions.leds.rightEar = get_ear_colour()

    # Remotely stiffen
    request.actions.stiffen = get_stiffen_command()

    # Obtain behaviour hierarchies of current skill
    request.behaviourDebugInfo.bodyBehaviourHierarchy = skill_instance.world.behaviour_hierarchy
    skill_instance.world.behaviour_hierarchy = ""
    request.behaviourDebugInfo.headBehaviourHierarchy = headskill_instance.world.behaviour_hierarchy
    headskill_instance.world.behaviour_hierarchy = ""

    return request


# import codecademylib
from matplotlib import pyplot as plt

def create_x(t, w, n, d):
    return [t*x + w*n for x in range(d)]

drinks = ["cappuccino", "latte", "chai", "americano", "mocha", "espresso"]
sales1 =  [91, 76, 56, 66, 52, 27]
sales2 = [65, 82, 36, 68, 38, 40]

# Use create_x to make store1_x
store1_x = create_x(2, 0.8, 1, len(sales1))
plt.bar(store1_x, sales1)

# Use create_x to make store2_x
store2_x = create_x(2, 0.8, 2, len(sales2))
plt.bar(store2_x, sales2)

ax = plt.subplot()
# ax.set_xticks([i  for i in range(len(sales1)*2) if i % 2 == 1])
# x-axis labels for side by side 2 series bar chart (hard coded for 2 series)
ax.set_xticks([i + 0.5  for i in range(len(sales1)*2) if i % 2 == 1])
# ax.set_xticks([i   for i in range(len(sales1)*2)])
# ax.set_xticklabels(drinks)

plt.show()

1-matplotlib/lesson4-side by side bar chart.py


#!/usr/bin/env python3

import math
import turtle

wn = turtle.Screen()

def frame():

    framePen = turtle.Turtle()
    framePen.color("#00004d", "#cce5ff")
    framePen.pensize(5)
    framePen.speed(10)
    framePen.showturtle()

    framePen.penup()
    framePen.right(90)
    framePen.forward(300)
    framePen.left(90)
    framePen.forward(-5)
    framePen.down()
    framePen.begin_fill()
    framePen.forward(345)
    framePen.left(90)
    framePen.forward(495)
    framePen.left(90)
    framePen.forward(345)
    framePen.left(90)
    framePen.forward(495)
    framePen.end_fill()
    framePen.hideturtle()

def wishes():
    wishPen = turtle.Turtle()
    wishPen.color("#000000")
    wishPen.pensize(5)
    wishPen.speed(10)
    wishPen.showturtle()

    wishPen.penup()
    wishPen.right(90)
    wishPen.forward(-105)
    wishPen.left(90)
    wishPen.forward(167.5)
    wishPen.write("HAPPY", align='center', font=('Linkin Park', 40))
    wishPen.right(90)
    wishPen.forward(54)
    wishPen.write("FATHER'S", align='center', font=('Linkin Park', 40))
    wishPen.forward(54)
    wishPen.write("DAY!", align='center', font=('Linkin Park', 40))
    wishPen.hideturtle()

def table():

    tablePen = turtle.Turtle()
    tablePen.color("#ffffff", "#000000")
    tablePen.pensize(5)
    tablePen.speed(10)
    tablePen.showturtle()

    tablePen.penup()
    tablePen.pensize(7)
    tablePen.color("#404040")
    tablePen.right(90)
    tablePen.forward(240)
    tablePen.left(90)
    tablePen.forward(-5)
    tablePen.forward(40)
    tablePen.right(90)
    tablePen.down()
    tablePen.forward(50)
    tablePen.penup()
    tablePen.backward(50)
    tablePen.left(90)
    tablePen.forward(260)
    tablePen.right(90)
    tablePen.down()
    tablePen.forward(50)
    tablePen.penup()
    tablePen.backward(50)

    tablePen.home()
    tablePen.color("#ffffff", "#000000")
    tablePen.pensize(5)
    tablePen.speed(10)

    tablePen.penup()
    tablePen.right(90)
    tablePen.forward(240)
    tablePen.left(90)
    tablePen.forward(-5)
    tablePen.forward(40)

    tablePen.down()
    tablePen.begin_fill()
    tablePen.forward(265)
    tablePen.left(110)
    tablePen.forward(90.5)
    tablePen.left(70)
    tablePen.forward(207)
    tablePen.left(70)
    tablePen.forward(90.5)
    tablePen.end_fill()

    tablePen.penup()
    tablePen.backward(47)
    tablePen.left(110)
    tablePen.forward(4)
    tablePen.pensize(4)
    tablePen.down()
    tablePen.forward(230)
    tablePen.penup()
    tablePen.backward(115)
    tablePen.left(90)
    tablePen.pensize(3)
    tablePen.down()
    tablePen.backward(43)
    tablePen.pensize(4)
    tablePen.color("#808080")
    tablePen.backward(7)
    tablePen.forward(20)
    tablePen.color("#ffffff")
    tablePen.pensize(3)
    tablePen.forward(73)
    tablePen.pensize(5)
    tablePen.color("#808080")
    tablePen.forward(11)
    tablePen.penup()
    tablePen.backward(2)
    tablePen.down()
    tablePen.color("#ffffff")
    tablePen.pensize(3)
    tablePen.backward(13)
    tablePen.hideturtle()

def rackets():

    racketPen = turtle.Turtle()
    racketPen.color("#b89161")
    racketPen.pensize(2)
    racketPen.speed(10)

    racketPen.penup()
    racketPen.right(90)
    racketPen.forward(140)
    racketPen.left(90)
    racketPen.forward(-5)
    racketPen.forward(80)
    racketPen.left(90)
    def drawRacket(rColor):
        racketPen.color("#b89161")
        racketPen.down()
        racketPen.begin_fill()
        racketPen.forward(60)
        racketPen.backward(20)
        racketPen.begin_fill()
        for i in range(30):
            racketPen.left(3)
            racketPen.forward(1)
        racketPen.right(180)
        racketPen.forward(20)
        racketPen.right(90)
        racketPen.forward(20)
        racketPen.end_fill()
        racketPen.backward(20)
        racketPen.begin_fill()
        for i in range(2):
            racketPen.forward(60)
            racketPen.left(90)
            racketPen.forward(15)
            racketPen.left(90)
        racketPen.end_fill()
        racketPen.left(90)
        racketPen.forward(15)
        racketPen.left(90)
        racketPen.backward(18)
        racketPen.begin_fill()
        for i in range(30):
            racketPen.right(3)
            racketPen.forward(1)
        racketPen.left(180)
        racketPen.forward(20)
        racketPen.left(90)
        racketPen.forward(20)
        racketPen.end_fill()
        racketPen.backward(20)
        racketPen.left(90)
        racketPen.forward(20)
        racketPen.color(rColor)
        racketPen.begin_fill()
        racketPen.left(20)
        for i in range(40):
            racketPen.left(4)
            racketPen.forward(3)
        racketPen.forward(20)
        for i in range(40):
            racketPen.left(4)
            racketPen.forward(3)
        racketPen.left(20)
        racketPen.forward(45)
        racketPen.end_fill()

    drawRacket("#d2213f")
    racketPen.penup()
    racketPen.home()
    racketPen.right(90)
    racketPen.forward(140)
    racketPen.left(90)
    racketPen.forward(-5)
    racketPen.forward(250)
    racketPen.left(90)
    drawRacket("#000000")
    racketPen.hideturtle()

def ball():
    ballPen = turtle.Turtle()
    ballPen.color("#ff8533")
    ballPen.pensize(2)
    ballPen.speed(10)

    ballPen.penup()
    ballPen.right(90)
    ballPen.forward(115)
    ballPen.left(90)
    ballPen.forward(-5)
    ballPen.forward(172.5)
    ballPen.down()
    ballPen.begin_fill()
    for i in range(45):
        ballPen.left(8)
        ballPen.forward(1.5)
    ballPen.end_fill()
    ballPen.hideturtle()

def frame2():
    framePen2 = turtle.Turtle()
    framePen2.color("#00004d", "#cce5ff")
    framePen2.pensize(5)
    framePen2.speed(10)
    framePen2.showturtle()
    framePen2.penup()

    framePen2.right(90)
    framePen2.forward(300)
    framePen2.left(90)
    framePen2.forward(-5)
    framePen2.down()
    framePen2.left(180)

    framePen2.down()
    framePen2.begin_fill()
    framePen2.forward(345)
    framePen2.right(90)
    framePen2.forward(495)
    framePen2.right(90)
    framePen2.forward(345)
    framePen2.right(90)
    framePen2.forward(495)
    framePen2.end_fill()
    framePen2.hideturtle()

def text():
    penText = turtle.Turtle()
    penText.penup()
    penText.color("#00004d")
    penText.speed(6)
    penText.right(90)
    penText.forward(-120)
    penText.left(90)
    penText.forward(-5)
    penText.forward(30)

    penText.write("Dear Dad,", font=("Verdana", 25, "normal"))
    penText.right(90)
    penText.forward(73)
    penText.left(90)
    penText.write("Happy Father's Day!", font=("Verdana", 25, "normal"))
    penText.right(90)
    penText.forward(53)
    penText.left(90)
    penText.write("Thank you for always", font=("Verdana", 25, "normal"))
    penText.right(90)
    penText.forward(53)
    penText.left(90)
    penText.write("playing table tennis", font=("Verdana", 25, "normal"))
    penText.right(90)
    penText.forward(53)
    penText.left(90)
    penText.write("and soccer with me!", font=("Verdana", 25, "normal"))
    penText.right(90)
    penText.forward(110)
    penText.left(90)
    penText.write("Love,", font=("Verdana", 26, "normal"))
    penText.right(90)
    penText.forward(40)
    penText.left(90)
    penText.write("Ryan", font=("Verdana", 26, "normal"))
    penText.right(90)
    penText.forward(50)
    penText.left(90)

    penText.hideturtle()

frame()
wishes()
table()
rackets()
ball()
moveOn = str(input("If you are ready to read the card then type y: "))
if moveOn == "y":
    frame()
    frame2()
    text()
wn.mainloop()


from socket import *
import sys
from time import sleep

# 具体功能类
class FtpClient:
    def __init__(self, sockfd):
        self.sockfd = sockfd

    def do_list(self):
        self.sockfd.send(b"L")  # 发送请求
        # 等待回复
        data = self.sockfd.recv(128).decode()
        # ok表示请求成功，否则打印请求失败的原因
        if data == "ok":
            # 接收文件列表，若要防止太大，可使用循环接收
            data = self.sockfd.recv(4096)
            print(data.decode())

        else:
            print(data)

    def do_download(self, fn):
        # 发送请求
        self.sockfd.send(("D " + fn).encode())
        data = self.sockfd.recv(128).decode()
        if data == "ok":
            fd = open(fn, "wb+")
            # 接收内容写入文件
            while True:
                data = self.sockfd.recv(1024)
                if data == b"##":
                    break
                fd.write(data)
            fd.close()
        else:
            print(data)

    def do_upload(self, fn):
        try:
            fd = open(fn, "rb+")
        except Exception:
            print("File not found.")
            return

        fn = fn.split("/")[-1]
        self.sockfd.send(("U " + fn).encode())
        data = self.sockfd.recv(128).decode()
        if data == "ok":
            while True:
                data = fd.read(1024)
                if not data:
                    sleep(0.1)
                    self.sockfd.send(b"##")
                    break
                self.sockfd.send(data)
            fd.close()
        else:
            print(data)

    def do_quit(self):
        self.sockfd.send(b"Q")
        self.sockfd.close()
        sys.exit("Thank you.")

# 向服务器发起请求的函数
def request(s):
    ftp = FtpClient(s)
    while True:
        print("\n=========== 命令选项 ===========")
        print("************* list ************")
        print("*********** download **********")
        print("************ upload ***********")
        print("************* quit ************")
        print("===============================\n")

        cmd = input("Enter command:")
        if cmd.strip() == "list":
            s.send(cmd.encode())
            ftp.do_list()
        elif cmd.strip().split(" ")[0] == "download":
            file_name = cmd.split(" ")[-1]
            ftp.do_download(file_name)
        elif cmd.strip().split(" ")[0] == "upload":
            file_name = cmd.split(" ")[-1]
            ftp.do_upload(file_name)
        elif cmd.strip() == "quit":
            ftp.do_quit()
        else:
            pass

# 网络连接
def main():
    # 服务器地址
    ADDR = ("127.0.0.1", 8888)

    sockfd = socket(AF_INET, SOCK_STREAM)

    # 请求连接
    try:
        sockfd.connect(ADDR)
    except Exception as e:
        print("Connecting to server failed.")
        return
    else:
        print("""
                *****************************
                    Data    File    Image
                *****************************
        """)
        cls = input("Enter file type:")
        if cls not in ["Data", "File", "Image"]:
            print("Sorry! Input type error!")
            return
        else:
            sockfd.send(cls.encode())
            request(sockfd)

if __name__ == "__main__":
    main()


class Guitar():
    def __init__(self, colour, string_no):
        self.colour = colour
        self.string_no = string_no

    def play(self):
        print("NOISE!")

ana_guitar = Guitar("Blue", 6)

ana_guitar.play()

example_variable_1 = 3.14152

print(type(example_variable_1))

example_variable2 = "Hello World"

print(type(example_variable2))

var = 'string example blah blah'

example_list = [
    1, 2, 3, 4, 5, 6, 7, 8
]

some_list = []
print(type(example_list))

example_list.pop()

print(ana_guitar)


import requests
import json
import datetime
import pandas
import http.client
import traceback
from utils import parse_prices
from utils import parse_prices_line
from constants import ts_client_secret
from constants import ts_client_id
from constants import ts_api_auth_url

def get_token(token, auth_code):
  res = requests.post(ts_api_auth_url, data = {
    "grant_type": "authorization_code",
    "client_id": ts_client_id,
    "redirect_uri": "https://api-ml-web-tool.herokuapp.com/account/tsapi_callback/" + token,
    "client_secret": ts_client_secret,
    "code": auth_code,
    "response_type": "token"
  })

  if res.status_code == 200:
    return res.json()
  else:
    print (res)
  return None

def get_access_token(refresh_token):
  res = requests.post(ts_api_auth_url, data = {
    "grant_type": "refresh_token",
    "client_id": ts_client_id,
    "redirect_uri": "http://ec2-52-201-19-122.compute-1.amazonaws.com:3002/app/ml-app", #https://ml-web-tool.herokuapp.com/
    "client_secret": ts_client_secret,
    "refresh_token": refresh_token,
    "response_type": "token"
  })

  if res.status_code == 200:
    return res.json()['access_token']
  return None

def load_ts_prices(access_token, symbol, frequency, start_date):
  from utils import convert_frequency
  unit, interval = convert_frequency(frequency)

  symbol = symbol.replace('aATt', '@')
  dt_format = '%m-%d-%Y'
  today = datetime.datetime.today()
  today_str = today.strftime(dt_format)
  read_date = datetime.datetime.strptime(start_date, dt_format)
  data = []
  do_break = False
  while not do_break:
    read_date_str = read_date.strftime(dt_format)
    next_date_str = today_str
    if (today-read_date).days > 365:
      next_date = read_date + datetime.timedelta(days=365)
      next_date_str = next_date.strftime(dt_format)
      read_date = next_date + datetime.timedelta(days=1)
    else:
      do_break = True

    url = "https://api.tradestation.com/v2/stream/barchart/" + symbol + "/" + str(interval) + "/" + unit + "/" + read_date_str + "/" + next_date_str + "?access_token=" + access_token
    try:
      res = requests.get(url, stream=True)
      if res.status_code == 200:
        for line in res.iter_lines():
          if line is None or len(line) == 0:
            continue
          d = parse_prices_line(line.decode("utf-8"))
          if d is None:
            continue
          if len(d) == 0:
            break
          data.append(d)
      else:
        print("status_code = " + str(res.status_code))
        continue
    except:
      traceback.print_exc()
      continue
  if len(data) == 0:
    return None
  df = pandas.DataFrame(data, columns = ['Date', 'Time', 'Open', 'High', 'Low', 'Close', 'Vol', 'OI'])
  return df

if __name__ == "__main__":
  from constants import test_key
  access_token = get_access_token(test_key)
  df = load_ts_prices(access_token, '@BTC', '15m', '10-26-2020')
  print(df)


#!/usr/bin/env python
# -*- coding:utf-8 -*-
#@Time    :    2020/5/11 0011 23:56
#@Author  :    tb_youth
#@FileName:    childFatherWindow.py
#@SoftWare:    PyCharm
#@Blog    :    https://blog.csdn.net/tb_youth

from PyQt5.QtWidgets import QWidget, QDialog, QApplication, QVBoxLayout
from PyQt5.QtWidgets import QPushButton
from PyQt5.QtCore import Qt

class ChildWidget(QDialog):
    def __init__(self,parent=None):
        super().__init__(parent)
        self.resize(500,500)
        self.setWindowTitle('Child')
        self.setWindowFlags(Qt.Dialog | Qt.WindowCloseButtonHint|Qt.WindowMaximizeButtonHint|Qt.WindowMinimizeButtonHint)

class ParentWidget(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.resize(600,600)
        self.setWindowTitle('Parent')
        self.btn = QPushButton('show child')
        self.child_widget = ChildWidget(self)
        layout = QVBoxLayout()
        layout.addWidget(self.btn)
        self.setLayout(layout)
        self.btn.clicked.connect(self.onClickedBtn)

    def onClickedBtn(self):
        self.child_widget.exec_()

if __name__=='__main__':
    import sys
    app = QApplication(sys.argv)
    w = ParentWidget()
    w.show()
    sys.exit(app.exec_())


# ----------------------------------------------------------------------------#
# Imports
# ----------------------------------------------------------------------------#
import sys
import json
import dateutil.parser
import babel
from flask import (
    Flask,
    render_template,
    request,
    Response,
    flash,
    redirect,
    url_for)
from flask_moment import Moment
from flask_sqlalchemy import SQLAlchemy
import logging
from logging import Formatter, FileHandler
from flask_wtf import Form
from forms import *
from flask_migrate import Migrate

from config import SQLALCHEMY_DATABASE_URI

# ----------------------------------------------------------------------------#
# App Config.
# ----------------------------------------------------------------------------#

app = Flask(__name__)
moment = Moment(app)
app.config.from_object('config')
app.config['SQLALCHEMY_DATABASE_URI'] = SQLALCHEMY_DATABASE_URI
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)

migrate = Migrate(app, db)
current_time = datetime.now()

# ----------------------------------------------------------------------------#
# Models.
# ----------------------------------------------------------------------------#

class Venue(db.Model):
    __tablename__ = 'venue'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String, nullable=False)
    city = db.Column(db.String(120), nullable=False)
    state = db.Column(db.String(120), nullable=False)
    address = db.Column(db.String(120))
    phone = db.Column(db.String(120))
    image_link = db.Column(db.String(500))
    facebook_link = db.Column(db.String(120))
    website = db.Column(db.String(120))
    genres = db.Column(db.ARRAY(db.String(120)))
    seeking_talent = db.Column(db.Boolean, nullable=False, default=False)
    seeking_description = db.Column(db.String(500), default=None)
    shows = db.relationship('Show', backref='venue', lazy=True)

    def __init__(self, name, city, state, address, phone, genres, image_link=None, facebook_link=None, website=None,
                 seeking_talent=False, seeking_description=None):
        self.name = name
        self.city = city
        self.state = state
        self.address = address
        self.phone = phone
        self.image_link = image_link
        self.facebook_link = facebook_link
        self.website = website
        self.genres = genres
        self.seeking_talent = seeking_talent
        self.seeking_description = seeking_description

    def venue_data(self):
        return {
            "id": self.id,
            "name": self.name,
            "num_upcoming_shows": len([show.id for show in self.shows if show.start_time > current_time]),
        }

    def __repr__(self):
        return f'<class {self.__class__.__name__} {self.id} {self.name}>'

class Artist(db.Model):
    __tablename__ = 'artist'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String, nullable=False)
    city = db.Column(db.String(120), nullable=False)
    state = db.Column(db.String(120), nullable=False)
    phone = db.Column(db.String(120))
    genres = db.Column(db.ARRAY(db.String(120)))
    image_link = db.Column(db.String(500))
    facebook_link = db.Column(db.String(120))
    website = db.Column(db.String(120))
    seeking_venue = db.Column(db.Boolean, nullable=False, default=False)
    seeking_description = db.Column(db.String(1000), default=None)
    shows = db.relationship('Show', backref='artist', lazy=True)

    def __init__(self, name, city, state, phone, genres, image_link=None, facebook_link=None, website=None,
                 seeking_venue=False, seeking_description=None):
        self.name = name
        self.city = city
        self.state = state
        self.phone = phone
        self.genres = genres
        self.image_link = image_link
        self.facebook_link = facebook_link
        self.website = website
        self.seeking_venue = seeking_venue
        self.seeking_description = seeking_description

    def __repr__(self):
        return f'<class {self.__class__.__name__} {self.id} {self.name}>'

class Show(db.Model):
    __tablename__ = 'show'

    id = db.Column(db.Integer, primary_key=True)
    venue_id = db.Column(db.Integer, db.ForeignKey('venue.id'), nullable=False)
    artist_id = db.Column(db.Integer, db.ForeignKey('artist.id'), nullable=False)
    start_time = db.Column(db.DateTime, nullable=False)

    def __init__(self, venue_id, artist_id, start_time):
        self.venue_id = venue_id
        self.artist_id = artist_id
        self.start_time = start_time

    def artist_details(self):
        return {
            'artist_id': self.venue_id,
            'artist_name': self.artist.name,
            'artist_image_link': self.artist.image_link,
            'start_time': str(self.start_time)
        }

    def venue_details(self):
        return {
            'venue_id': self.venue_id,
            'venue_name': self.venue.name,
            'venue_image_link': self.venue.image_link,
            'start_time': str(self.start_time)
        }

    def show_details(self):
        return {
            "venue_id": self.venue_id,
            "venue_name": self.venue.name,
            "artist_id": self.artist_id,
            "artist_name": self.artist.name,
            "artist_image_link": self.artist.image_link,
            "start_time": str(self.start_time)
        }

    def __repr__(self):
        return f'<class {self.__class__.__name__} {self.id}>'

# ----------------------------------------------------------------------------#
# Filters.
# ----------------------------------------------------------------------------#

def format_datetime(value, format='medium'):
    date = dateutil.parser.parse(value)
    if format == 'full':
        format = "EEEE MMMM, d, y 'at' h:mma"
    elif format == 'medium':
        format = "EE MM, dd, y h:mma"
    return babel.dates.format_datetime(date, format)

app.jinja_env.filters['datetime'] = format_datetime

# ----------------------------------------------------------------------------#
# Controllers.
# ----------------------------------------------------------------------------#

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

#  Venues
#  ----------------------------------------------------------------

@app.route('/venues')
def venues():
    venues = Venue.query.group_by(Venue.id, Venue.state, Venue.city).all()
    venue_state_and_city = ""
    data = []

    # loop through venues to check for upcoming shows, city, states and venue information
    for venue in venues:
        if venue_state_and_city == venue.city + venue.state:
            data[len(data) - 1]["venues"].append(venue.venue_data())
        else:
            venue_state_and_city = venue.city + venue.state
            data.append({
                "city": venue.city,
                "state": venue.state,
                "venues": [venue.venue_data()]
            })
    return render_template('pages/venues.html', areas=data)

@app.route('/venues/search', methods=['POST'])
def search_venues():
    search_term = request.form.get('search_term', '')
    # Below is the search query which returns list of all matched venues
    venues_list = Venue.query.filter(Venue.name.ilike('%' + search_term + '%')).all()
    response = {
        "count": len(venues_list),
        "data": [venue.venue_data() for venue in venues_list]
    }
    return render_template('pages/search_venues.html', results=response, search_term=search_term)

@app.route('/venues/<int:venue_id>')
def show_venue(venue_id):
    venue = Venue.query.get(venue_id)
    upcoming_shows = [show.artist_details() for show in venue.shows if show.start_time >= current_time]
    past_shows = [show.artist_details() for show in venue.shows if show.start_time < current_time]
    data = {
        "id": venue.id,
        "name": venue.name,
        "genres": venue.genres,
        "address": venue.address,
        "city": venue.city,
        "state": venue.state,
        "phone": venue.phone,
        "website": venue.website,
        "facebook_link": venue.facebook_link,
        "seeking_talent": venue.seeking_talent,
        "seeking_description": venue.seeking_description,
        "image_link": venue.image_link,
        "past_shows": past_shows,
        "upcoming_shows": upcoming_shows,
        "past_shows_count": len(past_shows),
        "upcoming_shows_count": len(upcoming_shows),
    }
    return render_template('pages/show_venue.html', venue=data)

#  Create Venue
#  ----------------------------------------------------------------

@app.route('/venues/create', methods=['GET'])
def create_venue_form():
    form = VenueForm()
    return render_template('forms/new_venue.html', form=form)

@app.route('/venues/create', methods=['POST'])
def create_venue_submission():
    # TODO: insert form data as a new Venue record in the db, instead
    # TODO: modify data to be the data object returned from db insertion
    error = False
    try:
        form_data = request.form
        seeking_talent_data = True if form_data.get("seeking_talent") == "True" else False
        if not seeking_talent_data:
            seeking_description_data = None
        else:
            seeking_description_data = form_data.get("seeking_description")
        new_venue = Venue(
            name=form_data.get("name"),
            city=form_data.get("city"),
            state=form_data.get("state"),
            address=form_data.get("address"),
            phone=form_data.get("phone"),
            genres=form_data.getlist("genres"),
            facebook_link=form_data.get("facebook_link"),
            image_link=form_data.get("image_link"),
            website=form_data.get("website"),
            seeking_talent=seeking_talent_data,
            seeking_description=seeking_description_data
        )
        db.session.add(new_venue)
        db.session.commit()
    except:
        error = True
        db.session.rollback()
        print(sys.exc_info())
    finally:
        db.session.close()

    if error:
        flash('An error occurred. Venue ' + form_data.get("name") + ' could not be listed.')
    else:
        flash('Venue ' + request.form['name'] + ' was successfully listed!')
        return render_template('pages/home.html')

@app.route('/venues/<venue_id>', methods=['DELETE'])
def delete_venue(venue_id):
    # TODO: Complete this endpoint for taking a venue_id, and using
    # SQLAlchemy ORM to delete a record. Handle cases where the session commit could fail.
    try:
        venue = Venue.query.get(venue_id)
        venue_name = venue.name
        db.session.delete(venue)
        db.session.commit()
        flash('Venue ' + venue_name + ' was successfully deleted!')
    except:
        db.session.rollback()
        print(sys.exc_info())
    finally:
        db.session.close()
    # BONUS CHALLENGE: Implement a button to delete a Venue on a Venue Page, have it so that
    # clicking that button delete it from the db then redirect the user to the homepage
    return render_template('pages/home.html')

#  Artists
#  ----------------------------------------------------------------
@app.route('/artists')
def artists():
    data = [{"id": artist.id, "name": artist.name} for artist in Artist.query.all()]
    return render_template('pages/artists.html', artists=data)

@app.route('/artists/search', methods=['POST'])
def search_artists():
    search_term = request.form.get('search_term', '')
    req_artist_list = Artist.query.filter(Artist.name.ilike("%" + search_term + "%")).all()
    # Note: There is no point in giving "num_upcoming_shows" data in response. so, didn't add that data in response
    response = {
        "count": len(req_artist_list),
        "data": [{"id": artist.id, "name": artist.name} for artist in req_artist_list]
    }
    return render_template('pages/search_artists.html', results=response, search_term=search_term)

@app.route('/artists/<int:artist_id>')
def show_artist(artist_id):
    artist = Artist.query.get(artist_id)
    upcoming_shows = [show.venue_details() for show in artist.shows if show.start_time >= current_time]
    past_shows = [show.venue_details() for show in artist.shows if show.start_time < current_time]

    data = {
        "id": artist.id,
        "name": artist.name,
        "genres": artist.genres,
        "city": artist.city,
        "state": artist.state,
        "phone": artist.phone,
        "website": artist.website,
        "facebook_link": artist.facebook_link,
        "seeking_venue": artist.seeking_venue,
        "seeking_description": artist.seeking_description,
        "image_link": artist.image_link,
        "past_shows": past_shows,
        "upcoming_shows": upcoming_shows,
        "past_shows_count": len(past_shows),
        "upcoming_shows_count": len(upcoming_shows),
    }
    return render_template('pages/show_artist.html', artist=data)

#  Update
#  ----------------------------------------------------------------
@app.route('/artists/<int:artist_id>/edit', methods=['GET'])
def edit_artist(artist_id):
    form = ArtistForm()
    artist_data = Artist.query.get(artist_id)
    artist = {
        "id": artist_data.id,
        "name": artist_data.name,
        "genres": artist_data.genres,
        "city": artist_data.city,
        "state": artist_data.state,
        "phone": artist_data.phone,
        "website": artist_data.website,
        "facebook_link": artist_data.facebook_link,
        "seeking_venue": artist_data.seeking_venue,
        "seeking_description": artist_data.seeking_description,
        "image_link": artist_data.image_link
    }
    return render_template('forms/edit_artist.html', form=form, artist=artist)

@app.route('/artists/<int:artist_id>/edit', methods=['POST'])
def edit_artist_submission(artist_id):
    # TODO: take values from the form submitted, and update existing
    # artist record with ID <artist_id> using the new attributes
    error = False
    try:
        data = request.form
        seeking_venue_data = True if data.get("seeking_venue") == "True" else False
        if not seeking_venue_data:
            seeking_description_data = None
        else:
            seeking_description_data = data.get("seeking_description")
        artist = Artist.query.get(artist_id)
        artist.name = data.get("name")
        artist.genres = data.getlist("genres")
        artist.city = data.get("city")
        artist.state = data.get("state")
        artist.phone = data.get("phone")
        artist.website = data.get("website")
        artist.facebook_link = data.get("facebook_link")
        artist.image_link = data.get("image_link")
        artist.seeking_venue = seeking_venue_data
        artist.seeking_description = seeking_description_data
        db.session.commit()
    except:
        error = True
        db.session.rollback()
        print(sys.exc_info())
    finally:
        db.session.close()

    if error:
        flash('An error occurred while updating ' + request.form['name'])
        return redirect(url_for('show_artist', artist_id=artist_id))
    else:
        flash('Artist ' + request.form['name'] + ' was successfully updated!')
        return redirect(url_for('show_artist', artist_id=artist_id))

@app.route('/venues/<int:venue_id>/edit', methods=['GET'])
def edit_venue(venue_id):
    form = VenueForm()
    venue_data = Venue.query.get(venue_id)
    venue = {
        "id": venue_data.id,
        "name": venue_data.name,
        "genres": venue_data.genres,
        "address": venue_data.address,
        "city": venue_data.city,
        "state": venue_data.state,
        "phone": venue_data.phone,
        "website": venue_data.website,
        "facebook_link": venue_data.facebook_link,
        "seeking_talent": venue_data.seeking_talent,
        "seeking_description": venue_data.seeking_description,
        "image_link": venue_data.image_link
    }
    return render_template('forms/edit_venue.html', form=form, venue=venue)

@app.route('/venues/<int:venue_id>/edit', methods=['POST'])
def edit_venue_submission(venue_id):
    # TODO: take values from the form submitted, and update existing
    # venue record with ID <venue_id> using the new attributes
    error = False
    try:
        venue = Venue.query.get(venue_id)
        form_data = request.form
        seeking_talent_data = True if form_data.get("seeking_talent") == "True" else False
        if not seeking_talent_data:
            seeking_description_data = None
        else:
            seeking_description_data = form_data.get("seeking_description")
        print("form_data", form_data)
        venue.name = form_data.get("name")
        venue.city = form_data.get("city")
        venue.state = form_data.get("state")
        venue.address = form_data.get("address")
        venue.phone = form_data.get("phone")
        venue.genres = form_data.getlist("genres")
        venue.facebook_link = form_data.get("facebook_link")
        venue.image_link = form_data.get("image_link")
        venue.website = form_data.get("website")
        venue.seeking_talent = seeking_talent_data
        venue.seeking_description = seeking_description_data
        db.session.commit()
    except:
        error = True
        db.session.rollback()
        print(sys.exc_info())
    finally:
        db.session.close()

    if error:
        flash('An error occurred while updating ' + request.form['name'])
        return redirect(url_for('show_venue', venue_id=venue_id))
    else:
        flash('Venue ' + request.form['name'] + ' was successfully updated!')
        return redirect(url_for('show_venue', venue_id=venue_id))

#  Create Artist
#  ----------------------------------------------------------------

@app.route('/artists/create', methods=['GET'])
def create_artist_form():
    form = ArtistForm()
    return render_template('forms/new_artist.html', form=form)

@app.route('/artists/create', methods=['POST'])
def create_artist_submission():
    # called upon submitting the new artist listing form
    # TODO: insert form data as a new Venue record in the db, instead
    # TODO: modify data to be the data object returned from db insertion
    error = False
    try:
        form_data = request.form
        seeking_venue_data = True if form_data.get("seeking_venue") == "True" else False
        if not seeking_venue_data:
            seeking_description_data = None
        else:
            seeking_description_data = form_data.get("seeking_description")
        new_artist = Artist(
            name=form_data.get("name"),
            city=form_data.get("city"),
            state=form_data.get("state"),
            phone=form_data.get("phone"),
            genres=form_data.getlist("genres"),
            image_link=form_data.get("image_link"),
            website=form_data.get("website"),
            seeking_venue=seeking_venue_data,
            seeking_description=seeking_description_data
        )
        db.session.add(new_artist)
        db.session.commit()
    except:
        error = True
        db.session.rollback()
        print(sys.exc_info())
    finally:
        db.session.close()

    if error:
        flash('An error occurred. Artist ' + form_data.get("name") + ' could not be listed.')
        return render_template('pages/home.html')
    else:
        flash('Artist ' + form_data.get("name") + ' was successfully listed!')
        return render_template('pages/home.html')

#  Shows
#  ----------------------------------------------------------------

@app.route('/shows')
def shows():
    data = [show.show_details() for show in Show.query.order_by(Show.start_time.desc()).all()]
    return render_template('pages/shows.html', shows=data)

@app.route('/shows/create')
def create_shows():
    # renders form. do not touch.
    form = ShowForm()
    return render_template('forms/new_show.html', form=form)

@app.route('/shows/create', methods=['POST'])
def create_show_submission():
    # called to create new shows in the db, upon submitting new show listing form
    # TODO: insert form data as a new Show record in the db, instead
    error = False
    try:
        form = ShowForm()
        form_data = request.form
        artist = Artist.query.get(form_data.get('artist_id'))
        if not artist:
            flash(f"Artist with given id {form_data.get('artist_id')} not exists!!!")
            return redirect('/shows/create')
        venue = Venue.query.get(form_data.get('venue_id'))
        if not venue:
            flash(f"Venue with given id {form_data.get('venue_id')} not exists!!!")
            return redirect('/shows/create')
        new_show = Show(
            venue_id=form_data.get('venue_id'),
            artist_id=form_data.get('artist_id'),
            start_time=form_data.get('start_time')
        )
        db.session.add(new_show)
        db.session.commit()
        # on successful db insert, flash success
        flash('Show was successfully listed!')
    except:
        error = True
        db.session.rollback()
        print(sys.exc_info())
    finally:
        db.session.close()

    if error:
        flash('An error occurred. Show could not be listed.')
    return render_template('pages/home.html')

@app.errorhandler(404)
def not_found_error(error):
    return render_template('errors/404.html'), 404

@app.errorhandler(500)
def server_error(error):
    return render_template('errors/500.html'), 500

if not app.debug:
    file_handler = FileHandler('error.log')
    file_handler.setFormatter(
        Formatter('%(asctime)s %(levelname)s: %(message)s [in %(pathname)s:%(lineno)d]')
    )
    app.logger.setLevel(logging.INFO)
    file_handler.setLevel(logging.INFO)
    app.logger.addHandler(file_handler)
    app.logger.info('errors')

# ----------------------------------------------------------------------------#
# Launch.
# ----------------------------------------------------------------------------#

# Default port:
if __name__ == '__main__':
    app.run()

# Or specify port manually:
'''
if __name__ == '__main__':
    port = int(os.environ.get('PORT', 5000))
    app.run(host='0.0.0.0', port=port)
'''


from math import *
import gc
import pyglet
from pyglet.gl import *
import Eco

screen = None
mw, mh, sep = 2,2,1

circle_verts = [0,0]
circle_numpoints = 1

circle_radius = 0
live_color = [0, 255, 0]
sleep_color = [255, 0, 0]

def setup (w, h):
	global screen
	global circle_verts
	global circle_numpoints

	for y in range(1, int(circle_radius) + 1):
		x_boundary = sqrt(circle_radius*circle_radius - y*y)
		for x in range (1, int(x_boundary) + 1):
			circle_verts += [ x,  y]
			circle_verts += [-x,  y]
			circle_verts += [ x, -y]
			circle_verts += [-x, -y]
			circle_verts += [ 0,  y]
			circle_verts += [ 0, -y]
			circle_numpoints += 6

	for x in range(1, int(circle_radius) + 1):
		circle_verts += [ x, 0]
		circle_verts += [-x, 0]
		circle_numpoints += 2

	screen = pyglet.window.Window (width = w + 2*mw, height = h + 2*mh, caption = 'Game of Life')

class World:
	def __init__ (self, w, h, cell_d, cont, seeds = None):
		self.w = w
		self.h = h
		self.cell_d = cell_d
		self.width = mw + w*(cell_d + sep) + mw - sep
		self.height = mh + h*(cell_d + sep) + mw - sep

		self.draw_batch = pyglet.graphics.Batch ()
		self.verts = dict ()

		self.ecosys     = [[Eco.CellEntity (x, y, self.spawn, seeds[x][y] if seeds is not None else False) for y in range (h)] for x in range(w)]
		self.ecosys_pst = [[seeds[x][y] if seeds is not None else False for y in range (h)] for x in range(w)]

		self.cont     = cont
		self.hijacked = False

	@property
	def IsHijacked (self):
		return self.hijacked

	def GodBearAHandIn (self):
		self.hijacked = True

	def GodLeave (self):
		self.hijacked = False

	@property
	def EcoSys (self):
		return self.ecosys

	@property
	def EcoState (self):
		return self.ecosys_pst

	def check_neiboughs (self, x, y):
		alive_around = 0
		cands = [[x-1,y-1],[x,y-1],[x+1,y-1],
		         [x-1,y  ],[x+1,y],
		         [x-1,y+1],[x,y+1],[x+1,y+1]]
		for (cand_x,cand_y) in cands:
			if self.cont:
				sample_x = self.w - 1 if cand_x < 0 else (0 if cand_x == self.w else cand_x)
				sample_y = self.h - 1 if cand_y < 0 else (0 if cand_y == self.h else cand_y)
				alive_around += 1 if self.EcoState[sample_x][sample_y] else 0
			else:
				if (0 <= cand_x < self.w) and (0 <= cand_y < self.h):
					alive_around += 1 if self.EcoState[cand_x][cand_y] else 0

		return alive_around

	def record (self):
		self.ecosys_pst = [[self.EcoSys[x][y].IsAlive for y in range (0, self.h)] for x in range(0, self.w)]

	def spawn (self, x, y):
		if x not in self.verts:
			self.verts[x] = dict ()
		if y not in self.verts[x]:
			center = [mw + sep + x*(self.cell_d + sep) + circle_radius, mh + sep + y*(self.cell_d + sep) + circle_radius]
			self.verts[x][y] = [circle_verts[i] + center[i % 2] for i in range(len(circle_verts))]

		return self.draw_batch.add (circle_numpoints, GL_POINTS, None, ('v2f', self.verts[x][y]))

	def draw (self):
		if not self.IsHijacked:
			glColor3f(live_color[0], live_color[1], live_color[2])
		else:
			glColor3f(sleep_color[0], sleep_color[1], sleep_color[2])

		self.draw_batch.draw ()

	def generate (self):
		for x in range(self.w):
			for y in range(self.h):
				n_alive_neiboughs = self.check_neiboughs (x, y)
				if self.EcoState[x][y]:
					if (n_alive_neiboughs < 2) or (n_alive_neiboughs > 3):
						self.EcoSys[x][y].Die ()
				else:
					if (n_alive_neiboughs == 3):
						self.EcoSys[x][y].Resurrect ()

		self.record ()


class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        # 可以买卖多次  同一天只能买入或者卖出
        if len(prices) < 2: return 0
        # dp[i][0]: 表示第i天未持股状态下的最大利润
        # dp[i][0]: 表示第i天持股状态下的最大利润
        dp = [[0 for _ in range(2)]for _ in range(len(prices))]
        dp[0][1] = -prices[0]
        for i in range(1, len(prices)):
            dp[i][0] = max(dp[i-1][0], dp[i-1][1]+prices[i])
            dp[i][1] = max(dp[i-1][1], dp[i-1][0]-prices[i])
        return dp[-1][0]

6-动态规划/经典题型/买卖股票/Leetcode122. 买卖股票的最佳时机 II（44）.py


#!/usr/bin/python3
"""Student to JSON with filter"""

class Student:
    """class Student"""
    def __init__(self, first_name, last_name, age):
        """Instantiation

        Args:
          first_name: student's first name (str)
          last_name: student's last name (str)
          age: student's age (int)
        """
        self.first_name = first_name
        self.last_name = last_name
        self.age = age

    def to_json(self, attrs=None):
        """
        Retrieves the dict representation of the instance

        Args:
          attrs: list (None default)
        """
        result = {}

        if attrs is None:
            return self.__dict__

        for attr in attrs:
            value = self.__dict__.get(attr)
            if value is not None:
                result[attr] = value

        return result


import io
from http.server import BaseHTTPRequestHandler, HTTPStatus
from typing import AnyStr

from .http import simple_http_server
from sqlalchemy_media.helpers import copy_stream
from sqlalchemy_media.mimetypes_ import guess_type
from sqlalchemy_media.typing_ import FileLike

def mockup_http_static_server(content: bytes = b'Simple file content.',
                              content_type: str = None, **kwargs):
    class StaticMockupHandler(BaseHTTPRequestHandler):  # pragma: no cover
        def serve_text(self):
            self.send_header('Content-Type', "text/plain")
            self.send_header('Content-Length', str(len(content)))
            self.send_header('Last-Modified', self.date_time_string())
            self.end_headers()
            self.wfile.write(content)

        def serve_static_file(self, filename: AnyStr):
            self.send_header('Content-Type', guess_type(filename))
            with open(filename, 'rb') as f:
                self.serve_stream(f)

        def serve_stream(self, stream: FileLike):
            buffer = io.BytesIO()
            self.send_header(
                'Content-Length',
                str(copy_stream(stream, buffer))
            )
            self.end_headers()
            buffer.seek(0)
            try:
                copy_stream(buffer, self.wfile)
            except ConnectionResetError:
                pass

        def do_GET(self):
            self.send_response(HTTPStatus.OK)
            if isinstance(content, bytes):
                self.serve_text()
            elif isinstance(content, str):
                self.serve_static_file(content)
            else:
                self.send_header('Content-Type', content_type)
                self.serve_stream(content)

    return simple_http_server(StaticMockupHandler, **kwargs)


"""
`Aloe-Webdriver` includes several utilities for writing Selenium_ tests.
"""

import operator
from copy import copy
from functools import wraps
from time import time, sleep

try:
    reduce
except NameError:
    from functools import reduce  # pylint:disable=redefined-builtin,ungrouped-imports

from selenium.common.exceptions import NoSuchElementException

# pylint:disable=missing-docstring,redefined-outer-name,redefined-builtin
# pylint:disable=invalid-name

# Pylint cannot infer the attributes on world
# pylint:disable=no-member

def string_literal(content):
    """
    Choose a string literal that can wrap our string.

    If your string contains a ``\'`` the result will be wrapped in ``\"``.
    If your string contains a ``\"`` the result will be wrapped in ``\'``.

    Cannot currently handle strings which contain both ``\"`` and ``\'``.
    """

    if '"' in content and "'" in content:
        # there is no way to escape string literal characters in XPath
        raise ValueError("Cannot represent this string in XPath")

    if '"' in content:  # if it contains " wrap it in '
        content = "'%s'" % content
    else:  # wrap it in "
        content = '"%s"' % content

    return content

class ElementSelector(object):
    """
    A set of elements on a page matching an XPath query.

    :param browser: ``world.browser``
    :param str xpath: XPath query
    :param list elements: list of :class:`selenium.WebElement` objects
    :param bool filter_displayed: whether to only return displayed elements
    :param bool filter_enabled: whether to only return enabled elements

    Delays evaluation to batch the queries together, allowing operations on
    selectors (e.g. union) to be performed first, and then issuing as few
    requests to the browser as possible.

    One of `xpath` or `elements` must be passed. Passing `xpath` creates a
    selector delaying evaluation until it's needed, passing `elements`
    stores the elements immediately.

    Can behave as an iterable of elements or a single element by proxying all
    method calls, asserting that there is only one element selected.

    Can be combined using the addition operator (``+``) to `OR` XPath queries
    together.
    """

    def __init__(self, browser, xpath=None, elements=None,  # pylint:disable=too-many-arguments
                 filter_displayed=False, filter_enabled=False):
        """
        Initialise the selector.

        One of `xpath` or `elements` must be passed. Passing `xpath` creates a
        selector delaying evaluation until it's needed, passing `elements`
        stores the elements immediately.
        """
        self.browser = browser

        if xpath is None and elements is None:
            raise ValueError("Must supply either xpath or elements.")

        if xpath is not None:
            self.xpath = xpath
        else:
            self._elements_cached = elements

        self.filter_displayed = filter_displayed
        self.filter_enabled = filter_enabled

    @property
    def evaluated(self):
        """Whether the selector has already been evaluated."""

        return hasattr(self, '_elements_cached')

    def filter(self, displayed=False, enabled=False):
        """
        Filter elements by visibility and enabled status.

        :param displayed: whether to filter out invisible elements
        :param enabled: whether to filter out disabled elements

        Returns: an :class:`ElementSelector`
        """

        if self.evaluated:
            # Filter elements one by one
            result = self

            if displayed:
                result = ElementSelector(
                    result.browser,
                    elements=[e for e in result if e.is_displayed()]
                )

            if enabled:
                result = ElementSelector(
                    result.browser,
                    elements=[e for e in result if e.is_enabled()]
                )

        else:
            result = copy(self)
            if displayed:
                result.displayed = True
            if enabled:
                result.enabled = True

        return result

    def _select(self):
        """Fetch the elements from the browser."""

        for element in self.browser.find_elements_by_xpath(self.xpath):
            if self.filter_displayed:
                if not element.is_displayed():
                    continue

            if self.filter_enabled:
                if not element.is_enabled():
                    continue

            yield element

    def _elements(self):
        """
        The cached list of elements.
        """
        if not self.evaluated:
            setattr(self, '_elements_cached', list(self._select()))
        return self._elements_cached

    def __add__(self, other):
        """
        Return a union of the two selectors.

        Where possible, avoid evaluating either selector to batch queries.
        """

        if not self.evaluated \
                and isinstance(other, ElementSelector) \
                and not other.evaluated \
                and self.filter_displayed == other.filter_displayed \
                and self.filter_enabled == other.filter_enabled:
            # Both summands are delayed, return a new delayed selector
            return ElementSelector(
                self.browser,
                xpath=self.xpath + '|' + other.xpath,
                filter_displayed=self.filter_displayed,
                filter_enabled=self.filter_enabled,
            )
        else:
            # Have to evaluate everything now
            # other can be either an already evaluated ElementSelector, a list
            # or a single element
            try:
                other = list(other)
            except TypeError:
                other = [other]

            return ElementSelector(self.browser, elements=list(self) + other)

    # The class behaves as a container for the elements, fetching the list from
    # the browser on the first attempt to enumerate itself.

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

    def __getitem__(self, key):
        return self._elements()[key]  # pylint:disable=unsubscriptable-object

    def __iter__(self):
        for el in self._elements():  # pylint:disable=not-an-iterable
            yield el

    def __nonzero__(self):
        return bool(self._elements())

    def __getattr__(self, attr):
        """
        Delegate all calls to the only element selected.
        """

        if attr == '_elements_cached':
            # Never going to be on the element
            raise AttributeError()

        assert len(self) == 1, \
            'Must be a single element, have {0}'.format(len(self))
        return getattr(self[0], attr)

def element_id_by_label(browser, label):
    """
    The ID of an element referenced by a `label`s ``for`` attribute. The label
    must be visible.

    :param browser: ``world.browser``
    :param label: label text to return the referenced element for

    Returns: ``for`` attribute value
    """
    label = ElementSelector(browser,
                            str('//label[contains(., %s)]' %
                                string_literal(label)))
    if not label:
        return False
    return label.get_attribute('for')

def field_xpath(field, attribute):
    """
    Field helper functions to locate select, textarea, and the other
    types of input fields (text, checkbox, radio)

    :param field: One of the values 'select', 'textarea', 'option', or
    'button-element' to match a corresponding HTML element (and to
    match a <button> in the case of 'button-element'). Otherwise a
    type to match an <input> element with a type=<field> attribute.

    :param attribute: An attribute to be matched against, or 'value'
    to match against the content within element being matched.
    """
    if field in ['select', 'textarea']:
        xpath = './/{field}[@{attr}=%s]'

    elif field == 'button-role':
        if attribute == 'value':
            xpath = './/*[@role="button"][contains(., %s)]'
        else:
            xpath = './/*[@role="button"][@{attr}=%s]'

    elif field == 'button-element':
        field = 'button'
        if attribute == 'value':
            xpath = './/{field}[contains(., %s)]'
        else:
            xpath = './/{field}[@{attr}=%s]'

    elif field == 'option':
        xpath = './/{field}[@{attr}=%s]'

    else:
        xpath = './/input[@{attr}=%s][@type="{field}"]'

    return xpath.format(field=field, attr=attribute)

def find_button(browser, value):
    """
    Find a button with the given value.

    Searches for the following different kinds of buttons:

        <input type="submit">
        <input type="reset">
        <input type="button">
        <input type="image">
        <button>
        <{a,p,div,span,...} role="button">

    Returns: an :class:`ElementSelector`
    """
    field_types = (
        'submit',
        'reset',
        'button-element',
        'button',
        'image',
        'button-role',
    )

    return reduce(
        operator.add,
        (find_field_with_value(browser, field_type, value)
         for field_type in field_types)
    )

def find_field_with_value(browser, field, value):
    return find_field_by_id(browser, field, value) + \
        find_field_by_name(browser, field, value) + \
        find_field_by_value(browser, field, value)

def find_option(browser, select_name, option_name):
    # First, locate the select
    select_box = find_field(browser, 'select', select_name)
    assert select_box, "Cannot find a '{}' select.".format(select_name)

    # Now locate the option
    option_box = find_field(select_box, 'option', option_name)
    if not option_box:
        # Locate by contents
        option_box = select_box.find_element_by_xpath(str(
            './/option[contains(., "%s")]' % option_name))
    return option_box

def find_field(browser, field_type, value):
    """
    Locate an input field.

    :param browser: ``world.browser``
    :param string field_type: a field type (i.e. `button`)
    :param string value: an id, name or label

    This first looks for `value` as the id of the element, else
    the name of the element, else as a label for the element.

    Returns: an :class:`ElementSelector`
    """
    return find_field_by_id(browser, field_type, value) + \
        find_field_by_name(browser, field_type, value) + \
        find_field_by_label(browser, field_type, value)

def find_any_field(browser, field_types, field_name):
    """
    Find a field of any of the specified types.

    :param browser: ``world.browser``
    :param list field_types: a list of field type (i.e. `button`)
    :param string value: an id, name or label

    Returns: an :class:`ElementSelector`

    See also: :func:`find_field`.
    """

    return reduce(
        operator.add,
        (find_field(browser, field_type, field_name)
         for field_type in field_types)
    )

def find_field_by_id(browser, field_type, id):
    """
    Locate the control input with the given ``id``.

    :param browser: ``world.browser``
    :param string field_type: a field type (i.e. `button`)
    :param string id: ``id`` attribute

    Returns: an :class:`ElementSelector`
    """
    return ElementSelector(
        browser,
        xpath=field_xpath(field_type, 'id') % string_literal(id),
        filter_displayed=True,
    )

def find_field_by_name(browser, field_type, name):
    """
    Locate the control input with the given ``name``.

    :param browser: ``world.browser``
    :param string field_type: a field type (i.e. `button`)
    :param string name: ``name`` attribute

    Returns: an :class:`ElementSelector`
    """
    return ElementSelector(
        browser,
        field_xpath(field_type, 'name') %
        string_literal(name),
        filter_displayed=True,
    )

def find_field_by_value(browser, field_type, name):
    """
    Locate the control input with the given ``value``. Useful for buttons.

    :param browser: ``world.browser``
    :param string field_type: a field type (i.e. `button`)
    :param string name: ``value`` attribute

    Returns: an :class:`ElementSelector`
    """
    xpath = field_xpath(field_type, 'value') % string_literal(name)
    elems = ElementSelector(
        browser,
        xpath=str(xpath),
        filter_displayed=True,
        filter_enabled=True,
    )

    # sort by shortest first (most closely matching)
    if field_type in ('button-element', 'button-role'):
        elems = sorted(elems, key=lambda elem: len(elem.text))
    else:
        elems = sorted(elems,
                       key=lambda elem: len(elem.get_attribute('value')))

    if elems:
        elems = [elems[0]]

    return ElementSelector(browser, elements=elems)

def find_field_by_label(browser, field_type, label):
    """
    Locate the control input that has a label pointing to it.

    :param browser: ``world.browser``
    :param string field_type: a field type (i.e. `button`)
    :param string label: label text

    This will first locate the label element that has a label of the given
    name. It then pulls the id out of the 'for' attribute, and uses it to
    locate the element by its id.

    Returns: an :class:`ElementSelector`
    """

    return ElementSelector(
        browser,
        xpath=field_xpath(field_type, 'id') %
        '//label[contains(., {0})]/@for'.format(
            string_literal(label)),
        filter_displayed=True,
    )

def option_in_select(browser, select_name, option):
    """
    Returns the Element specified by @option or None

    Looks at the real <select> not the select2 widget, since that doesn't
    create the DOM until we click on it.
    """

    select = find_field(browser, 'select', select_name)
    assert select, "Cannot find a '{}' select.".format(select_name)

    try:
        return select.find_element_by_xpath(str(
            './/option[normalize-space(text())=%s]' % string_literal(option)))
    except NoSuchElementException:
        return None

TIMEOUT = 15
CHECK_EVERY = 0.2

def wait_for(func):
    """
    A decorator to invoke a function, retrying on assertion errors for a
    specified time interval.

    Adds a kwarg `timeout` to `func` which is a number of seconds to try
    for (default 15).
    """

    @wraps(func)
    def wrapped(*args, **kwargs):
        timeout = kwargs.pop('timeout', TIMEOUT)

        start = None

        while True:
            try:
                return func(*args, **kwargs)
            except AssertionError:
                # The function took some time to test the assertion, however,
                # the result might correspond to the state of the world at any
                # point in time, perhaps earlier than the timeout. Therefore,
                # start counting time from the first assertion fail, not from
                # before the function was called.
                if not start:
                    start = time()
                if time() - start < timeout:
                    sleep(CHECK_EVERY)
                    continue
                raise

    return wrapped


# -*- coding: utf-8 -*-

import string

def validate_ISBN10(isbn):
    """
    Validate ISBN10 code. Returns the ISBN or False if is not valid.
    """
    isbn = isbn.replace("-", "").replace(" ", "")

    if len(isbn) == 10 and not [x for x in isbn if x not in (
            string.digits + "X")]:

        total = 0
        for i in range(9):
            total += int(isbn[i]) * (10 - i)
        z = (11 - (total % 11)) % 11
        if (z == 10 and isbn[-1] == 'X') or ("%d" % z == isbn[-1]):
            return isbn
        else:
            return False

def validate_ISBN13(isbn):
    """
    Validate ISBN13 code. Returns the ISBN or False if is not valid.
    """
    #El chequeo para ISBN de 13 digitos sale de:
    #ref: http://en.wikipedia.org/wiki/International_Standard_Book_Number#ISBN-13

    isbn = isbn.replace("-", "").replace(" ", "")

    if len(isbn) == 13 and not [x for x in isbn if x not in string.digits]:
        i = 1
        total = 0
        for n in isbn[:-1]:
            total = total + i * int(n)
            if i == 1: i = 3
            else: i = 1
        check = 10 - ( total % 10 )
        if check == int(isbn[-1]):
            return isbn
        else:
            return False

def validate_ISBN(isbn):
    """
    Validate ISBN13 or ISBN10 code. Returns the ISBN or False if any is valid.
    """
    return validate_ISBN10(isbn) or validate_ISBN13(isbn)