from urllib.request import Request, urlopen
from bs4 import BeautifulSoup
import requests
import json
import os
import argparse
import sys
import uuid

headers = {'User-Agent': 'Mozilla/5.0 (X11; Linux i686)'
                         ' AppleWebKit/537.17 (KHTML)'
                         ' Chrome/24.0.1312.27 Safari/537.17'}

def search(search_terms, number=15, size=None):
    """Search for images from Google Images.

    Args:
        search_terms(list): A list of image search terms.
        number(int): Number of images to download.
        size(str): Size of images to download, available options are
                   large, medium, icon.

    Returns:
        dict, a dictionary of links.
    """
    size_desig = {'large': 'l', 'medium': 'm', 'icon': 'i'}

    root = 'https://www.google.com/search?q='
    params_head = '&tbm=isch&tbs=isz:'
    params_tail = ',itp:photo,ic:color,ift:jpg'

    _links = {}

    for search_term in search_terms:
        _links[search_term] = []

        joined_search_term = '+'.join(search_term.split(' '))
        url = root + joined_search_term + params_head + 'm' + params_tail

        if size is not None:
            url = root + joined_search_term + params_head + size_desig[size] + params_tail

        req = Request(url, headers=headers)
        # noinspection PyBroadException
        try:
            source = urlopen(req).read()
        except Exception:
            continue

        soup = BeautifulSoup(source, 'html5lib')
        body = soup.body
        results = body.find_all('div', class_='rg_meta notranslate')

        for result in results:
            content = result.get_text()
            content_dict = json.loads(content)
            _links[search_term].append(content_dict['ou'])
            if len(_links[search_term]) == number:
                break
        print('Found {0} links for {1}'.format(len(_links[search_term]), search_term))

    return _links

def download(links, destination='images', categorize=True, to_home=True):
    """Download images given links

    Args:
        links(dict): Dictionary of links.
        destination(str): Destination to store the downloaded images.
        categorize(bool): Set to True to place downloaded contents in
            different folders, categorized by search terms.
        to_home(bool): Set to True to save images to the user's home
            directory instead of locally where the script is run.

    Returns:
        None
    """
    download_count = 0

    if to_home:
        destination = os.path.join(os.path.expanduser('~'), destination)

    if not os.path.isdir(destination):
        os.mkdir(destination)

    for category in links.keys():
        folder = destination
        if categorize:
            folder = os.path.join(destination, '_'.join(category.split(' ')))
            if not os.path.isdir(folder):
                os.mkdir(folder)
        try:
            for img_link in links[category]:
                img_name = img_link.split('/')[-1]
                # noinspection PyBroadException
                try:
                    req = requests.get(img_link, stream=True, headers=headers)
                except Exception:
                    continue
                try:
                    with open(os.path.join(folder, img_name), 'wb') as f:
                        f.write(req.content)
                except IOError:
                    continue
                download_count += 1

                file_name = os.path.join(folder, img_name)
                if not file_name.split('.')[-1] == 'jpg':
                    try:
                        os.rename(file_name, file_name + '.jpg')
                    except IOError:
                        os.rename(file_name, uuid.uuid4().hex + '.jpg')

                print('Downloaded image {}'.format(img_name))
        except KeyboardInterrupt:
            print('Terminated by user.')

    print('Download complete, total images downloaded: {}'.format(download_count))

if __name__ == '__main__':

    print('Downloading a large amount of images could take a while, if you wish to '
          'end the process, press Ctrl+C.')

    if sys.version_info[0] < 3:
        print('Python 3.x required')
        sys.exit()

    parser = argparse.ArgumentParser()
    parser.add_argument('--search-for', dest='search', type=str,
                        help='Search term for google image search')
    parser.add_argument('--number', dest='number', type=int, default=15,
                        help='Number of search results to return')
    parser.add_argument('--size', dest='size', type=str, default=None,
                        help='Size of image results')
    parser.add_argument('--destination', dest='destination', type=str, default='images',
                        help='Destination to store the searched results')
    parser.add_argument('--no-categorize', dest='categorize', action='store_false',
                        help='Use this flag to skip sorting results from different search'
                             ' terms into folders and save them under the same directory')
    parser.add_argument('--local', dest='to_home', action='store_false',
                        help='Use this flag if you want your images stored in a folder in '
                             'the same directory this script is run, other wise they will'
                             'be downloaded to your home directory')

    args = parser.parse_args()

    search_list = args.search.split(',')

    links = search(search_terms=search_list, number=args.number, size=args.size)
    download(links, destination=args.destination, categorize=args.categorize, to_home=args.to_home)


# invert a binary tree

class Node:
    def __init__(self, value, left=None, right=None):
        self.left = left
        self.right = right
        self.value = value

def print_tree(root):
    if root is not None:
        print_tree(root.left)
        print(root.value)
        print_tree(root.right)

def reverse(root):
    if root:
        root.left, root.right = root.right, root.left
        reverse(root.left)
        reverse(root.right)
    return root

root1 = Node(4, Node(2, Node(1), Node(3)), Node(7, Node(6), Node(9)))
print_tree(reverse(root1))


"""
Hierarchical triple orbit simultaneously fit with RV, astrometry, and disk constraints for both tight inner binary and wide outer binary: inner: `parallax`, `P_A`, `a_A_ang`, `M_Ab`, `e_A`, `i_A`, `omega_Aa`, `Omega_Aa`,  outer: `P_B`, `a_B_ang`, `e_AB`, `i_AB`, `omega_A`, `Omega_A`, `gamma_AB`. `M_A` is derived from inner orbit and fed to outer orbit.  `gamma_A` is essentially the RV prediction of A, and is derived from outer orbit and fed to the inner orbit. This has 15 orbital parameters. Adding 4 RV offsets, 2 * 4 RV jitter terms, and 2 astrometric jitter terms makes it 30 parameters total.

We want to preserve the option of doing a joint fit but without the prior from the disk fit.

To do that, just switch the directory output to `stars-only` and comment out the disk portion of the model definition.
"""

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib import rcParams

rcParams["savefig.dpi"] = 100
rcParams["figure.dpi"] = 100
rcParams["font.size"] = 16
rcParams["text.usetex"] = False
rcParams["font.family"] = ["sans-serif"]
rcParams["font.sans-serif"] = ["cmss10"]
rcParams["axes.unicode_minus"] = False

from astropy.time import Time
from astropy.io import ascii
from astropy import units as u
from astropy import constants
import astropy

# load the exoplanet part
import pymc3 as pm
import theano.tensor as tt
import arviz as az

# rcParams["plot.max_subplots"] = 60

import corner

import exoplanet as xo
from exoplanet.distributions import Angle

from src.constants import *

# change to "stars-only/" if you remove the astrometric constraint
# outdir = "disk/"
outdir = "stars-only/"

# calculate posteriors on MA using the disk samples
flatchain = np.load("run10/flatchain.npy")
mass_samples = flatchain[:, 0]
MA_mean = np.mean(mass_samples)
MA_std = np.std(mass_samples)
print(f"{MA_mean:.2f} +/- {MA_std:.2f}")

# for now, subtract from all dates for start of astrometric timeseries
jd0 = 2448630.485039346

def get_arrays(asciiTable, errDict=None, jitter=False):
    """
    Reformat ascii tables into pure numpy arrays of the right dimension.
    """

    output = []

    for star in ["Aa", "Ab"]:

        # get the RVs
        rv = asciiTable["RV_" + star]

        if type(rv) is astropy.table.column.MaskedColumn:
            mask = ~rv.mask  # values we want to keep when indexing
        else:
            mask = np.ones(len(rv), dtype="bool")

        rv = np.ascontiguousarray(rv[mask])
        date = np.ascontiguousarray(asciiTable["HJD"][mask]) + 2400000 - jd0

        if errDict is None:
            err = np.ascontiguousarray(asciiTable["sigma_" + star][mask])
        else:
            err = np.ones(len(date), dtype=np.float64) * errDict[star]

        if jitter:
            err = (
                np.ones(len(date), dtype=np.float64) * 0.1
            )  # [km/s] assume a small error, since we'll infer.

        assert len(date) == len(rv), "date - rv length mismatch"
        assert len(date) == len(err), "date - err length mismatch"

        tup = (date, rv, err)

        output.append(tup)

    return output

# Do this to infer w/ jitter
jitter = True

# load all the data
data_cfa = ascii.read("../close/data/cfa.dat")
# cfa errors are provided in table
cfa1, cfa2 = get_arrays(data_cfa, jitter=jitter)

data_keck = ascii.read("../close/data/keck.dat", format="tab", fill_values=[("X", 0)])
err_keck = {"Aa": 0.63, "Ab": 0.85, "B": 0.59}  # km/s
keck1, keck2 = get_arrays(data_keck, err_keck, jitter=jitter)

data_feros = ascii.read("../close/data/feros.dat")
err_feros = {"Aa": 2.61, "Ab": 3.59, "B": 2.60}  # km/s
feros1, feros2 = get_arrays(data_feros, err_feros, jitter=jitter)

data_dupont = ascii.read("../close/data/dupont.dat", fill_values=[("X", 0)])
err_dupont = {"Aa": 1.46, "Ab": 2.34, "B": 3.95}  # km/s
dupont1, dupont2 = get_arrays(data_dupont, err_dupont, jitter=jitter)

data = [data_cfa, data_keck, data_feros, data_dupont]

# specifically load the B velocities
mask = ~data_keck["RV_B"].mask

keck3 = (
    np.ascontiguousarray(data_keck["HJD"][mask]) + 2400000 - jd0,
    np.ascontiguousarray(data_keck["RV_B"][mask]),
    0.2 * np.ones(np.sum(mask), dtype=np.float64),
)

# load the astrometric points for the close orbit

# keep in mind that the primary and secondary stars *could* be switched
# separation is in milliarcseconds
int_data = ascii.read("../close/data/int_data.dat")

astro_jd = int_data["epoch"][0] - jd0
rho_data = int_data["sep"][0] * 1e-3  # arcsec
rho_err = int_data["sep_err"][0] * 1e-3  # arcsec
theta_data = int_data["pa"][0] * deg  # radians
theta_err = int_data["pa_err"][0] * deg  # radians

anthonioz = (astro_jd, rho_data, rho_err, theta_data, theta_err)

# load the astrometry for the wide orbit
data = ascii.read(
    "../wide/data/visual_data_besselian.csv", format="csv", fill_values=[("X", "0")]
)

# convert years
jds = Time(np.ascontiguousarray(data["epoch"]), format="byear").jd - jd0

data["rho_err"][data["rho_err"].mask == True] = 0.05
data["PA_err"][data["PA_err"].mask == True] = 5.0

# convert all masked frames to be raw np arrays, since theano has issues with astropy masked columns
rho_data = np.ascontiguousarray(data["rho"], dtype=float)  # arcsec
rho_err = np.ascontiguousarray(data["rho_err"], dtype=float)

# the position angle measurements come in degrees in the range [0, 360].
# we need to convert this to radians in the range [-pi, pi]
theta_data = np.ascontiguousarray(data["PA"] * deg, dtype=float)
theta_data[theta_data > np.pi] -= 2 * np.pi

theta_err = np.ascontiguousarray(data["PA_err"] * deg)  # radians

wds = (jds, rho_data, rho_err, theta_data, theta_err)

def calc_Mtot(a, P):
    """
    Calculate the total mass of the system using Kepler's third law.

    Args:
        a (au) semi-major axis
        P (days) period

    Returns:
        Mtot (M_sun) total mass of system (M_primary + M_secondary)
    """

    day_to_s = (1 * u.day).to(u.s).value
    au_to_m = (1 * u.au).to(u.m).value
    kg_to_M_sun = (1 * u.kg).to(u.M_sun).value

    return (
        4
        * np.pi ** 2
        * (a * au_to_m) ** 3
        / (constants.G.value * (P * day_to_s) ** 2)
        * kg_to_M_sun
    )

def calc_a(Mtot, P):
    """
    Calculate the semi-major axis using Kepler's third law

    Args:
        Mtot (Msun) total mass
        P (days) period

    Returns:
        a (au)
    """

    day_to_s = (1 * u.day).to(u.s).value
    au_to_m = (1 * u.au).to(u.m).value
    kg_to_M_sun = (1 * u.kg).to(u.M_sun).value

    return (
        ((Mtot / kg_to_M_sun) * constants.G.value * (P * day_to_s) ** 2)
        / (4 * np.pi ** 2)
    ) ** (1 / 3) / au_to_m

zeros = np.zeros_like(wds[0])

xs_phase = np.linspace(0, 1, num=500)
t_data = np.linspace(-yr, wds[0][-1] + yr)

with pm.Model() as model:

    # We'll include the parallax data as a prior on the parallax value
    mparallax = pm.Normal("mparallax", mu=27.31, sd=0.12)  # milliarcsec GAIA DR2
    parallax = pm.Deterministic("parallax", 1e-3 * mparallax)  # arcsec

    a_ang_inner = pm.Uniform("a_ang_inner", 0.1, 10.0, testval=4.66)  # milliarcsec

    # the semi-major axis in au
    a_inner = pm.Deterministic("a_inner", 1e-3 * a_ang_inner / parallax)  # au

    logP_inner = pm.Uniform(
        "logP_inner", lower=0, upper=np.log(50.0), testval=np.log(34.879)
    )  # days
    P_inner = pm.Deterministic("P_inner", tt.exp(logP_inner))

    e_inner = pm.Uniform("e_inner", lower=0, upper=1, testval=0.63)

    omega_inner = Angle("omega_inner", testval=1.42)  # omega_Aa
    Omega_inner = Angle("Omega_inner", testval=1.99)

    cos_incl_inner = pm.Uniform("cos_incl_inner", lower=-1.0, upper=1.0, testval=0.67)
    incl_inner = pm.Deterministic("incl_inner", tt.arccos(cos_incl_inner))

    MAb = pm.Normal("MAb", mu=0.29, sd=0.5)  # solar masses

    t_periastron_inner = pm.Uniform(
        "t_periastron_inner", lower=4050.0, upper=4100.0, testval=4073.0
    )  # + 2400000 + jd0

    orbit_inner = xo.orbits.KeplerianOrbit(
        a=a_inner * au_to_R_sun,
        period=P_inner,
        ecc=e_inner,
        t_periastron=t_periastron_inner,
        omega=omega_inner,
        Omega=Omega_inner,
        incl=incl_inner,
        m_planet=MAb,
    )

    # derived properties from inner orbit
    MA = pm.Deterministic("MA", orbit_inner.m_total)
    MAa = pm.Deterministic("MAa", MA - MAb)

    # we expect the period to be somewhere in the range of 25 years,
    # so we'll set a broad prior on logP
    logP_outer = pm.Normal("logP_outer", mu=6.71, sd=1.0)  # yrs
    P_outer = pm.Deterministic("P_outer", tt.exp(logP_outer) * yr)  # days

    omega_outer = Angle("omega_outer", testval=-0.939)  # - pi to pi
    Omega_outer = Angle("Omega_outer", testval=-0.491)  # - pi to pi

    phi_outer = Angle("phi_outer", testval=0.63)

    n = 2 * np.pi * tt.exp(-logP_outer) / yr  # radians per day

    t_periastron_outer = pm.Deterministic(
        "t_periastron_outer", (phi_outer + omega_outer) / n
    )

    cos_incl_outer = pm.Uniform("cos_incl_outer", lower=-1.0, upper=1.0, testval=-0.60)
    incl_outer = pm.Deterministic("incl_outer", tt.arccos(cos_incl_outer))
    e_outer = pm.Uniform("e_outer", lower=0.0, upper=1.0, testval=0.03)
    gamma_outer = pm.Uniform(
        "gamma_outer", lower=0, upper=15, testval=10.0
    )  # km/s on CfA RV scale

    # We would like to use MB as a parameter, but we have already defined Mtot via the
    # semi-major axis and period, and we have already defined MA from the inner orbit.
    # Mtot = pm.Deterministic("Mtot", calc_Mtot(a_outer, P_outer))
    # MB = pm.Deterministic("MB", Mtot - MA) # solar masses
    PosNormal = pm.Bound(pm.Normal, lower=0.0)
    MB = PosNormal("MB", mu=0.3, sd=0.3, testval=0.5)
    Mtot = pm.Deterministic("Mtot", MA + MB)

    # instead, MB becomes a parameter, and then a_outer is calculated from Mtot and P_outer
    a_outer = pm.Deterministic("a_outer", calc_a(Mtot, P_outer))
    a_ang_outer = pm.Deterministic("a_ang_outer", a_outer * parallax)

    orbit_outer = xo.orbits.KeplerianOrbit(
        a=a_outer * au_to_R_sun,
        period=P_outer,
        ecc=e_outer,
        t_periastron=t_periastron_outer,
        omega=omega_outer,
        Omega=Omega_outer,
        incl=incl_outer,
        m_planet=MB,
    )

    # parameters to shift the RV scale onto the CfA scale
    offset_keck = pm.Normal("offsetKeck", mu=-1.6, sd=5.0)  # km/s
    offset_feros = pm.Normal("offsetFeros", mu=1.8, sd=5.0)  # km/s
    offset_dupont = pm.Normal("offsetDupont", mu=-0.57, sd=5.0)  # km/s

    def get_gamma_A(t):
        """
        Helper function to determine gamma of the inner orbit.

        Args:
            t: time to query

        Returns:
            gamma_A (t) : [km/s]
        """

        gamma_A = conv * orbit_outer.get_star_velocity(t)[2]

        return gamma_A

    # get the radial velocity predictions for RV B
    rv3_keck = (
        conv * orbit_outer.get_planet_velocity(keck3[0])[2] + gamma_outer + offset_keck
    )

    # since we have 4 instruments, we need to predict 4 different dataseries
    def get_RVs(t1, t2, offset):
        """
        Helper function for RVs.

        Args:
            t1: times to query for star 1
            t2 : times to query for star 2
            offset: (km/s)

        Returns:
            (rv1, rv2) [km/s] evaluated at those times with offset applied
       """
        # get the RV predictions
        # get_star_velocity and get_planet_velocity return (v_x, v_y, v_z) tuples,
        # so we only need the v_z vector
        # but, note that since +Z points towards the observer,
        # we actually want v_radial = -v_Z (see conv)
        rv1 = (
            conv * orbit_inner.get_star_velocity(t1)[2]
            + gamma_outer
            + get_gamma_A(t1)
            + offset
        )
        rv2 = (
            conv * orbit_inner.get_planet_velocity(t2)[2]
            + gamma_outer
            + get_gamma_A(t2)
            + offset
        )

        return (rv1, rv2)

    # expects m/s
    # dates are the first entry in each tuple of (date, rv, err)
    rv1_cfa, rv2_cfa = get_RVs(cfa1[0], cfa2[0], 0.0)
    rv1_keck, rv2_keck = get_RVs(keck1[0], keck2[0], offset_keck)
    rv1_feros, rv2_feros = get_RVs(feros1[0], feros2[0], offset_feros)
    rv1_dupont, rv2_dupont = get_RVs(dupont1[0], dupont2[0], offset_dupont)

    logjit_cfa = pm.Uniform("logjittercfa", lower=-5.0, upper=np.log(4), testval=1.18)
    logjit_keck = pm.Uniform(
        "logjitterkeck", lower=-5.0, upper=np.log(4), testval=-0.07
    )
    logjit_feros = pm.Uniform(
        "logjitterferos", lower=-5.0, upper=np.log(4), testval=1.32
    )
    logjit_dupont = pm.Uniform(
        "logjitterdupont", lower=-5.0, upper=np.log(4), testval=0.66
    )
    jit_cfa = pm.Deterministic("jitCfa", tt.exp(logjit_cfa))
    jit_keck = pm.Deterministic("jitKeck", tt.exp(logjit_keck))
    jit_feros = pm.Deterministic("jitFeros", tt.exp(logjit_feros))
    jit_dupont = pm.Deterministic("jitDupont", tt.exp(logjit_dupont))

    # get the total errors
    def get_err(rv_err, logjitter):
        return tt.sqrt(rv_err ** 2 + tt.exp(2 * logjitter))

    # define the RV likelihoods
    pm.Normal(
        "cfaRV1Obs", mu=rv1_cfa, observed=cfa1[1], sd=get_err(cfa1[2], logjit_cfa)
    )
    pm.Normal(
        "cfaRV2Obs", mu=rv2_cfa, observed=cfa2[1], sd=get_err(cfa2[2], logjit_cfa)
    )

    pm.Normal(
        "keckRV1Obs", mu=rv1_keck, observed=keck1[1], sd=get_err(keck1[2], logjit_keck)
    )
    pm.Normal(
        "keckRV2Obs", mu=rv2_keck, observed=keck2[1], sd=get_err(keck2[2], logjit_keck)
    )
    pm.Normal(
        "keckRV3Obs", mu=rv3_keck, observed=keck3[1], sd=get_err(keck3[2], logjit_keck)
    )

    pm.Normal(
        "ferosRV1Obs",
        mu=rv1_feros,
        observed=feros1[1],
        sd=get_err(feros1[2], logjit_feros),
    )
    pm.Normal(
        "ferosRV2Obs",
        mu=rv2_feros,
        observed=feros2[1],
        sd=get_err(feros2[2], logjit_feros),
    )

    pm.Normal(
        "dupontRV1Obs",
        mu=rv1_dupont,
        observed=dupont1[1],
        sd=get_err(dupont1[2], logjit_dupont),
    )
    pm.Normal(
        "dupontRV2Obs",
        mu=rv2_dupont,
        observed=dupont2[1],
        sd=get_err(dupont2[2], logjit_dupont),
    )

    # get the astrometric predictions
    # since there is only one Anthonioz measurement, we won't use jitter
    rho_inner, theta_inner = orbit_inner.get_relative_angles(
        anthonioz[0], parallax
    )  # arcsec

    # astrometric likelihood functions
    pm.Normal("obs_rho_inner", mu=rho_inner, observed=anthonioz[1], sd=anthonioz[2])
    # wrap-safe
    theta_diff_inner = tt.arctan2(
        tt.sin(theta_inner - anthonioz[3]), tt.cos(theta_inner - anthonioz[3])
    )
    pm.Normal("obs_theta_inner", mu=theta_diff_inner, observed=0.0, sd=anthonioz[4])

    rho_outer, theta_outer = orbit_outer.get_relative_angles(wds[0], parallax)  # arcsec

    # add jitter terms to both separation and position angle
    log_rho_s = pm.Normal("logRhoS", mu=-5.14, sd=2.0)
    log_theta_s = pm.Normal("logThetaS", mu=-4.03, sd=2.0)

    rho_tot_err = tt.sqrt(wds[2] ** 2 + tt.exp(2 * log_rho_s))
    theta_tot_err = tt.sqrt(wds[4] ** 2 + tt.exp(2 * log_theta_s))

    pm.Normal("obs_rho_outer", mu=rho_outer, observed=wds[1], sd=rho_tot_err)
    theta_diff_outer = tt.arctan2(
        tt.sin(theta_outer - wds[3]), tt.cos(theta_outer - wds[3])
    )
    pm.Normal("obs_theta_outer", mu=theta_diff_outer, observed=zeros, sd=theta_tot_err)

    # disk dynamical likelihoods
    pm.Normal("obs_MA", mu=MA, observed=MA_mean, sd=MA_std)

# optimize to get a decent starting point
# with model:
#     map_sol0 = xo.optimize(vars=[t_periastron_inner, gamma_outer])
#     map_sol1 = xo.optimize(map_sol0, vars=[a_ang_inner, logP_inner, omega_inner, Omega_inner,
#                                            cos_incl_inner, e_inner, gamma_outer])
#     map_sol2 = xo.optimize(map_sol1, vars=[phi_outer, omega_outer,
#                                             Omega_outer, cos_incl_outer, e_outer])
#     map_sol3 = xo.optimize(map_sol2)

# now let's actually explore the posterior for real
# sampler = xo.PyMC3Sampler(finish=1000, chains=4)
with model:
    trace = pm.sample(
        draws=2000, tune=1000, step_kwargs=dict(target_accept=0.9), chains=4
    )

# save as CSV file
df = pm.trace_to_dataframe(trace)
df.to_csv(f"{outdir}current.csv")

vars = [
    "mparallax",
    "MA",
    "MAb",
    "a_ang_inner",
    "a_inner",
    "logP_inner",
    "e_inner",
    "omega_inner",
    "Omega_inner",
    "cos_incl_inner",
    "incl_inner",
    "t_periastron_inner",
    "logP_outer",
    "omega_outer",
    "Omega_outer",
    "phi_outer",
    "cos_incl_outer",
    "e_outer",
    "gamma_outer",
    "MB",
    "offsetKeck",
    "offsetFeros",
    "offsetDupont",
    "logRhoS",
    "logThetaS",
    "logjittercfa",
    "logjitterkeck",
    "logjitterferos",
    "logjitterdupont",
]

pm.summary(trace)
az.plot_trace(trace)  # , var_names=vars)
plt.savefig(f"{outdir}traceplot.png", dpi=120)


# %matplotlib inline
import numpy as np
import matplotlib.pyplot as plt

# https://stackoverflow.com/questions/25689238/show-origin-axis-x-y-in-matplotlib-plot

x = np.linspace(0.2,10,100)
fig, ax = plt.subplots()
ax.plot(x, 1/x)
ax.plot(x, np.log(x))
ax.set_aspect('equal')
ax.grid(True, which='both')

ax.axhline(y=0, color='k')
ax.axvline(x=0, color='k')

plt.show()


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

"""
author: FddDaiErBai
date: 2022.04.04
"""

a = 1
# 判断套件表达式
while a < 10:
    # 执行条件执行体
    print(a)
    a += 1
# while 判断N+1次，条件为True执行N次

# 计算0到4之间的累加和
# 1. 初始化变量
# 2. 条件判断
# 3. 条件执行体(循环体)
# 4. 改变变量

a = 0
sum = 0
while a < 5:
    sum += a
    a += 1
print('和为:', sum)


from typing import Any, Dict, Iterable, List, Optional, Tuple, TypeVar, Union

import tensorflow as tf
import torch

from fastestimator.backend._binary_crossentropy import binary_crossentropy
from fastestimator.backend._categorical_crossentropy import categorical_crossentropy
from fastestimator.backend._sparse_categorical_crossentropy import sparse_categorical_crossentropy
from fastestimator.op.tensorop.loss.loss import LossOp
from fastestimator.util.traceability_util import traceable

Tensor = TypeVar('Tensor', tf.Tensor, torch.Tensor)

@traceable()
class CrossEntropy(LossOp):
    """Calculate Element-Wise CrossEntropy (binary, categorical or sparse categorical).

    Args:
        inputs: A tuple or list like: [y_pred, y_true].
        outputs: String key under which to store the computed loss value.
        mode: What mode(s) to execute this Op in. For example, "train", "eval", "test", or "infer". To execute
            regardless of mode, pass None. To execute in all modes except for a particular one, you can pass an argument
            like "!infer" or "!train".
        ds_id: What dataset id(s) to execute this Op in. To execute regardless of ds_id, pass None. To execute in all
            ds_ids except for a particular one, you can pass an argument like "!ds1".
        from_logits: Whether y_pred is logits (without softmax).
        average_loss: Whether to average the element-wise loss after the Loss Op.
        form: What form of cross entropy should be performed ('binary', 'categorical', 'sparse', or None). None will
            automatically infer the correct form based on tensor shape: if the both y_pred and y_true are rank-2 tensors
            then 'categorical' will be used, if y_pred is rank-2 tensors but y_true is rank-1 tensor, then `sparse` will
            be chosen, otherwise `binary` will be applied.
        class_weights: Dictionary mapping class indices to a weight for weighting the loss function. Useful when you
            need to pay more attention to samples from an under-represented class.

    Raises:
        AssertionError: If `class_weights` or it's keys and values are of unacceptable data types.
    """
    def __init__(self,
                 inputs: Union[Tuple[str, str], List[str]],
                 outputs: str,
                 mode: Union[None, str, Iterable[str]] = "!infer",
                 ds_id: Union[None, str, Iterable[str]] = None,
                 from_logits: bool = False,
                 average_loss: bool = True,
                 form: Optional[str] = None,
                 class_weights: Optional[Dict[int, float]] = None):
        super().__init__(inputs=inputs, outputs=outputs, mode=mode, ds_id=ds_id, average_loss=average_loss)
        self.from_logits = from_logits
        self.form = form
        self.cross_entropy_fn = {
            "binary": binary_crossentropy,
            "categorical": categorical_crossentropy,
            "sparse": sparse_categorical_crossentropy
        }

        if class_weights:
            assert isinstance(class_weights, dict), \
                "class_weights should be a dictionary or have None value, got {}".format(type(class_weights))
            assert all(isinstance(key, int) for key in class_weights.keys()), \
                "Please ensure that the keys of the class_weight dictionary are of type: int"
            assert all(isinstance(value, float) for value in class_weights.values()), \
                "Please ensure that the values of the class_weight dictionary are of type: float"

        self.class_weights = class_weights
        self.class_dict = None

    def build(self, framework: str, device: Optional[torch.device] = None) -> None:
        if self.class_weights:
            if framework == 'tf':
                keys_tensor = tf.constant(list(self.class_weights.keys()))
                vals_tensor = tf.constant(list(self.class_weights.values()))
                self.class_dict = tf.lookup.StaticHashTable(
                    tf.lookup.KeyValueTensorInitializer(keys_tensor, vals_tensor), default_value=1.0)
            elif framework == 'torch':
                self.class_dict = self.class_weights
            else:
                raise ValueError("unrecognized framework: {}".format(framework))

    def forward(self, data: List[Tensor], state: Dict[str, Any]) -> Tensor:
        y_pred, y_true = data
        form = self.form
        if form is None:
            if len(y_pred.shape) == 2 and y_pred.shape[-1] > 1:
                if len(y_true.shape) == 2 and y_true.shape[-1] > 1:
                    form = "categorical"
                else:
                    form = "sparse"
            else:
                form = "binary"

        loss = self.cross_entropy_fn[form](y_pred,
                                           y_true,
                                           from_logits=self.from_logits,
                                           average_loss=self.average_loss,
                                           class_weights=self.class_dict)
        return loss


def solution():
    x = int(input())
    row = 0
    idx = 0
    for i in range(1, x+1):
        row += i
        if row >= x:
            idx = i
            break

    inc = x - (row - idx) - 1
    if idx % 2 == 0:
        y_ = (idx - 1) - inc
        x_ = inc
    else:
        x_ = (idx - 1) - inc
        y_ = inc

    print(f"{x_+1}/{y_+1}")

if '__main__' == __name__:
    solution()


# -*- coding: utf-8 -*-
from bengali_stemmer.rafikamal2014.parser import RafiStemmer
from nltk.corpus.reader import PlaintextCorpusReader
from nltk import RegexpTokenizer
import re
import numpy as np

#Reading Datasets with word tokenization
dir_fake = 'f:/TitleFake/'
dir_real = 'f:/TitleReal/'

w_t = RegexpTokenizer("[\u0980-\u09FF']+")
corpus_fake = PlaintextCorpusReader(dir_fake, r'.*\.txt', word_tokenizer=w_t)
corpus_real = PlaintextCorpusReader(dir_real, r'.*\.txt', word_tokenizer=w_t)

corpus_fake_text = []
corpus_real_text = []

#Removing Numbers
for file in corpus_fake.fileids():
    corpus_fake_text.append(corpus_fake.words(file))
corpus_fake_text = [[re.sub(r'\d+', ' ', word) for word in document]for document in corpus_fake_text]

for file in corpus_real.fileids():
    corpus_real_text.append(corpus_real.words(file))
corpus_real_text = [[re.sub(r'\d+', ' ', word) for word in document]for document in corpus_real_text]

#Stemming for dimensionality reduction and removing hanging single/double letters
vocab_fake = []
vocab_real = []
my_stemmer = RafiStemmer()

document_fake_text = []
for doc in corpus_fake_text:
    doc_fake = []
    for word in doc:
        stemmed_word = my_stemmer.stem_word(word)
        if len(stemmed_word) < 2:
            continue
        doc_fake.append(stemmed_word)
        vocab_fake.append(stemmed_word)
    document_fake_text.append(doc_fake)

document_real_text = []
for doc in corpus_real_text:
    doc_real = []
    for word in doc:
        stemmed_word = my_stemmer.stem_word(word)
        if len(stemmed_word) < 2:
            continue
        doc_real.append(stemmed_word)
        vocab_real.append(stemmed_word)
    document_real_text.append(doc_real)

vocab_fake = sorted(set(vocab_fake))
fake_dict = {}
for word in vocab_fake:
    fake_dict[word] = 0
for doc in document_fake_text:
    for word in doc:
        fake_dict[word] += 1
fake_top = sorted(fake_dict, key = fake_dict.get, reverse=True)[:10]

vocab_real = sorted(set(vocab_real))
real_dict = {}
for word in vocab_real:
    real_dict[word] = 0
for doc in document_real_text:
    for word in doc:
        real_dict[word] += 1
real_top = sorted(real_dict, key = real_dict.get, reverse=True)[:10]

tf_title = []
for word in fake_top:
    freq = 0
    if word in real_dict:
        freq = real_dict[word]
    tf_title.append([word, fake_dict[word], freq])

for word in real_top:
    freq = 0
    if word in fake_dict:
        freq = fake_dict[word]
    tf_title.append([word, freq, real_dict[word]])

# Number of input document 662
# Number of words in document 1,34,606 after stemming and dropping small words
vocab_set = sorted(set(vocab))
#Total unique words 14,210
#Building Dictionary
word_indices = dict((c, i) for i, c in enumerate(vocab_set))
indices_word = dict((i, c) for i, c in enumerate(vocab_set))


import time
import numpy as np

def convert_to_sepia(image):
    """Converts an image to sepia using a numpy implementation

        Args:
            image (Array): an array representation of the image that is to be converted
        Returns:
            Array: an array representation of the image in sepia
    """

    sepia_matrix = [[0.393, 0.769, 0.189],
                [ 0.349 , 0.686 , 0.168],
                [ 0.272 , 0.534 , 0.131]]
    sepia_array = np.array(sepia_matrix)

    sepia_image = image
    sepia_image = np.dot(sepia_image, sepia_array.T)
    sepia_image = np.minimum(sepia_image, 255)
    return sepia_image

def calculate_runtime(image, experiment_repeats):
    """Calculates the average runtime of the time used to convert an image to sepia
       The result are being printed to the terminal

        Args:
            image (Array): an array representation of the image that is to be converted
            experiment_repeats (int): the number of times to calculate the runtime
    """

    sum_runtime = 0

    for i in range(experiment_repeats):
        start_time = time.time()
        convert_to_sepia(image)
        end_time = time.time()
        runtime = end_time - start_time
        sum_runtime += runtime

    average_runtime = sum_runtime/experiment_repeats
    print("\nAverage runtime over {} runs: {:.4} s\n".format(experiment_repeats, average_runtime))


from __future__ import absolute_import, division, print_function

from polyaxon import settings
from polyaxon.exceptions import PolyaxonClientException
from polyaxon.tracking import Run

try:
    from tensorflow.train import LoggingTensorHook
except ImportError:
    raise PolyaxonClientException(
        "tensorflow is required to use PolyaxonLoggingTensorHook"
    )

class PolyaxonLoggingTensorHook(LoggingTensorHook):
    """Hook that logs data to console and Polyaxon"""

    def __init__(self, tensors, run=None, every_n_iter=None, every_n_secs=None):
        super(PolyaxonLoggingTensorHook, self).__init__(
            tensors=tensors, every_n_iter=every_n_iter, every_n_secs=every_n_secs
        )
        self.run = run
        if settings.CLIENT_CONFIG.is_managed:
            self.run = self.run or Run()

    def _log_tensors(self, tensor_values):
        super(PolyaxonLoggingTensorHook, self)._log_tensors(tensor_values)

        if not self.run:
            return
        metrics = {k: tensor_values[k] for k in self._tensors.keys()}
        self.run.log_metrics(**metrics)


"""healthyfirst URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/4.0/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.urls import path, include
from rest_framework import routers
from healthyfirst.api import views
from rest_framework_simplejwt.views import (
    TokenObtainPairView,
    TokenRefreshView,
)

router = routers.DefaultRouter()
router.register(r'users', views.PersonViewSet, basename='users')
router.register(r'premises', views.PremiseViewSet, basename='premises')
router.register(r'certificate', views.CertificateViewSet, basename='certificate')
router.register(r'businesstype', views.BusinessTypeViewSet, basename='businesstype')
router.register(r'inspectionplan', views.InspectionPlanViewSet, basename='inspectionplan')
router.register(r'sample', views.SampleViewSet, basename='sample')
router.register(r'area', views.AreaViewSet, basename='area')

urlpatterns = [
    path('api/', include(router.urls)),
    path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
    path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
    path('gen_form/<int:cert_id>/', views.generate_form, name='gen_form')
]


"""Bulgarian български bg."""

APPLICATION_TITLE = "Celestine Преглед на изображения"

ARGUMENT_APPLICATION_DESCRIPTION = "\
Вашите програмни стойности отиват тук. Уау."

ARGUMENT_APPLICATION_HELP = "Изберете приложение, което да изпълните."

ARGUMENT_APPLICATION_TITLE = "Приложение"

ARGUMENT_CUSTOMIZATION_DESCRIPTION = "\
Celestine ще се опита да отгатне най-добрите настройки за използване. \
Вместо това можете да поискате да използвате тези стойности."

ARGUMENT_CUSTOMIZATION_TITLE = "Персонализиране"

ARGUMENT_HELP_HELP = "Показва този екран за помощ."

ARGUMENT_INFORMATION_DESCRIPTION = "\
Включването им ще сложи край на програмата за показване на \
информация."

ARGUMENT_INFORMATION_TITLE = "Информация"

ARGUMENT_INTERFACE_HELP = "\
Кой графичен интерфейс искате да използвате?"

ARGUMENT_LANGUAGE_HELP = "\
ЕС има 24 официални езика: \
български, хърватски, чешки, датски, нидерландски, английски, \
естонски, фински, френски, немски, гръцки, унгарски, ирландски, \
италиански, латвийски, литовски, малтийски, полски, португалски, \
румънски, словашки, словенски, испански и шведски."

ARGUMENT_MODIFICATION_DESCRIPTION = "Конфигуриране на флагове"

ARGUMENT_MODIFICATION_TITLE = "Промяна"

ARGUMENT_PARSER_ARGUMENT = "аргумент"

ARGUMENT_PARSER_CHOICE = "невалиден избор"

ARGUMENT_PARSER_CHOOSE = "Изберете от"

ARGUMENT_PARSER_ERROR = "грешка"

ARGUMENT_PARSER_USAGE = "Използване"

ARGUMENT_PYTHON_HELP = "Изберете коя версия на Python използвате."

ARGUMENT_VERSION_HELP = "Показва текущата версия."

CLEAN_MAIN_CLEAN = "Форматирайте всички кодови файлове на Python."

CLEAN_MAIN_LICENCE = "Почистете лицензионните файлове."

CLEAN_MAIN_TITLE = "\
Скриптове, за да получите проект готов за публикуване."

CLEAN_MAIN_VERSION = "Актуализиране на номера на версията."

CURSES_EXIT = "Натиснете клавиша ESC, за да излезете."

DEMO_COW_TALK = "Аз съм говореща крава."

DEMO_ZERO_ACTION = "Поздравете кравата."

DEMO_MAIN_NEXT = "Отидете на втора страница."

DEMO_MAIN_PAST = "Отиди на първа страница."

DEMO_ZERO_SAY = "Здравей човеко."

DEMO_ZERO_TITLE = "Основна страница."

DEMO_ONE_ACTION = "Нахрани кравата."

DEMO_ONE_NEXT = "Отидете на втора страница."

DEMO_ONE_PAST = "Отидете на главната страница."

DEMO_ONE_SAY = "Храната е вкусна."

DEMO_ONE_TITLE = "Страница първа."

DEMO_TWO_ACTION = "Махни на кравата."

DEMO_TWO_NEXT = "Отидете на главната страница."

DEMO_TWO_PAST = "Отиди на първа страница."

DEMO_TWO_SAY = "Довиждане, човече."

DEMO_TWO_TITLE = "Страница втора."

LANGUAGE = "\
ЕС има 24 официални езика: \
български, хърватски, чешки, датски, нидерландски, английски, \
естонски, фински, френски, немски, гръцки, унгарски, ирландски, \
италиански, латвийски, литовски, малтийски, полски, португалски, \
румънски, словашки, словенски, испански и шведски."

LANGUAGE_NAME_ENGLISH = "Английски"

LANGUAGE_NAME_NATIVE = "Английски"

LANGUAGE_TAG_AZURE = "ен"

LANGUAGE_TAG_ISO = "ен"

SCAN_MAIN_BUTTON = "Този бутон не прави нищо."

SCAN_MAIN_TITLE = "Проект за бъдещо сканиране на сигурността"

SESSION_PARSER_CHOICE = "невалиден избор"

SESSION_PARSER_CHOOSE = "Изберете от"

SESSION_PARSER_ERROR = "грешка"

SESSION_PARSER_UNRECOGNIZED = "Неразпознати аргументи"

SESSION_PARSER_USAGE = "Използване"

TRANSLATOR_FILE_ERROR_OVERFLOW = "Преляхме."

TRANSLATOR_MAIN_BUTTON = "Превод на файлове"

TRANSLATOR_REPORT_BUTTON = "Доклад за досиетата."

TRANSLATOR_SESSION_KEY = "\
Вашият сервизен ключ за преводач от портала на Azure."

TRANSLATOR_SESSION_REGION = "\
Регионът, в който е създаден вашият ресурс."

TRANSLATOR_SESSION_URL = "Местоположението на преводаческата услуга."

VIEWER_MAIN_BUTTON = "Зареждане на изображения в директория."

VIEWER_SESSION_DIRECTORY = "Път до директория, съдържаща изображения."

name = "ен"

########################################################################

LANGUAGE = "\
В ЕС има 24 официални езика: \
английски, български, гръцки, датски, естонски, испански, италиански, \
латвийски, литовски, малтийски, немски, нидерландски, полски, \
португалски, румънски, словашки, словенски, унгарски, фински, френски, \
хърватски, чешки и шведски."

LANGUAGE_NAME_ENGLISH = "Bulgarian"

LANGUAGE_NAME_NATIVE = "български"

LANGUAGE_TAG_AZURE = "bg"

LANGUAGE_TAG_ISO = "bg"


"""
Contains a representation of GitHub users.
"""
from typing import Optional

from IGitt.GitHub import GitHubMixin
from IGitt.GitHub import GitHubToken
from IGitt.GitHub import GitHubInstallationToken
from IGitt.Interfaces import get
from IGitt.Interfaces.User import User

PREVIEW_HEADER = {'Accept': 'application/vnd.github.machine-man-preview+json'}

class GitHubUser(GitHubMixin, User):
    """
    A GitHub user, e.g. sils :)
    """
    def __init__(self, token: GitHubToken, username: Optional[str]=None):
        """
        Creates a GitHubUser with the given credentials.

        :param token:       The Oauth token.
        :param username:    The username of github user.
                            Takes None, if it's the associated user's token.
        """
        self._token = token
        self._url = '/users/' + username if username else '/user'
        self._username = username

    @property
    def username(self) -> str:
        """
        Retrieves the login for the user.
        """
        return self._username or self.data['login']

    @property
    def identifier(self) -> int:
        """
        Gets a unique id for the user that never changes.
        """
        return self.data['id']

    def installed_repositories(self, installation_id: int):
        """
        List repositories that are accessible to the authenticated user for an
        installation.
        """
        # Don't move to module code, causes circular dependencies
        from IGitt.GitHub.GitHubRepository import GitHubRepository

        repos = get(self._token,
                    self.absolute_url(
                        '/user/installations/{}/repositories'.format(
                            installation_id
                        )
                    ),
                    headers=PREVIEW_HEADER)['repositories']
        return {GitHubRepository.from_data(repo, self._token, repo['id'])
                for repo in repos}

    def get_installations(self, jwt):
        """
        Gets the installations this user has access to.

        :param jwt: The GitHubJsonWebToken required to fetch data.
        """
        # Don't move to module code, causes circular dependencies
        from IGitt.GitHub.GitHubInstallation import GitHubInstallation

        resp = get(self._token, self.absolute_url('/user/installations'),
                   headers=PREVIEW_HEADER)
        return {
            GitHubInstallation.from_data(
                i, GitHubInstallationToken(i['id'], jwt), i['id'])
            for i in resp['installations']
        }


# -*- coding: utf-8 -*-
from django.conf.urls import url
from django.contrib import admin
from web1.views import *

urlpatterns = [
   url(r'^login/$',Login),
   url(r'^logout/$',Logout),
   url(r'^register/$',Register),
   url(r'^index.html',Index),
    url(r'^project_info.html',Project_Info),
    url(r'^project_edit.html',Project_edit),
   url(r'^server_info.html',Server_Info),
   url(r'^ajax/$',ajax),
   url(r'^fenye/(\d*)',fenye),
   url(r'^test/$',test),
]


from constants import *

CREATIVE_TAG = """
<script>
 var w = window;
 for (i = 0; i < 10; i++) {
     w = w.parent;
     if (w.pbjs) {
         try {
             w.pbjs.renderAd(document, '#{HB_ADID}');
             break;
         } catch (e) {
             continue;
         }
     }
 }
</script>
"""

order_data = {
    "insertion-order": {
        "name": f'{PUB_NAME}_Pbjs_HB',
        "advertiser_id": ADVERTISER_ID
    }
}

li_data = {
    "line-item":{
        "name": "Pbjs hb_pb is ",  # set dynamically
        "advertiser_id": ADVERTISER_ID,
        "state": "active",
        "insertion_order_id": 0, # set dynamically
        "revenue_value": 0, # set dynamically
        "revenue_type": "cpm",
        "manage_creative": True,
        "creatives": [] # set dynamically
    }
}

creative_data = {
    "creative": {
        "name": "Pbjs HB", # set dynamically
        "advertiser_id": ADVERTISER_ID,
        "ad_type": "banner",
        "is_self_audited": True,
        "allow_audit": False,
        "width": 0, # set dynamically
        "height": 0, # set dynamically
        "content": CREATIVE_TAG,
        "template": {
            "id": 0 # set dynamically
        }
    }
}

key_data = {
    "targeting-key": {
        "name": "test", # set dynamically
        "type": "string"
    }
}

value_data = {
    "targeting-value": {
        "name": "test", # set dynamically
        "targeting_key_id": 0 # set dynamically
    }
}

campaign_data = {
    "campaign": {
        "state": "active",
        "name": "Pbjs Campaign hb_pb is ", # set dynamically
        "advertiser_id": ADVERTISER_ID,
        "line_item_id": 0, # set dynamically
        "inventory_type": "direct"
    }
}

category_data = {
    "content-category": {
        "name": "pbjs_hb",
        "description": "Any placements targeting this category will serve on Prebidjs HB LI."
    }
}

# setup one profile and populate each key value
profile_data = {
   "profile": {
       "inventory_action": "include",
       "advertiser_id": ADVERTISER_ID,
       "placement_targets": PLACEMENT_TARGETS, #PLACEMENT_TARGETS, # array/list of placements
        "key_value_targets": {
          "kv_expression": {
            "header": {
                "an_version": "1.0",
                "client_version": "1.0"
            },
            "exp": {
                "typ": "and",
                "sbe": [{
                    "exp": {
                        "typ": "in",
                        "key": "hb_bidder",
                        "vtp": "sta",
                        "vsa": ['appnexus', 'aol', 'rubicon', 'pulsepoint', 'sovrn', 'openx', 'sonobi', 'pubmatic']
                    }
                },
                {
                    "exp": {
                        "typ": "eq",
                        "key": "hb_pb is ", # 1.00 - set dynamically
                        "vtp": "num",
                        "vnm": 0 # set dynamically
                    }
                }
                ]
            }
            }
        }
    }
}


# 하샤드 수

# 문제설명 :

# 예상풀이

# 문제풀이(1)
def solution(x):
    xs = str(x)         # x를 문자열로 바꿔준다.
    xsum = 0          # 자릿수의 합의 변수

    for I in range(len(xs)):    # xs의 길이만큼 반복한다.
        xsum += int(xs[i])       # 좌, 우의 값을 더한다.
        if x % xsum == 0:       # x / xsum의 나머지가 0이면
            answer = True        # 하샤드 수 True
        else:
            answer = False

    return answer

# 다른 사람의 풀이(1)
def Harshad(n):

    return n % sum([int(c) for c in str(n)]) == 0

print(solution(10)) # True
print(solution(12)) # True
print(solution(11)) # False
print(solution(13)) # False


"""
Levantando os próprios erros com raise

raise -> não é uma função é uma palavra reservada que serve para criar as
nossas proprias exceções e mensagens de erro.

OBS: Nada depois do RAISE é executado.
"""

# Exemplo real

def colore(texto, cor):
    cores = ('verde', 'amarelo', 'azul', 'branco')
    if type(texto) is not str:
        raise TypeError('texto precisa ser uma string')
    if type(cor) is not str:
        raise TypeError('cor precisa ser uma string')
    if cor not in cores:
        raise TypeError(f'A cor precisa ser uma entre: {cores}')
    print(f'O texto {texto} será impresso na cor {cor}')

colore('True', 'preto')


from __future__ import absolute_import
from __future__ import unicode_literals

import six
import yaml

from compose.config import types
from compose.const import COMPOSEFILE_V1 as V1
from compose.const import COMPOSEFILE_V2_1 as V2_1
from compose.const import COMPOSEFILE_V2_2 as V2_2
from compose.const import COMPOSEFILE_V3_1 as V3_1
from compose.const import COMPOSEFILE_V3_2 as V3_2

def serialize_config_type(dumper, data):
    representer = dumper.represent_str if six.PY3 else dumper.represent_unicode
    return representer(data.repr())

def serialize_dict_type(dumper, data):
    return dumper.represent_dict(data.repr())

yaml.SafeDumper.add_representer(types.VolumeFromSpec, serialize_config_type)
yaml.SafeDumper.add_representer(types.VolumeSpec, serialize_config_type)
yaml.SafeDumper.add_representer(types.ServiceSecret, serialize_dict_type)
yaml.SafeDumper.add_representer(types.ServicePort, serialize_dict_type)

def denormalize_config(config, image_digests=None):
    result = {'version': V2_1 if config.version == V1 else config.version}
    denormalized_services = [
        denormalize_service_dict(
            service_dict,
            config.version,
            image_digests[service_dict['name']] if image_digests else None)
        for service_dict in config.services
    ]
    result['services'] = {
        service_dict.pop('name'): service_dict
        for service_dict in denormalized_services
    }
    result['networks'] = config.networks.copy()
    for net_name, net_conf in result['networks'].items():
        if 'external_name' in net_conf:
            del net_conf['external_name']

    result['volumes'] = config.volumes.copy()
    for vol_name, vol_conf in result['volumes'].items():
        if 'external_name' in vol_conf:
            del vol_conf['external_name']

    if config.version in (V3_1, V3_2):
        result['secrets'] = config.secrets
    return result

def serialize_config(config, image_digests=None):
    return yaml.safe_dump(
        denormalize_config(config, image_digests),
        default_flow_style=False,
        indent=2,
        width=80)

def serialize_ns_time_value(value):
    result = (value, 'ns')
    table = [
        (1000., 'us'),
        (1000., 'ms'),
        (1000., 's'),
        (60., 'm'),
        (60., 'h')
    ]
    for stage in table:
        tmp = value / stage[0]
        if tmp == int(value / stage[0]):
            value = tmp
            result = (int(value), stage[1])
        else:
            break
    return '{0}{1}'.format(*result)

def denormalize_service_dict(service_dict, version, image_digest=None):
    service_dict = service_dict.copy()

    if image_digest:
        service_dict['image'] = image_digest

    if 'restart' in service_dict:
        service_dict['restart'] = types.serialize_restart_spec(
            service_dict['restart']
        )

    if version == V1 and 'network_mode' not in service_dict:
        service_dict['network_mode'] = 'bridge'

    if 'depends_on' in service_dict and version not in (V2_1, V2_2):
        service_dict['depends_on'] = sorted([
            svc for svc in service_dict['depends_on'].keys()
        ])

    if 'healthcheck' in service_dict:
        if 'interval' in service_dict['healthcheck']:
            service_dict['healthcheck']['interval'] = serialize_ns_time_value(
                service_dict['healthcheck']['interval']
            )
        if 'timeout' in service_dict['healthcheck']:
            service_dict['healthcheck']['timeout'] = serialize_ns_time_value(
                service_dict['healthcheck']['timeout']
            )

    if 'ports' in service_dict and version not in (V3_2,):
        service_dict['ports'] = [
            p.legacy_repr() if isinstance(p, types.ServicePort) else p
            for p in service_dict['ports']
        ]

    return service_dict


"""

Authors: Shubham Ugare.

Copyright:
Copyright (c) 2020 Microsoft Research
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

"""

import numpy.random
import numpy as np
import common
import os, sys
import onnx
from onnx import helper
import math
from onnx import numpy_helper

def main():
    if len(sys.argv) < 3:
        print("Model file or scaling factor unspecified.", file=sys.stderr)
        exit(1)

    file_name = sys.argv[1]
    scaling_factor = int(sys.argv[2])
    file_path = "models/" + file_name
    model_name = file_name[:-5]  # name without the '.onnx' extension
    model = onnx.load(file_path)
    graph_def = model.graph

    # Generating input
    input_dims = common.proto_val_to_dimension_tuple(model.graph.input[0])
    input_array = numpy.random.random(input_dims)
    # input_array = numpy.ones(input_dims, dtype=float)
    print("Generated random input of dimension " + str(input_dims))
    np.save("debug/" + model_name + "/" + model_name + "_input", input_array)

    (chunk, cnt) = common.numpy_float_array_to_fixed_point_val_str(
        input_array, scaling_factor
    )
    f = open("debug/" + model_name + "/" + model_name + "_input.inp", "w")
    f.write(chunk)
    f.close()

    model_name_to_val_dict = {
        init_vals.name: numpy_helper.to_array(init_vals).tolist()
        for init_vals in model.graph.initializer
    }

    preprocess_batch_normalization(graph_def, model_name_to_val_dict)

    chunk_n = ""
    cnt_n = 0
    for init_vals in model.graph.initializer:
        (chunk_1, cnt_1) = common.numpy_float_array_to_fixed_point_val_str(
            np.asarray(model_name_to_val_dict[init_vals.name], dtype=np.float32),
            scaling_factor,
        )
        chunk_n += chunk_1
        cnt_n += cnt_1

    f = open("debug/" + model_name + "/" + model_name + "_weights.inp", "w")
    f.write(chunk_n)
    f.close()

    f = open(
        "debug/" + model_name + "/" + model_name + "_combined_input_weights.inp", "w"
    )
    f.write(chunk + chunk_n)
    f.close()

    print(
        "Total "
        + str(cnt + cnt_n)
        + " integers were written in "
        + model_name
        + "_combined_input_weights.inp"
    )

def preprocess_batch_normalization(graph_def, model_name_to_val_dict):
    # set names to graph nodes if not present
    for node in graph_def.node:
        node.name = node.output[0]
        # Update the batch normalization scale and B
        # so that mean and var are not required
        if node.op_type == "BatchNormalization":
            # scale
            gamma = model_name_to_val_dict[node.input[1]]
            # B
            beta = model_name_to_val_dict[node.input[2]]
            mean = model_name_to_val_dict[node.input[3]]
            var = model_name_to_val_dict[node.input[4]]
            for i in range(len(gamma)):
                rsigma = 1 / math.sqrt(var[i] + 1e-5)
                gamma[i] = gamma[i] * rsigma
                beta[i] = beta[i] - gamma[i] * mean[i]
                mean[i] = 0
                var[i] = 1 - 1e-5

    # Just testing if the correct values are put
    model_name_to_val_dict2 = {}
    for init_vals in graph_def.initializer:
        # TODO: Remove float_data
        model_name_to_val_dict2[init_vals.name] = init_vals.float_data
    for node in graph_def.node:
        node.name = node.output[0]
        if node.op_type == "BatchNormalization":
            mean = model_name_to_val_dict[node.input[3]]
            for val in mean:
                assert val == 0

if __name__ == "__main__":
    main()


n=int(input())
a=list(map(int,input().strip().split()))
x=0
y=0
for i in range(n):
    if(i<n//2):
       x+=a[i]
    else:
        y+=a[i]
if(abs(x-y)%4==0):
    print('X')
else:
    print("Y")


import tensorflow as tf
import tensorflow.keras.backend as K
import numpy as np

from tensorflow_addons.layers import InstanceNormalization
from tensorflow.keras.layers import Dense, LeakyReLU, Conv2D, Flatten, Add, Cropping2D, Layer, InputSpec
from tensorflow.keras.layers import UpSampling2D, Reshape, AveragePooling2D, Input, BatchNormalization
from tensorflow.keras.models import Model

# Initializers
orthogonal = tf.initializers.Orthogonal
normal = tf.initializers.RandomNormal
ones = tf.initializers.ones

def crop_noise(noise_tensor, size, block):
    """
    Crops the noise_tensor to the target size.
    """
    cut = (noise_tensor.shape[1] - size) // 2
    crop = Cropping2D(cut, name=f"G_Noise_Crop_block_{block}")(noise_tensor)
    return crop

class DenseEQ(Dense):
    """
    Standard dense layer but includes learning rate equilization
    at runtime as per Karras et al. 2017. Includes learning rate multiplier,
    but defaults to 1.0. Only needed for the mapping network.

    Inherits Dense layer and overides the call method.
    """
    def __init__(self, lrmul=1, **kwargs):
        if 'kernel_initializer' in kwargs:
            raise Exception("Cannot override kernel_initializer")
        self.lrmul=lrmul
        super().__init__(kernel_initializer=normal(0, 1/self.lrmul), **kwargs)

    def build(self, input_shape):
        super().build(input_shape)
        # The number of inputs
        n = np.product([int(val) for val in input_shape[1:]])
        # He initialisation constant
        self.c = np.sqrt(2/n)*self.lrmul

    def call(self, inputs):
        output = K.dot(inputs, self.kernel*self.c)  # scale kernel
        if self.use_bias:
            output = K.bias_add(output, self.bias * self.lrmul, data_format='channels_last')
        if self.activation is not None:
            output = self.activation(output)
        return output

class Conv2DEQ(Conv2D):
    """
    Standard Conv2D layer but includes learning rate equilization
    at runtime as per Karras et al. 2017.

    Inherits Conv2D layer and overrides the call method, following
    https://github.com/keras-team/keras/blob/master/keras/layers/convolutional.py

    from the tf-keras branch.

    """

    def __init__(self, lrmul=1, **kwargs):
        """
        Requires usual Conv2D inputs e.g.
         - filters, kernel_size, strides, padding
        """
        self.lrmul = lrmul

        if 'kernel_initializer' in kwargs:
            raise Exception("Cannot override kernel_initializer")
        super().__init__(kernel_initializer=normal(0, 1/self.lrmul), **kwargs)

    def build(self, input_shape):
        super().build(input_shape)
        # The number of inputs
        n = np.product([int(val) for val in input_shape[1:]])
        # He initialisation constant
        self.c = np.sqrt(2 / n)*self.lrmul

    def call(self, inputs):
        outputs = K.conv2d(
            inputs,
            self.kernel * self.c,  # scale kernel
            strides=self.strides,
            padding=self.padding,
            data_format=self.data_format,
            dilation_rate=self.dilation_rate)

        if self.use_bias:
            outputs = K.bias_add(
                outputs,
                self.bias * self.lrmul,
                data_format=self.data_format)

        if self.activation is not None:
            return self.activation(outputs)
        return outputs

class AdaInstanceNormalization(Layer):
    """
    This is the AdaInstanceNormalization layer used by manicman199 available at
     https://github.com/manicman1999/StyleGAN-Keras

     This is used in StyleGAN version 1 as well as ALAE.
    """

    def __init__(self,
                 axis=-1,
                 momentum=0.99,
                 epsilon=1e-3,
                 center=True,
                 scale=True,
                 **kwargs):
        super(AdaInstanceNormalization, self).__init__(**kwargs)
        self.axis = axis
        self.momentum = momentum
        self.epsilon = epsilon
        self.center = center # always done
        self.scale = scale # always done

    def build(self, input_shape):

        dim = input_shape[0][self.axis]
        if dim is None:
            raise ValueError('Axis ' + str(self.axis) + ' of '
                                                        'input tensor should have a defined dimension '
                                                        'but the layer received an input with shape ' +
                             str(input_shape[0]) + '.')

        super(AdaInstanceNormalization, self).build(input_shape)

    def call(self, inputs, training=None):
        input_shape = K.int_shape(inputs[0])
        reduction_axes = list(range(0, len(input_shape)))

        beta = inputs[1]
        gamma = inputs[2]

        if self.axis is not None:
            del reduction_axes[self.axis]

        del reduction_axes[0]
        mean = K.mean(inputs[0], reduction_axes, keepdims=True)
        stddev = K.std(inputs[0], reduction_axes, keepdims=True) + self.epsilon
        normed = (inputs[0] - mean) / stddev

        return normed * gamma + beta

    def get_config(self):
        config = {
            'axis': self.axis,
            'momentum': self.momentum,
            'epsilon': self.epsilon,
            'center': self.center,
            'scale': self.scale
        }
        base_config = super(AdaInstanceNormalization, self).get_config()
        return dict(list(base_config.items()) + list(config.items()))

    def compute_output_shape(self, input_shape):
        return input_shape[0]

class Attention(Layer):
    def __init__(self, ch, **kwargs):
        super(Attention, self).__init__(**kwargs)
        self.channels = ch
        self.filters_f_g = self.channels // 8
        self.filters_h = self.channels

    def build(self, input_shape):
        kernel_shape_f_g = (1, 1) + (self.channels, self.filters_f_g)
        kernel_shape_h = (1, 1) + (self.channels, self.filters_h)

        # Create a trainable weight variable for this layer:
        self.gamma = self.add_weight(name='gamma', shape=[1], initializer='zeros', trainable=True)
        self.kernel_f = self.add_weight(shape=kernel_shape_f_g,
                                        initializer='glorot_uniform',
                                        name='kernel_f')
        self.kernel_g = self.add_weight(shape=kernel_shape_f_g,
                                        initializer='glorot_uniform',
                                        name='kernel_g')
        self.kernel_h = self.add_weight(shape=kernel_shape_h,
                                        initializer='glorot_uniform',
                                        name='kernel_h')
        self.bias_f = self.add_weight(shape=(self.filters_f_g,),
                                      initializer='zeros',
                                      name='bias_F')
        self.bias_g = self.add_weight(shape=(self.filters_f_g,),
                                      initializer='zeros',
                                      name='bias_g')
        self.bias_h = self.add_weight(shape=(self.filters_h,),
                                      initializer='zeros',
                                      name='bias_h')
        super(Attention, self).build(input_shape)
        # Set input spec.
        self.input_spec = InputSpec(ndim=4,
                                    axes={3: input_shape[-1]})
        self.built = True

    def call(self, x, **kwargs):
        def hw_flatten(x):
            return K.reshape(x, shape=[K.shape(x)[0], K.shape(x)[1] * K.shape(x)[2], K.shape(x)[-1]])

        f = K.conv2d(x,
                     kernel=self.kernel_f,
                     strides=(1, 1), padding='same')  # [bs, h, w, c']
        f = K.bias_add(f, self.bias_f)
        g = K.conv2d(x,
                     kernel=self.kernel_g,
                     strides=(1, 1), padding='same')  # [bs, h, w, c']
        g = K.bias_add(g, self.bias_g)
        h = K.conv2d(x,
                     kernel=self.kernel_h,
                     strides=(1, 1), padding='same')  # [bs, h, w, c]
        h = K.bias_add(h, self.bias_h)

        s = tf.matmul(hw_flatten(g), hw_flatten(f), transpose_b=True)  # # [bs, N, N]

        beta = K.softmax(s, axis=-1)  # attention map

        self.beta = beta

        o = K.batch_dot(beta, hw_flatten(h))  # [bs, N, C]

        o = K.reshape(o, shape=K.shape(x))  # [bs, h, w, C]
        x = self.gamma * o + x

        return x

    def compute_output_shape(self, input_shape):
        return input_shape

class tRGB(Layer):
    """
    Linear transformation from feature space to rgb space, using a 1x1 convolution
    """
    def __init__(self, block):
        super(tRGB, self).__init__()
        self.block = block
        self.transform = Conv2DEQ(filters=3, kernel_size=(1, 1), padding="same", name=f"G_block_{block}_tRGB")

    def build(self, input_shape):
        super(tRGB, self).build(input_shape)

    def call(self, inputs, **kwargs):
        return self.transform(inputs)

class MeanAndStDev(Layer):
    """
    This is the Instance Normalization transformation which
    concatenates mu and sigma to later be mapped to w.

    This is used in the encoder introduced by
    """
    def __init__(self, **kwargs):
        super(MeanAndStDev, self).__init__(**kwargs)

    def build(self, input_shape):
        super(MeanAndStDev, self).build(input_shape)

    def call(self, inputs, **kwargs):
        m = K.mean(inputs, axis=[1, 2], keepdims=True)
        std = K.std(inputs, axis=[1, 2], keepdims=True)
        statistics = K.concatenate([m, std], axis=1)
        return statistics

class ModulationConv2D(Layer):
    """
    Modulation/Demodulation Convolutional layer, including learning rate equilization
    at runtime as per Karras et al. 2017 & 2019. (ProGAN & StyleGan2)

    Inspired by https://github.com/moono/stylegan2-tf-2.x/blob/master/stylegan2/custom_layers.py

    Look at tf-keras branch at
    https://github.com/keras-team/keras/blob/master/keras/layers/convolutional.py

    for implementation details.

    """

    def __init__(self, filters, kernel_size, style_fmaps, block, demodulate=False, **kwargs):
        super().__init__(**kwargs)
        self.filters = filters
        self.kernel_size = kernel_size
        self.style_fmaps = style_fmaps  # this is z_dim
        self.block = block
        self.demodulate = demodulate

    def build(self, input_shape):
        """
        Input shape is a list of input shapes.

        x_shape = input_shape[0] - the shape of the feature map
        w_shape = input_shape[1] - the shape of the style vector
        """
        x_shape, w_shape = input_shape[0], input_shape[1]

        # print("Build X-shape:", x_shape)

        # Conv Kernel
        self.kernel = self.add_weight("kernel",
                                      shape=(self.kernel_size[0], self.kernel_size[1],
                                             x_shape[-1], self.filters),
                                      initializer=normal(0, 1),
                                      trainable=True
                                      )

        # Equilized learning rate constant
        n = np.product([int(val) for val in x_shape[1:]])
        # He initialisation constant
        self.c = np.sqrt(2 / n)

        # add modulation layer
        self.modulate = DenseEQ(units=x_shape[-1], name=f"modulation_{self.block}")

    def scale_weights(self, style):
        """
        Scales and transforms the weights using the style vector

        B - BATCH
        k - kernel
        I - Input Features
        O - Output Features

        """
        # convolution kernel weights for fused conv
        weight = self.kernel * self.c  # [kkIO]
        weight = weight[np.newaxis]  # [BkkIO]

        # modulation
        style = self.modulate(style)  # [BI] - includes the bias
        weight *= style[:, np.newaxis, np.newaxis, :, np.newaxis]  # [BkkIO]

        # demodulation
        if self.demodulate:
            # demodulate with the L2 Norm of the weights (statistical assumption)
            d = tf.math.rsqrt(tf.reduce_sum(tf.square(weight), axis=[1, 2, 3]) + 1e-8)  # [BO]
            weight *= d[:, np.newaxis, np.newaxis, np.newaxis, :]  # [BkkIO]

        # weight: reshape, prepare for fused operation
        new_weight_shape = [tf.shape(weight)[1], tf.shape(weight)[2], tf.shape(weight)[3], -1]  # [kkI(BO)]
        weight = tf.transpose(weight, [1, 2, 3, 0, 4])  # [kkIBO]
        weight = tf.reshape(weight, shape=new_weight_shape)  # [kkI(BO)]
        return weight

    def call(self, inputs, **kwargs):
        x = inputs[0]
        style = inputs[1]

        # Transform the weights using the style vector
        weights = self.scale_weights(style)

        # Prepare inputs: reshape minibatch to convolution groups
        rows = x.shape[1]
        cols = x.shape[2]
        f = x.shape[3]
        x = tf.reshape(x, [1, -1, rows, cols])

        # Perform convolution
        x = tf.nn.conv2d(x, weights, data_format='NCHW', strides=[1, 1, 1, 1], padding='SAME')

        # x: reshape back to batches
        x = tf.reshape(x, [-1, self.filters, tf.shape(x)[2], tf.shape(x)[3]])

        # x: reshape to [BHWO]
        x = tf.transpose(x, [0, 2, 3, 1])

        x = tf.reshape(x, shape=(-1, rows, cols, f))  # FIXES RESHAPE ISSUE!

        return x

    def get_config(self):
        config = super(ModulationConv2D, self).get_config()
        config.update({
            'filters': self.filters,
            'kernel': self.kernel,
            'style_fmaps': self.style_fmaps,
            'demodulate': self.demodulate,
            'up': self.up,
            'down': self.down
        })
        return config

class Noise(Layer):
    def __init__(self, **kwargs):
        super(Noise, self).__init__(**kwargs)

    def build(self, input_shape):
        w_init = tf.zeros(shape=(), dtype=tf.dtypes.float32)
        self.noise_strength = tf.Variable(w_init, trainable=True, name='w')

    def call(self, inputs, noise=None, training=None, mask=None):
        x_shape = tf.shape(inputs)

        # noise: [1, 1, x_shape[2], x_shape[3]] or None
        if noise is None:
            noise = tf.random.normal(shape=(x_shape[0], 1, x_shape[2], x_shape[3]), dtype=tf.dtypes.float32)

        x = inputs + noise * self.noise_strength
        return x

    def get_config(self):
        config = super(Noise, self).get_config()
        config.update({})
        return config

class Bias(Layer):
    """
    A simple bias layer used in StyleGAN2 after
    the Mod/Demod layer
    """
    def __init__(self, units, lrmul=1, **kwargs):
        super().__init__(**kwargs)
        self.units = units
        self.lrmul = lrmul

    def build(self, input_shape):
        # Conv bias
        self.bias = self.add_weight("bias",
                                    shape=[self.units, ],
                                    initializer=normal(0, 1/self.lrmul)
                                    )

    def call(self, inputs, **kwargs ):
        return inputs + self.bias


import pygame, sys
from settings import *
from player import Player
from car import Car

class AllSprites(pygame.sprite.Group):
    def __init__(self):
        super().__init__()

    def customize_draw(self):
        for sprite in self.sprites():
            screen.blit(sprite.image, sprite.rect)

pygame.init()

screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
pygame.display.set_caption("Frogger")
clock = pygame.time.Clock()

# groups
all_sprites = AllSprites()

# classes
player = Player(all_sprites, (200, 300))
car = Car(all_sprites, (700, 400))

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

        # keyboard alternative
        # if event.type == pygame.KEYDOWN:
        #     if event.key == pygame.K_w:
        #         print("w")

    dt = clock.tick() / 1000

    screen.fill("black")

    all_sprites.update(dt)

    all_sprites.draw(screen)

    pygame.display.update()


'''
Created on 2019年6月4日

@author: wukai
'''
import os
import numpy as np
import scipy.io as sio
import matplotlib.pyplot as plt
from calcu import *

print('Loading data ...........')
os.chdir(os.path.split(os.path.abspath(__file__))[0])
data = sio.loadmat('ex3data1.mat')
m, n = data['X'].shape
y = data['y']
input_layer_size = n     # Input feature nums
hidden_layer_size = 25   # 25 hidden unit
num_labels = 10          # Label nums
X = np.column_stack((np.ones(m), data['X']))

print('Loading Saved Neural Network Parameters')
params = sio.loadmat('ex3weights.mat')
print(params)

y_pr = nnPredict(params['Theta1'], params['Theta2'], X)
py = (y.flatten() == y_pr)
acc = len(py[(py == True)]) * 100.0 / len(y)
print('Accuracy = {}'.format(acc))


""" Wrapper API for dingding bot. """

class Message:
    def __init__(self, msgtype, **kwargs):
        self.msgtype = msgtype
        self.kwargs = kwargs

        # message has two list values, first is requried, second is optional
        arg_dict = {'text': [['content'], []],
                    'link': [['title', 'text', 'messageUrl'], ['picUrl']],
                    'markdown': [['title', 'text'], []]
                    }

        assert self.msgtype in arg_dict.keys(), 'msgtype is invalid.'

        for k, v in self.kwargs.items():
            print(k, v, arg_dict[self.msgtype])
            if k not in arg_dict[self.msgtype][0]:
                print('{} is not a valid key for msgtype {}'.format(
                    k, self.msgtype))
                raise KeyError()

        for key_word in arg_dict[self.msgtype][0]:
            if key_word not in self.kwargs.keys():
                print('{} is required for msgtype {}'.format(
                    key_word, self.msgtype))
                raise KeyError()

        dict_at = {}
        if 'atMobiles' in kwargs.keys():
            dict_at = {'atMobiles': kwargs['atMobiles']}
        if 'isAtAll' in kwargs.keys():
            dict_at['isAtAll'] = kwargs['isAtAll']

        if self.msgtype == 'text':
            self.msg = {
                "msgtype": "text",
                "text": {
                    "content": kwargs['content']
                },
                "at": dict_at
            }

        elif self.msgtype == 'link':
            picUrl = ""
            if 'picUrl' in kwargs.keys():
                picUrl = kwargs['picUrl']

            self.msg = {
                "msgtype": "link",
                "link": {
                    "text": kwargs['text'],
                    "title": kwargs['title'],
                    "picUrl": picUrl,
                    "messageUrl": kwargs['messageUrl']
                }
            }

        if self.msgtype == 'markdown':
            self.msg = {
                "msgtype": "markdown",
                "text": {
                    "title": kwargs['title'],
                    "text": kwargs['text']
                },
                "at": dict_at
            }

    def get(self):
        return self.msg


import sys
import os
newPath = os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir, os.path.pardir))
sys.path.append(newPath)

from datetime import datetime, timedelta
import unittest
from app import create_app, db
from app.models import User, Post
from config import Config

class TestConfig(Config):
    TESTING = True
    SQLALCHEMY_DATABASE_URI = 'sqlite://'
    ELASTICSEARCH_URL = None

class EditPostTestCase(unittest.TestCase):
    def setUp(self):
        self.app = create_app(TestConfig)
        self.client = self.app.test_client()
        self.app_context = self.app.app_context()
        self.app_context.push()
        db.create_all()

    def tearDown(self):
        db.session.remove()
        db.drop_all()
        self.app_context.pop()

    def test_edit_post(self):
        u = User(username='manraj')
        db.session.add(u)

        now = datetime.utcnow()
        p1 = Post(body="post from manraj", author=u,
                  timestamp=now + timedelta(seconds=1))
        db.session.add(p1)
        db.session.commit()

        p2 = Post(body="post from manraj but different", author=u,
                  timestamp=now + timedelta(seconds=1))
        p1 = p2
        db.session.add(p1)
        db.session.commit()

        self.assertEqual(p1, p2)

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


import json
from typing import Any
from typing import Dict

from src.code.logger import create_logger
from src.code.model.custom_enums import MessageGroup
from src.code.model.custom_enums import MessageType
from src.code.model.request import Request

logger = create_logger(__name__)

class SlackEventType:
    def __init__(self, event: Dict):
        self._event: Dict = event

    def get_event_type(self) -> MessageType:
        if self._event.get("type") == "message":
            # Test for new main message
            if self._event.get("subtype") is None:
                if self._event.get("thread_ts") is not None:
                    logger.info("Message type is: %s", MessageType.THREAD_NEW.value)
                    return MessageType.THREAD_NEW
                else:
                    logger.info("Message type is: %s", MessageType.MAIN_NEW.value)
                    return MessageType.MAIN_NEW

            # Test for new main file share
            if self._event.get("subtype") == "file_share":
                if self._event.get("thread_ts") is not None:
                    logger.info("Message type is: %s", MessageType.THREAD_NEW_FILE.value)
                    return MessageType.THREAD_NEW_FILE
                else:
                    logger.info("Message type is: %s", MessageType.MAIN_NEW.value)
                return MessageType.MAIN_NEW_FILE

            # Test for editing message - if true the main message exists
            if self._event.get("subtype") == "message_changed":
                record = Request().get_request(channel_id=self._event["channel"], event_ts=self._event["message"]["ts"])
                if record is not None:
                    if self._event["message"]["text"] == "This message was deleted.":
                        logger.info("Message type is: %s", MessageType.MAIN_REMOVE.value)
                        return MessageType.MAIN_REMOVE

                    else:
                        logger.info("Message type is: %s", MessageType.MAIN_EDIT.value)
                        return MessageType.MAIN_EDIT
                else:
                    logger.info("Message type is: %s", MessageType.THREAD_EDIT.value)
                    return MessageType.THREAD_EDIT
        elif self._event.get("type") == "reaction_added":
            logger.info("Message type is: %s", MessageType.REACTION_ADD.value)
            return MessageType.REACTION_ADD
        elif self._event.get("type") == "reaction_removed":
            logger.info("Message type is: %s", MessageType.REACTION_REMOVE.value)
            return MessageType.REACTION_REMOVE
        raise ValueError("Failed to find event type on event %s", json.dumps(self._event))

    def get_event_group(self) -> Any:
        if self._event.get("subtype") == "message_changed":
            return MessageGroup.EDIT.value
        return MessageGroup.NEW.value


import torch
from torch.autograd import Variable
import torch.nn.functional as F
from settings import *
from torchvision import datasets, transforms
import torch.nn as nn
import numpy as np
import torch.optim as optim
import matplotlib
matplotlib.use('Agg')
from matplotlib import pyplot as plt
SCALE = 255.0
IMAGE_SIZE = 28 * 28
K = 1
EPOCH = 100
FAKE_IMG_SIZE = 256

def get_data_mnist_loader(train=True):
    return torch.utils.data.DataLoader(
        datasets.MNIST(MNIST_DATA,
                       train=train,
                       download=True,
                       transform=transforms.Compose([
                           transforms.ToTensor(),
                           # transforms.Normalize((0.1307,), (0.3081,))
                       ])),

        batch_size=BATCH_SIZE,
        shuffle=True)

class GeneratorNet(nn.Module):
    def __init__(self, input_size=IMAGE_SIZE, output_size=IMAGE_SIZE, layers=(50, 50), scale=SCALE):
        super(GeneratorNet, self).__init__()

        # self.layer_dims = np.concatenate(([input_size], list(layers), [output_size]))
        # self.fcs = [nn.Linear(self.layer_dims[i], self.layer_dims[i + 1]) for i in range(len(self.layer_dims) - 1)]
        # self.scale = SCALE
        self.fc1 = nn.Linear(FAKE_IMG_SIZE, 256)
        self.fc2 = nn.Linear(256, 512)
        self.fc3 = nn.Linear(512, 1024)
        self.fc4 = nn.Linear(1024, IMAGE_SIZE)
        self.sigmoid = nn.Sigmoid()

    def forward(self, x):
        # for i in range(len(self.fcs) - 1):
        x = Variable(x)
        x = F.relu(self.fc1(x))
        x = F.dropout(x, p=0.5)
        x = F.relu(self.fc2(x))
        x = F.dropout(x, p=0.5)
        x = F.relu(self.fc3(x))
        x = F.dropout(x, p=0.5)
        x = self.fc4(x)

        x = self.sigmoid(x)

        # x = torch.mul(x, SCALE)

        # x = x.view(-1, 1, 28, 28)
        return x

class DiscriminatorNet(nn.Module):
    def __init__(self, input_size=IMAGE_SIZE, output_size=1, layers_cnn=(32, 20), kernel=3, layers_dnn=(320, 50)):
        super(DiscriminatorNet, self).__init__()

        # self.conv_dims = np.concatenate(([input_size], list(layers_cnn)))
        # self.fc_dims = np.concatenate(([list(layers_dnn), [output_size]]))
        #
        # self.convs = [nn.Conv2d(i, i + 1, kernel_size=kernel) for i in range(len(self.fc_dims) - 1)]
        # self.fcs = [nn.Linear(self.fc_dims[i], self.fc_dims[i + 1]) for i in range(len(self.fc_dims) - 1)]
        # self.conv1 = nn.Conv2d(1, 5, kernel_size=kernel, padding=1)
        # self.conv2 = nn.Conv2d(5, 5, kernel_size=kernel, padding=1)
        #
        # self.fc1 = nn.Linear(5*IMAGE_SIZE, 1)
        # self.fc2 = nn.Linear(layers_dnn[1], output_size)

        self.fc1 = nn.Linear(IMAGE_SIZE, 512)
        self.fc2 = nn.Linear(512, 256)
        self.fc3 = nn.Linear(256, 128)
        self.fc4 = nn.Linear(128, 1)
        self.sigmoid = nn.Sigmoid()

    def forward(self, x):
        # for conv in self.convs:
        #     x = F.relu(conv(x))
        #
        # x = x.view(-1, self.fc_dims[0])
        #
        # for i in range(len(self.fcs) - 1):
        #     x = F.relu(self.fcs[i](x))
        #
        # x = self.fcs[-1](x)
        # print(x.shape)
        # x = F.relu(self.conv1(x))
        #
        # x = F.relu(self.conv2(x))
        #
        # x = x.view(-1, 5*IMAGE_SIZE) # hack
        #
        # x = self.fc1(x)
        x = x.view(-1, IMAGE_SIZE)
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = F.relu(self.fc3(x))
        x = self.fc4(x)

        x = self.sigmoid(x)

        return x

PRINT = False

def get_next_batch(data_loader, epoch=EPOCH):
    for ep in range(epoch):
        for batch_idx, (data, _) in enumerate(data_loader):
            yield ep, data.cuda()
        global PRINT

        PRINT = True
    yield None

def train(train_loader):
    gen_model = GeneratorNet()
    gen_model.cuda()
    gen_optimizer = optim.Adam(gen_model.parameters(), lr=0.000002)

    disc_model = DiscriminatorNet()
    disc_model.cuda()
    disc_optimizer = optim.Adam(disc_model.parameters(), lr=0.0002)

    batch_data = get_next_batch(train_loader, EPOCH)

    train_loop = True
    while(train_loop):
        gen_model.eval()
        disc_model.train()
        for i in range(K):
            try:
                _, data = next(batch_data)
            except StopIteration:
                train_loop = False
                break
            # for batch_idx, (data, _) in enumerate(train_loader):
            data = Variable(data)
            disc_optimizer.zero_grad()
            noise_data = torch.rand(data.size(0), FAKE_IMG_SIZE).cuda()

            y_noise_data = Variable(torch.zeros(data.size(0)).cuda())
            y_data = Variable(torch.ones(data.size(0)).cuda())

            loss_d_data = torch.nn.BCELoss()
            loss_d_noise_data = torch.nn.BCELoss()

            g_d = gen_model(noise_data)
            d_nd = disc_model(g_d)
            d_d = disc_model(data)

            loss_d = loss_d_data(d_d, y_data) + loss_d_noise_data(d_nd, y_noise_data)

            loss_d.backward()
            disc_optimizer.step()
            # print('Discriminator loss: %f' % loss_d)
        try:
            ep, data = next(batch_data)
        except StopIteration:
            train_loop = False
            break

        disc_model.eval()
        gen_model.train()
        gen_optimizer.zero_grad()

        y_data = Variable(torch.ones(data.size(0)).cuda())

        noise_data = torch.rand(data.size(0), FAKE_IMG_SIZE).cuda()  # hacky

        g_d = gen_model(noise_data)
        d_nd = disc_model(g_d)

        loss_g = torch.nn.BCELoss()
        loss_g = loss_g(d_nd, y_data)
        loss_g.backward()
        gen_optimizer.step()
        # print()
        # print('Generator loss: %f' % loss_g)
        global PRINT
        if PRINT:
            PRINT = False
            print('Discriminator loss: %f' % loss_d)
            print('Generator loss: %f' % loss_g)
            plt.imshow(g_d.cpu().data.numpy()[-1].reshape((28,28)), cmap='gray')
            plt.savefig(os.path.join(PLOT_DIR, 'plot_' + str(ep)))

def main():
    train_loader = get_data_mnist_loader(train=True)
    train(train_loader)

if __name__ == '__main__':
    main()


import sys
from PyQt5.QtWidgets import QDialog, QApplication
from messung1 import *

class MyMessungQT(QDialog):
    def __init__(self):
        super().__init__()
        self.ui=Ui_Messung()
        self.ui.setupUi(self)
        self.ui.Mstarten.clicked.connect(self.startMessung)
        self.ui.Mstoppen.clicked.connect(self.stopMessung)
        self.show()

    def startMessung(self):
        self.ui.Mstoppen.setEnabled(True)
        self.ui.Mstarten.setEnabled(False)

    def stopMessung(self):
        self.ui.Mstoppen.setEnabled(False)
        self.ui.Mstarten.setEnabled(True)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    w = MyMessungQT()
    w.show()
    sys.exit(app.exec_())


import cv2

face_cascade = cv2.CascadeClassifier("user/haarcascade_frontalface_default.xml")
src = cv2.imread('user/2020-11-30_16h13_39.png')
#http://localhost/fs/pub/533a250b/2020-11-30_12h54_46.png
#http://localhost/fs/pub/533a250b/2020-11-30_16h13_39.png
src_gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)

faces = face_cascade.detectMultiScale(src_gray)

for x, y, w, h in faces:
    cv2.rectangle(src, (x, y), (x + w, y + h), (255, 0, 0), 2)
    face = src[y: y + h, x: x + w]
    face_gray = src_gray[y: y + h, x: x + w]
    #eyes = eye_cascade.detectMultiScale(face_gray)
    #for ex, ey, ew, eh in eyes:
    #    cv2.rectangle(face, (ex, ey), (ex + ew, ey + eh), (0, 255, 0), 2)
cv2.imshow("face", src)


from pyfirmata2 import Arduino
from time import sleep
import matplotlib.pyplot as plt

signal = []

def my_cb(data):
    # print(data)
    signal.append(data)
    #pass

board = Arduino(Arduino.AUTODETECT)

board.samplingOn(10)  # ms

board.analog[0].register_callback(my_cb)
board.analog[0].enable_reporting()

lenPin = board.get_pin('d:3:p')

lum = 0
delta_lum = 0.05;

for t in range(50):
    sleep(0.5)
    if lum > 1.0 or lum < 0:
        delta_lum = -delta_lum
    lum += delta_lum
    lenPin.write(lum)

lenPin.write(0)

plt.plot(signal)
plt.show()

board.exit()


# 344 ms
from collections import Counter as nyaaaa

def count_valid(lower, upper):
    count = 0
    for pw in range(lower, upper + 1):
        s = str(pw)

        never_decreasing = True
        for idx in range(len(s) - 1):
            if s[idx] > s[idx + 1]:
                never_decreasing = False
                break

        if never_decreasing:
            freq_map = nyaaaa(s)
            if any(k == 2 for k in freq_map.values()):
                count += 1
    return count

def is_valid(number):
    s = str(number)

    never_decreasing = True
    for idx in range(len(s) - 1):
        if s[idx] > s[idx + 1]:
            never_decreasing = False
            break

    if never_decreasing:
        freq_map = nyaaaa(s)
        if any(k == 2 for k in freq_map.values()):
            return True
    return False

# 344 ms
def f1():
    return count_valid(134792, 675810 + 1)

# 445 ms
def f2():
    return sum([1 if is_valid(i) else 0 for i in range(134792, 675810 + 1)])

# 520 ms
def f3():
    return nyaaaa(is_valid(i) for i in range(134792, 675810 + 1))[True]

print(f1())
print(f2())
print(f3())


import random
def NumberGuessingGame():
        chances = 0
        randomnumber=random.randint(1,10)
        while chances<5:
            guess = int(input("Enter the guessed number: "))
            if guess == randomnumber:
                print("Hurray! You got it!")
                break
            elif guess < randomnumber:
                print(" Your number is less than the random number")
            else:
                print(" Your number is greater than the random number")
            chances += 1
        if not chances<5:
            print("You loose!!! The number is", randomnumber)

NumberGuessingGame()


""" Patch plone.app.layout ver 2.2.7, due to #9518
"""
from plone.app.layout.navigation import root as nav_root
from Products.CMFCore.utils import getToolByName
from zope.component.hooks import getSite

def getNavigationRootObject(context, portal):
    """ Patched getNavigationRootObject in order to return site root
    """
    if context is None:
        return None

    ### patch #9518 return root + context language as navigationRootObject
    # #16662 define portal as it might be an empty parameter when using a
    # dexterity object
    portal = portal or getSite()
    portal_url = '/'.join(portal.getPhysicalPath())
    if portal_url[-1] != '/':
        portal_url += '/'
    lang = context.Language()
    # check if portal_url is /www as this code could be reached from tests
    # where we don't have SITE
    if portal_url != '/www/':
        return portal
    if lang:
        # use  same logic for getting the navigationRootObject like the
        # one used and explained in getNavigationRoot
        context_path_root = context.getPhysicalPath()
        context_path_root = context_path_root[2] if \
                    len(context_path_root) > 2 else context_path_root[-1]
        lang = lang if lang != 'en' else 'SITE'
        if context_path_root != lang:
            return portal.get(context_path_root)
        return portal.get(lang)
    return portal
    ### end patch

def getNavigationRoot(context, relativeRoot=None):
    """Get the path to the root of the navigation tree.

    If a relativeRoot argument is provided, navigation root is computed from
    portal path and this relativeRoot.

    If no relativeRoot argument is provided, and there is a root value set in
    portal_properties, navigation root path is computed from
    portal path and this root value.

    IMPORTANT !!!
    Previous paragraphs imply relativeRoot is relative to the Plone portal.

    Else, a root must be computed : loop from the context to the portal,
    through parents, looking for an object implementing INavigationRoot.
    Return the path of that root.
    """
    portal_url = getToolByName(context, 'portal_url')

    if relativeRoot is None:
        # fetch from portal_properties
        portal_properties = getToolByName(context, 'portal_properties')
        navtree_properties = getattr(portal_properties, 'navtree_properties')
        relativeRoot = navtree_properties.getProperty('root', None)

    ### Original code:

    ## if relativeRoot has a meaningful value,
    #if relativeRoot and relativeRoot != '/':
    #    # use it
    #
    #    # while taking care of case where
    #    # relativeRoot is not starting with a '/'
    #    if relativeRoot[0] != '/':
    #        relativeRoot = '/' + relativeRoot

    #    portalPath = portal_url.getPortalPath()
    #    return portalPath + relativeRoot

    ### Start patch

    if relativeRoot:
        if relativeRoot[0] != '/':
            relativeRoot = '/' + relativeRoot

        portalPath = portal_url.getPortalPath()
        # return old logic if portalPath isn't /www
        if portalPath != '/www':
            return portalPath + relativeRoot
        lang = context.Language()
        portal = portal_url.getPortalObject()
        if lang:
            lang = lang if lang != 'en' else 'SITE'
            context_path_root = context.getPhysicalPath()
            # check if length of physicalPath is greater than 2 as we might
            # get a result where we are on the root path and it results in
            # ('', 'www')
            context_path_root = context_path_root[2] if \
                    len(context_path_root) > 2 else context_path_root[-1]
            # context_path_root will return the path after www, from the
            # context, if it is not equal to lang then it means that the
            # context is of different language from the root of the context
            # but we should use that context_path_root in order to preserve
            # correct listing ex: /www/SITE/tests/romanian-page should return
            # /www/SITE as the navigationRoot and not /www/ro even thou the
            # page is romanian since it is created in the /www/SITE english
            # folder
            if context_path_root != lang:
                return portalPath + '/' + context_path_root
            return portalPath + '/' + lang
        return portalPath + relativeRoot
    ### End patch

    else:
        # compute the root
        portal = portal_url.getPortalObject()
        root = getNavigationRootObject(context, portal)
        return '/'.join(root.getPhysicalPath())

nav_root.getNavigationRoot = getNavigationRoot
nav_root.getNavigationRootObject = getNavigationRootObject


"""
Metrics functions
"""

from pyfit.engine import Scalar, Vector

def mean_squared_error(y_true: Vector, y_pred: Vector) -> Scalar:
    """MSE loss"""

    total_squared_error: Scalar = sum(
        (
            (y_true_i - y_pred_i) * (y_true_i - y_pred_i)
            for (y_true_i, y_pred_i) in zip(y_true, y_pred)
        ),
        Scalar(0),
    )
    n_total: int = max(len(y_true), 1)
    return total_squared_error / n_total

def binary_accuracy(y_true: Vector, y_pred: Vector) -> float:
    """Binary accuracy"""

    n_exact: int = sum(
        [
            y_true_i.data == round(y_pred_i.data)
            for (y_true_i, y_pred_i) in zip(y_true, y_pred)
        ]
    )
    n_total: int = max(len(y_true), 1)
    return n_exact / n_total


import re

from libadventofcode import base
from libadventofcode import registry

class Solver(base.Solver):
    def solve1(self, data):
        r = re.compile(r'(\d+)-(\d+) (.): (.*)')
        data = data.splitlines()

        data = [r.match(line).groups() for line in data]
        res = 0
        for mi, ma, c, pwd in data:
            if pwd.count(c) in range(int(mi), int(ma) + 1):
                res += 1

        return res

    def solve2(self, data):
        r = re.compile(r'(\d+)-(\d+) (.): (.*)')
        data = data.splitlines()

        data = [r.match(line).groups() for line in data]
        res = 0
        for idx1, idx2, c, pwd in data:
            if (pwd[int(idx1)-1] == c) ^ (pwd[int(idx2)-1] == c):
                res += 1

        return res

registry.register((__name__.split(".")[-2], str(int(__name__[-2:]))), Solver())


x=int(input("Enter the amount in PLN: "))
five=0
two=0
one=0
while x>0:
    if x>=5:
        five=five+1
        x=x-5
    elif x>=2:
        two=two+1
        x=x-2
    elif x>=1:
        one=one+1
        x=x-1
print(f"Amount of PLN {x} in coins")
print(f"5zł - {five}")
print(f"2zł - {two}")
print(f"1zł - {one}")