""" Modified ReLU activation functions: Leaky ReLU and Parametrized ReLU, plus a batch normalisation wrapper. """

import tensorflow as tf
import numpy as np

def lrelu(input_data, multiplier, scope_id):
    """ An implementation of Leaky ReLU, outlined in 'Rectifier nonlinearities improve neural network acoustic models.'
    by Maas et al. a should be low: nmarkou.blogspot.de/2017/02/the-black-magic-of-deep-learning-tips.html """
    with tf.name_scope('lrelu_{:s}'.format(scope_id)):
        # Get boundaries
        maximum_value = tf.reduce_max(input_data, name='max_value')
        minimum_value = tf.reduce_min(input_data, name='min_value')
        # Clip values
        input_pos = tf.clip_by_value(input_data, clip_value_min=0, clip_value_max=maximum_value, name='min_clipped')
        input_neg = tf.clip_by_value(input_data, clip_value_min=minimum_value, clip_value_max=0, name='max_clipped')
        # Apply negative sloping
        out = tf.add(input_pos, tf.multiply(input_neg, multiplier), name='combined')
    return out

def prelu(input_data, scope_id, dtype):
    """ An implementation of the PReLU activation function following 'Delving Deep into Rectifiers: Surpassing Human-
    Level Performance on ImageNet Classification' by He et al. """
    # Declare adaptive multiplier parameter
    with tf.variable_scope('prelu_{:s}'.format(scope_id)):
        multiplier = tf.get_variable(
            name='multiplier', shape=[], initializer=tf.constant_initializer(0.25, dtype=dtype))
    return lrelu(input_data, multiplier, scope_id)

# Alternatively, for comparison to simplified implementation
# from tensorflow.contrib.layers.python.layers import batch_norm (might have changed with 1.0)

def batch_norm_wrapper(inputs, dims_out, scope_id, is_train, decay=0.999):
    """ A batch norm handler implmentation following r2rt.com/implementing-batch-normalization-in-tensorflow.html.
            inputs = inputs to a layer's activation function
            is_training = conditions the update
            decay = weighting of updates within the moving average and variance calculation.
    """
    # Declare parameters
    with tf.variable_scope('{:s}_batch_norm'.format(scope_id)):
        offset = tf.get_variable(name='offset', shape=[1, dims_out],
                                 initializer=tf.zeros_initializer())
        scale = tf.get_variable(name='scale', shape=[1, dims_out],
                                initializer=tf.ones_initializer())
        population_mean = tf.get_variable(name='pop_mean', shape=[dims_out],
                                          initializer=tf.zeros_initializer(), trainable=False)
        population_var = tf.get_variable(name='pop_var', shape=[dims_out],
                                         initializer=tf.ones_initializer(), trainable=False)
        # Avoids division by zero
        epsilon = 1e-3

        def _batch_bn():
            # Get batch statistics along the batch dimension
            batch_mean, batch_var = tf.nn.moments(inputs, [0])
            # Update population statistics
            train_mean = tf.assign(population_mean, tf.add(tf.multiply(population_mean, decay),
                                                           tf.multiply(batch_mean, 1 - decay)), name='pop_mean_update')
            train_var = tf.assign(population_var, tf.add(tf.multiply(population_var, decay),
                                                         tf.multiply(batch_var, 1 - decay)), name='pop_var_update')
            # Apply batch normalization using the approximation of population statistics
            with tf.control_dependencies([train_mean, train_var]):
                return tf.nn.batch_normalization(inputs, batch_mean, batch_var, offset, scale, epsilon,
                                                 name='training_batch_norm')

        def _pop_bn():
            return tf.nn.batch_normalization(inputs, population_mean, population_var, offset, scale, epsilon,
                                             name='testing_batch_norm')

        if is_train:
            norm_function = _batch_bn()
        else:
            norm_function = _pop_bn()

        return norm_function

def layer_norm_wrapper(inputs, dims_out, scope_id, _):
    """ Layer normalization implementation for use with WGAN-GP models;
    behaves identically during training and inference. """
    # see theneuralperspective.com/2016/10/27/gradient-topics
    with tf.variable_scope('{:s}_layer_norm'.format(scope_id)):
        layer_mean, layer_var = tf.nn.moments(inputs, [1], keep_dims=True)
        offset = tf.get_variable(name='offset', shape=[dims_out],
                                 initializer=tf.zeros_initializer())
        scale = tf.get_variable(name='scale', shape=[dims_out],
                                initializer=tf.ones_initializer())
        epsilon = 1e-5
        normalized = scale * (inputs - layer_mean) / tf.sqrt(layer_var + epsilon) + offset
    return normalized

class EncodingsBuffer(object):
    """ Buffer for storing sentence encodings produced by a GAN generator, used in the discriminator network updates;
    intended to reduce oscillation during GAN training as suggested in arxiv.org/pdf/1703.10593.pdf;
    implementation is comparable to github.com/junyanz/pytorch-CycleGAN-and-pix2pix/blob/master/util/image_pool.py. """
    def __init__(self, opt, name, size_factor=50):
        self.opt = opt
        self.name = name
        self.buffer_size = self.opt.batch_size * size_factor  # Paper uses a buffer size of 50 and batch size of 1

        # Initialize the pool
        if self.buffer_size > 0:
            self.buffer = list()
            self.buffered = 0

    def query(self, batch_input):
        """ Adds supplied encodings into the current pool and returns encodings sampled from the present pool. """
        # No buffering
        if self.buffer_size == 0:
            out = batch_input
        else:
            # Split batch into individual encodings
            encodings = tf.split(batch_input, tf.shape(batch_input)[0], axis=0)
            out = list()
            for enc in encodings:
                # Fill buffer
                if self.buffered < self.buffer_size:
                    self.buffered += 1
                    self.buffer.append(enc)
                    out.append(enc)
                # Sample randomly from buffer
                else:
                    flip = np.random.uniform(0.0, 1.0)
                    if flip > 0.5:
                        replace_id = np.random.randint(0, len(self.buffer))
                        out.append(self.buffer[replace_id])
                        self.buffer[replace_id] = enc
                    else:
                        out.append(enc)
        # Return a batch tensor of the same size as the input batch
        return tf.concat(out, axis=0)


import pandas
import os
import random
import argparse
import pysam
from FastqStreamer.FastqReader import FastqReader
from BamStreamer.BamUtils import read_alignments
##from FastqIterator import FastqIterator
##from link_bams import BamLinker

class IPeteSpikeIn(FastqReader):
    """
    Filter spike-in reads from fastq file

    Attributes
    ----------
    spikes : pandas data frame
    Pandas data frame containing spike-in alignments

    spike_stats : dict
    Dictionary for counting spike-in alignments
    """

    def __init__(self, spikein, reference_annot_file, basename):
        FastqReader.__init__(self)
        self.spikes = self.load_spike_aln(spikein)
        self.spike_stats = {}
        self.basename = basename

    def load_spike_aln(self, spikeBam):
        """
        Read spike in alignment names into memory, store read and spikeID together

        Parameters
        ----------
        spikeBam : str
        path to spikein alignment bam file

        Returns
        -------
        spikes : dict
        dictionary of read name keys and spikeId values

        """
        spikes = {}
        for read in read_alignments(spikeBam):
            read_name = read["query_name"]
            spikes[read_name] = read['reference_name']
        return spikes

    def split_bams(self, Vbam, Jbam):
        """
        use spikein read alignments to split V and J alignments into spike-in and native read files.

        Sbam : str
        spikein alignments bam file
        Vbam : str
        Vgene alignments bam file
        Jbam : str
        Jgene alignments bam file
        """

        Vsam = pysam.AlignmentFile(Vbam, "rb", check_sq=False)
        nativeV = pysam.AlignmentFile("{}_Vgene_native.bam".format(self.basename), "wb", template=Vsam)
        spikeV = pysam.AlignmentFile("{}_Vgene_spikein.bam".format(self.basename), "wb", template=Vsam)
        Vsam.close()
        ##split V gene alignments reads based on spikein alignments
        for read in read_alignments(Vbam):
            if read["query_name"] in self.spikes:
                spikeV.write(read['pyread'])
            else:
                nativeV.write(read['pyread'])
        nativeV.close()
        spikeV.close()
        Jsam = pysam.AlignmentFile(Jbam, "rb", check_sq=False)
        nativeJ = pysam.AlignmentFile("{}_Jgene_native.bam".format(self.basename), "wb", template=Jsam)
        spikeJ = pysam.AlignmentFile("{}_Jgene_spikein.bam".format(self.basename), "wb", template=Jsam)
        Jsam.close()
        ##split J gene alignments reads based on spikein alignments
        for read in read_alignments(Jbam):
            if read["query_name"] in self.spikes:
                spikeJ.write(read['pyread'])
            else:
                nativeJ.write(read['pyread'])
        nativeJ.close()
        spikeJ.close()

        ##can also process with `read_two_bams` via BamParser, but that is slower with larger files.

    def label_spikeins(self, spikeDF, spikeUMI_df):
        UMI_groups = spikeDF.UMI_group.unique()
        spikeGroups = {}
        for group in UMI_groups:
            groupDF = spikeDF.loc[spikeDF["UMI_group"] == group]
            family_size = groupDF.shape[0]
            Spikes = groupDF["spikein"].value_counts(dropna=False)
            spikeGroups[group] = Spikes.idxmax()
        spikeUMI_df["spikein"] = spikeUMI_df["UMI_group"].map(lambda x : spikeGroups[x])
        return spikeUMI_df

    def cummulative_stats(self, df):
        df["cummulative_reads"] = df["UMI_family_size"].cumsum()
        df["cummulative_fraction"] = df["cummulative_reads"] / sum(df["UMI_family_size"])
        return df

    def split_umi_reports(self, VDJfile, UMIfams):
        VDJreport = pandas.read_csv(VDJfile, sep="\t")
        UMIreport = pandas.read_csv(UMIfams, sep="\t")
        ## spikein reads by name
        VDJspikein1 = VDJreport[VDJreport["name"].isin(self.spikes)]
        VDJspikein1["spikein"] = VDJspikein1["name"].map(lambda x : self.spikes[x])
        ## native reads by name
        VDJnative = VDJreport[~VDJreport["name"].isin(self.spikes)]
        ## spike in reads by UMI group
        VDJspikein2 = VDJnative[VDJnative["UMI_group"].isin(VDJspikein1["UMI_group"])]
        VDJspikein = pandas.concat([VDJspikein1, VDJspikein2])
        NativeReport = UMIreport[~UMIreport["UMI_group"].isin(VDJspikein["UMI_group"])]
        SpikeinReport = UMIreport[UMIreport["UMI_group"].isin(VDJspikein["UMI_group"])]
        SpikeinReport = self.cummulative_stats(SpikeinReport)
        NativeReport = self.cummulative_stats(NativeReport)
        ## count spikeins
        SpikeinReport = self.label_spikeins(VDJspikein, SpikeinReport)
        ##label UMI report with consensus spikein label
        ##output files
        nativeTabOut = "{}_on_target_umi_groups_native.tsv".format(self.basename)
        spikeTabOut = "{}_on_target_umi_groups_spikein.tsv".format(self.basename)
        nativeUMIOut = "{}_cdr3_dedup_report_native.tsv".format(self.basename)
        spikeUMIOut = "{}_cdr3_dedup_report_spikein.tsv".format(self.basename)
        ##write output
        VDJnative.to_csv(nativeTabOut, sep="\t", index=False)
        VDJspikein.to_csv(spikeTabOut, sep="\t", index=False)
        NativeReport.to_csv(nativeUMIOut, sep="\t", index=False)
        SpikeinReport.to_csv(spikeUMIOut, sep="\t", index=False)

    def report_spikein_counts(self, VJaln, outFile):
        """
        write a report file of spike-in sequences

        Parameters
        ----------
        outFile : str
        Path to output file

        Returns
        -------
        None
        """
        # summarize VJ alignments of spike-in reads
        VJspike = {}
        try:
            aln = pandas.read_csv(VJaln, sep="\t")
            if len(aln) > 0:
                for name, Vgene, Jgene, uid_group in zip(aln["name"], aln["v_gene"], aln["j_gene"], aln["UMI_group"]):
                    VJpair = "{}__{}".format(Vgene, Jgene)
                    if name in self.spikes:
                        spikeId = self.spikes[name]
                        if not spikeId in VJspike:
                            VJspike[spikeId] = {"match": 0, "diff": 0, "uids": []}
                        if VJpair == spikeId:
                            VJspike[spikeId]["match"] += 1
                        else:
                            VJspike[spikeId]["diff"] += 1
                        uid = "{}_{}".format(VJpair, uid_group)
                        VJspike[spikeId]["uids"].append(uid)
                # create summary for spike-in reads
                for name in self.spikes:
                    spike = self.spikes[name]
                    if not spike in self.spike_stats:
                        self.spike_stats[spike] = {"reads": 0,
                                                   "on_target": 0,
                                                   "VJ_match": 0,
                                                   "dedup_count": 0}
                    self.spike_stats[spike]["reads"] += 1
                for spike in self.spike_stats:
                    if spike in VJspike:
                        self.spike_stats[spike]["on_target"] = (
                            VJspike[spike]["match"] + VJspike[spike]["diff"])
                        self.spike_stats[spike]["VJ_match"] = VJspike[spike]["match"]
                        self.spike_stats[spike]["dedup_count"] = len(set(VJspike[spike]["uids"]))
        except Exception as e:
            print("Error: ", e)
            pass
        # spike-in report
        with open(outFile, 'w') as fhOut:
            fhOut.write("synthetic,reads,on_target,VJ_match,dedup_count\n")
            for spike in self.spike_stats:
                vals = [spike,
                        str(self.spike_stats[spike]["reads"]),
                        str(self.spike_stats[spike]["on_target"]),
                        str(self.spike_stats[spike]["VJ_match"]),
                        str(self.spike_stats[spike]["dedup_count"])]
                vals = ",".join(vals)+"\n"
                fhOut.write(vals)

def main():
    parser = argparse.ArgumentParser(
        description="gather amplicon stats from bam file")
    parser.add_argument("-s", "--spike_aln",
                        required=True,
                        help="Spike in alignment bam")
    parser.add_argument("-v", "--v_aln",
                        required=True,
                        help="V gene alignment bam")
    parser.add_argument("-j", "--j_aln",
                        required=True,
                        help="J gene alignment bam")
    parser.add_argument("-VJ", "--VJ_umi",
                        required=True,
                        help="V & J gene alignment summary file")
    parser.add_argument("-d", "--dedup_report",
                        required=True,
                        help="V & J gene alignment summary file")
    parser.add_argument("-r", "--reference_annot",
                        required=True,
                        help="reference annotation file")
    parser.add_argument("-b", "--basename",
                        required=True,
                        help="basename argument for report file name")
    args = parser.parse_args()
    parser = IPeteSpikeIn(args.spike_aln, args.reference_annot, args.basename)
    parser.split_bams(args.v_aln, args.j_aln)
    parser.split_umi_reports(args.VJ_umi, args.dedup_report)
    ##parser.report_spikein_counts(args.VJaln, "{}_{}".format(
    ##args.basename, "spikein_stats.csv"))

if __name__ == '__main__':
    main()


import pandas as pd

length = 93
num_followers = []

file_error_location = 'C:\\Users\\Giacomo\\Documents\\Università\\Magistrale\\Network Science (Mod. B)\\Interdisciplinary Project\\Elaborazione Dati\\UPDATED_DATASET.xlsx'
df = pd.read_excel(file_error_location)

#print(df)

for x in range(0,length):
    num_followers.append(int(df.loc[x]['FOLLOWERS']))

#print(num_followers)

out = ''
for x in range(0, length):
    out = out + str(num_followers[x]) + '\n'
saveFile = open('Num_Followers.txt', 'w')
saveFile.write(out)
saveFile.close()


import configparser
import os

def has_config(path):
    """Returns true if gritter config file exists."""
    return True if os.path.isfile(path) else False

def create_config(path):
    """Create the config file iff it doesn't exist."""
    if not os.path.exists(os.path.dirname(path)):
        os.makedirs(os.path.dirname(path))
    if not has_config(path):
        open(path, 'a').close()

def set_auth(path, args):
    """Sets auth args in config."""
    config = configparser.ConfigParser()
    config.read(path)
    # clobber old auth values
    config["auth"] = {}
    for k, v in args.items():
        config["auth"][k] = v

    with open(path, 'w') as configfile:
        config.write(configfile)

def get_auth(path):
    """Gets dict of auth args from config."""
    config = configparser.ConfigParser()
    config.read(path)
    return config["auth"]


roman = {
    "I": 1,
    "V": 5,
    "X": 10,
    "L": 50,
    "C": 100,
    "D": 500,
    "M": 1000
}

x = "IVI"
previous_char = ""
nums = []

for i in x:
    if previous_char == "":
        previous_char = i
        nums.append(roman[i])
        continue
    if roman[i] > roman[previous_char]:
        num = roman[previous_char] - roman[i]
        nums.append(num)
    else:
        nums.append(roman[i])

print(sum(nums))


import snscrape.modules.twitter as sntwitter
import pandas as pd
import itertools
import time
import datetime
from datetime import timedelta

# start = datetime.date(2022, 12, 1)
# # end = datetime.date(2022, 12, 25)
# end = datetime.date.today()
# start = end - timedelta(days = 31)

# end = end.strftime('%Y-%m-%d')
# start = start.strftime('%Y-%m-%d')

from classifier import pre_process,predict_emotion,predict_sentiment
# def scrapeTweet(keyword, start,end,n):
#     df = getTweets(str(keyword).lower(),start,end,n)
#     df = getSentiment(df)
#     df = getEmotion(df)
#     return df
from classifier_dev import pre_process, predict_emotion,predict_sentiment

def getUser(df,Col):
    col = df[Col].values

def getTweets(keyword,start,end,n,loc):
    keyword = keyword
    df = pd.DataFrame(itertools.islice(
            sntwitter.TwitterSearchScraper(
            f'{keyword} {loc} since:{start} until:{end}',maxEmptyPages=100)
            .get_items(),n)
            )[['id','date', 'rawContent', 'user','mentionedUsers',
            'replyCount', 'retweetCount', 'likeCount','quoteCount','viewCount','place','hashtags']]
            # 'lang','coordinates', 'place', 'hashtags','url']]
    df['username'] = df['user'].str['username']
    df['followers'] = df['user'].str['followersCount']
    df['mentioned'] = [[d.get('username') for d in x] if x is not None else [] for x in df['mentionedUsers']]
    df['text'] = df['rawContent'].apply(pre_process)
    df['emotion'] = df['text'].apply(predict_emotion)
    df['sentiment'] = df['text'].apply(predict_sentiment)
    keywords=[]
    for i in df['id']:
        keywords.append(keyword)
    df['keyword'] = keywords
    # df['city'] = df['place'].str['city']
    # df['mentioned'] = df['mentionedUsers'].apply( lambda x: [d['username'] for d in x])
    return df[['id','keyword','date','username','rawContent','sentiment','emotion','viewCount','replyCount', 'retweetCount', 'likeCount', 'quoteCount','followers','mentioned','hashtags']]
#     # return df.explode('mentioned')

#columnlist: ['url', 'date', 'rawContent', 'renderedContent', 'id', 'user',
    #    'replyCount', 'retweetCount', 'likeCount', 'quoteCount',
    #    'conversationId', 'lang', 'source', 'sourceUrl', 'sourceLabel', 'links',
    #    'media', 'retweetedTweet', 'quotedTweet', 'inReplyToTweetId',
    #    'inReplyToUser', 'mentionedUsers', 'coordinates', 'place', 'hashtags',
    #    'cashtags', 'card',  'vibe']

sing= f'lang:en near:"Jakarta" within:50km'

ausie = f'lang:en geocode:-25.165173,134.386371,2000km'
# ausie = f'lang:en geocode:-25.165173,134.386371,2000km'
usa = f'country_code:us'
indo = f'lang:id'
key_indo = f'(motor listrik) OR (mobil listrik) OR (kendaraan listrik)'
key_aus = f'(electric car) OR (electric vehicle)'
import datetime, calendar
# from calendar import monthrange
# monthrange(2014, 2)

keyword = key_aus
loc = usa
year = 2023
month = 4
numb = 10
num_days = calendar.monthrange(year, month)[1]
# num_days = 2
dates = list(range(1, num_days+1))
current_time = datetime.datetime.now()
today = current_time.day

df = None
for i in dates:
    if datetime.datetime(year, month, i) > current_time:
        df1 = None
    # elif month>11:
    #     df1 = getTweets(keyword,f'{year}-{month}-{i}',f'{year+1}-1-1',numb,loc)
    # elif i == dates[-1]:
    #     df1 = getTweets(keyword,f'{year}-{month}-{i}',f'{year}-{month+1}-1',numb,loc)
    elif i < dates[-1]:
        df1 = getTweets(keyword,f'{year}-{month}-{i}',f'{year}-{month}-{i+1}',numb,loc)
    else:
        df1 = None
    df = pd.concat([df,df1])

# df = getTweets(keyword,f'{year}-{month}-1',f'{year}-{month+1}-1',numb,loc)
# # df = pd.concat([df,df1])
# df.to_csv(f'EVUS-{year}{month}.csv')
print(df.tail())


import torch
import torch.nn.functional as F
import torch.nn as nn
from torchvision.models import resnet18

class Network(torch.nn.Module):
    def __init__(self):
        super().__init__()
        self.fc1 = torch.nn.Linear(input_size, 256)
        self.fc2 = torch.nn.Linear(256, 128)
        self.fc3 = torch.nn.Linear(128, 64)
        self.fc4 = torch.nn.Linear(64, classes)

        # Dropout module with 0.2 drop probability
        self.dropout = torch.nn.Dropout(p=0.2)

    def forward(self, x):
        # make sure input tensor is flattened
        x = x.view(x.shape[0], -1)

        # Now with dropout
        x = self.dropout(F.relu(self.fc1(x)))
        x = self.dropout(F.relu(self.fc2(x)))
        x = self.dropout(F.relu(self.fc3(x)))

        # output so no dropout here
        x = F.log_softmax(self.fc4(x), dim=1)

        return x

class Lenet5(torch.nn.Module):
    def __init__(self, classes):
        super().__init__()
        self.conv = torch.nn.Sequential(

            torch.nn.Conv2d(3, 6, 5), # out = (in - kernal + 2*padding) / stride + 1  (1, 28, 28) -> (6, 24, 24)
            torch.nn.ReLU(),
            torch.nn.AvgPool2d(2, stride=2), # (N, 6, 24, 24) - > (N, 6, 12, 12)

            torch.nn.Conv2d(6, 16, 5),  #  (N, 6, 12, 12) -> (N. 6, 8, 8)
            torch.nn.ReLU(),
            torch.nn.AvgPool2d(2, stride=2)  # (N, 16, 8, 8) -> (N, 16, 4 4)
        )
        self.fc = torch.nn.Sequential(
            # torch.nn.Linear(256, 120), #(N, 256) - > (N, 120)
            # torch.nn.ReLU(),
            # torch.nn.Linear(120, 84), #(N, 120) - > (N, 84)
            # torch.nn.ReLU(),
            # torch.nn.Linear(84, classes)

            # torch.nn.Linear(576, 256),
            # torch.nn.ReLU(),

            torch.nn.Linear(256, classes),
            torch.nn.ReLU(),
            torch.nn.Linear(classes, classes),

            )
    def forward(self, x):
        x = self.conv(x)
        # print(x.size()) # torch.Size([64, 16, 4, 4])
        x = x.view(x.size(0), -1)  # batch_size is x.size(0)

        x = self.fc(x)
        return x

def my_resnt18(classes):
    resnet = resnet18()
    resnet.fc = torch.nn.Linear(in_features=512, out_features=classes, bias=True)
    resnet.add_module("softmax", torch.nn.Softmax(dim=-1))

    return resnet

# classes =145
# myresnt18 = resnet18()
# myresnt18.fc = torch.nn.Linear(in_features=512, out_features=classes, bias=True)
# myresnt18.add_module("softmax", torch.nn.Softmax(dim=-1))

class FashionCNN(nn.Module):
    def __init__(self, classes):
        super().__init__()
        self.layer1 = nn.Sequential(
            nn.Conv2d(in_channels=3, out_channels=32, kernel_size=3, padding=1),
            nn.BatchNorm2d(32),
            nn.ReLU(),
            nn.MaxPool2d(kernel_size=2, stride=2)
        )

        self.layer2 = nn.Sequential(
            nn.Conv2d(in_channels=32, out_channels=64, kernel_size=3),
            nn.BatchNorm2d(64),
            nn.ReLU(),
            nn.MaxPool2d(2)
        )

        self.fc1 = nn.Linear(in_features=64*6*6, out_features=600)
        self.drop = nn.Dropout2d(0.25)
        self.fc2 = nn.Linear(in_features=600, out_features=300)  #   classes: 300 to 120 to 10
        self.fc3 = nn.Linear(in_features=300, out_features=classes)

    def forward(self, x):
        out = self.layer1(x)
        out = self.layer2(out)
        out = out.view(out.size(0), -1)
        out = self.fc1(out)
        out = self.drop(out)
        out = self.fc2(out)
        out = self.fc3(out)

        return out


#!/usr/bin/env python3

import threading
import json
import socket
import wave
import pyaudio
import numpy as np
import requests

import signal
import sys

from time import sleep
from utils.camera_utils import Vector3
from pydub import AudioSegment
from pydub.playback import play

# def signal_handler(sig, frame):
#     print('You pressed Ctrl+C!')
#     sys.exit(0)

# print('Press Ctrl+C')
# signal.pause()

class SoundServer:
    def __init__(self, api_params={'host': 'localhost', 'port': 5000}, self_params={'host': 'localhost', 'port': 50002}) -> None:
        self.self_params: dict = self_params
        self.api_params:  dict = api_params
        self.sound_chunk_queue: list = []
        self.chunk_size: int = 256
        self.running: bool = True
        self.can_play: bool = False

        self.observer_pos = Vector3(0, 0, 0)
        self.sounndev_pos = Vector3(0, 0, 0)
        # self.socket = None

    def stop_signal_handler(self, sig, frame):
        self.running = False
        print('\nReceived interrrupt signal')
        # if self.socket:
        #     self.socket.close()

        # to force the socket.listen.close()
        socket.socket(
            socket.AF_INET,
            socket.SOCK_STREAM
        ).connect( (self.self_params['host'], self.self_params['port']))

    def observer_loop(self):
        while self.running:
            try:
                result = json.loads(requests.get(f"http://{self.api_params['host']}:{self.api_params['port']}/people").text)
                obs = {}
                for obj in result[::-1]:
                    if obj['id'] == '-1':
                        obs = obj
                        break

                self.observer_pos = Vector3(
                    obs['x'],
                    obs['y'],
                    obs['z']
                )
                # print(self.observer_pos)
            except Exception as e:
                print(e)
                pass

            sleep(0.1)

    def receive_loop(self):
        self_host = self.self_params['host']  # Standard loopback interface address (localhost)
        self_port = self.self_params['port']  # Port to listen on (non-privileged ports are > 1023)

        while self.running:
            print('Opening socket')
            num = 0
            try:
                with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
                    # self.socket = s
                    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
                    s.bind(("0.0.0.0", self_port))
                    print('binded')
                    s.listen()
                    print('listened')
                    conn, addr = s.accept()
                    print('accepted')
                    print('Opened socket')
                    with conn:
                        print(f"Connected by {addr}")
                        while self.running:
                            try:
                                data = conn.recv(self.chunk_size)
                            except:
                                print('hmm has the client died or something?')
                            if not data:
                                break
                            # conn.sendall(data)
                            # print(num, data[0])
                            # frames.append(data)

                            # stream.write(data)
                            self.sound_chunk_queue.append(data)

                            # for i in xrange(0, len(signal), lframe):
                            # data = np.frombuffer(data)
                            # sd.play(data, RATE, blocking=False)
                            num += 1

                            if len(self.sound_chunk_queue) > 30:
                                self.can_play = True
            except Exception as e:
                print(e)

    def playback_loop(self):
        FORMAT = pyaudio.paInt16
        CHANNELS = 1
        RATE = 44100

        observer_distance = 0

        p = pyaudio.PyAudio()
        stream = p.open(
            format=FORMAT,
            channels=CHANNELS,
            rate=RATE,
            output=True,
            frames_per_buffer=self.chunk_size
        )

        while self.running:
            if self.observer_pos:
                observer_distance = self.observer_pos.diff(self.sounndev_pos).len()

            if self.can_play:
                chunks = self.sound_chunk_queue[0:4]
                chunk = b''.join(chunks)
                # chunk = self.sound_chunk_queue[0]
                audio_segment = AudioSegment(
                    chunk,
                    frame_rate=RATE,
                    sample_width=2,
                    channels=CHANNELS
                )
                # print(observer_distance)
                if observer_distance:
                    audio_segment -= observer_distance
                stream.write(audio_segment.raw_data)
                # play(audio_segment)

                # self.sound_chunk_queue.pop(0)
                # self.sound_chunk_queue.pop(0)
                # self.sound_chunk_queue.pop(0)
                # self.sound_chunk_queue.pop(0)
                del self.sound_chunk_queue[0:4]
                # del self.sound_chunk_queue[0]
                # del self.sound_chunk_queue[0]
                # del self.sound_chunk_queue[0]

                if len(self.sound_chunk_queue) < 5:
                    self.can_play = False

        # after we've stopped
        # for chunk in self.sound_chunk_queue:
        #     stream.write(chunk)

    def run(self):
        thread_functions = [
            self.receive_loop,
            self.playback_loop,
            self.observer_loop,
        ]
        # threads = []
        for thread_function in thread_functions:
            thread = threading.Thread(target=thread_function)
            thread.start()

        # receive.start()
        # playbck.start()

if __name__ == '__main__':
    server = SoundServer()
    signal.signal(signal.SIGINT, server.stop_signal_handler)
    server.run()


import csv
import random
import string
import pickle
from faker import Factory
import yaml
import os
from datetime import datetime
import ipaddress
import pandas as pd
import sys
from scipy.stats import norm

# variables
scenario_name = None
ip_dataset_name = None
apis = None
invoke_scenario = None
user_country = {}
user_ip = {}
user_cookie = {}
users_apps = {}
scenario_pool = {}
scenario_distribution = []
existing_no_of_user_combinations = 0         # to validate the user count
total_no_of_user_combinations = 0
used_ips = []
ip_dataset = None

fake_generator = Factory.create()

# setup configurations
abs_path = os.path.abspath(os.path.dirname(__file__))

try:
    with open(abs_path + '/../../../../config/traffic-tool.yaml', 'r') as file:
        traffic_config = yaml.load(file, Loader=yaml.FullLoader)
    scenario_name = traffic_config['scenario_name']
    user_agents = traffic_config['user_agents']

    with open(abs_path+'/../../../../config/apim.yaml', 'r') as file:
        apim_config = yaml.load(file, Loader=yaml.FullLoader)
    apis = apim_config['apis']

    with open(abs_path+'/../../../../config/user-settings.yaml', 'r') as file:
        user_settings = yaml.load(file, Loader=yaml.FullLoader)
    ip_dataset_name = user_settings['resources']['ip_database']

except FileNotFoundError as e:
    print('[ERROR] {} gen_invoke_scenario.py: {}: {}'.format(str(datetime.now()), e.strerror, e.filename))
    sys.exit()

'''
    This function will write the given log output to the log.txt file
'''
def log(tag, write_string):
    with open(abs_path + '/../../../../logs/traffic-tool.log', 'a+') as file:
        file.write("[{}] ".format(tag) + str(datetime.now()) + ": " + write_string + "\n")

'''
    This function will return the invoke path for a given api and http method
'''
def getPath(api_name, method):
    global apis

    for api in apis:
        if api.get('name') == api_name:
            context = str(api.get('context'))
            version = str(api.get('version'))
            resources = api.get('resources')
            for resource in resources:
                if resource.get('method') == method:
                    return context + '/' + version + '/' + str(resource.get('path'))

'''
    This function will return an integer slightly varied to the given median
'''
def varySlightly(median):
    st_div = 1
    return abs(int(norm.rvs(loc=median, scale=st_div)))

'''
    This function will return a randomly generated ipv4 address for a given country
'''
def ipGen(country):
    global used_ips, ip_dataset

    ip_range = ip_dataset.loc[ip_dataset['country_name'] == country][['ip_from', 'ip_to']]
    if len(ip_range) > 0:
        ip_decs = ip_range.sample(n=1).values[0]

        random.seed()
        MAX_IPV4 = ipaddress.IPv4Address._ALL_ONES
        temp_ip = ipaddress.IPv4Address._string_from_ip_int(random.randint(ip_decs[0], ip_decs[1]))
        while temp_ip in used_ips:
            temp_ip = ipaddress.IPv4Address._string_from_ip_int(random.randint(ip_decs[0], ip_decs[1]))

        used_ips.append(temp_ip)
        return temp_ip

    else:
        return fake_generator.ipv4()

'''
    This function will return a randomly generated cookie
'''
def getCookie():
    lettersAndDigits = string.ascii_lowercase + string.digits
    cookie = 'JSESSIONID='
    cookie += ''.join(random.choice(lettersAndDigits) for ch in range(31))
    return cookie

'''
    This function will return a list of unique cookies
'''
def genUniqueCookieList(count:int):
    cookie_list = set()
    while len(cookie_list) != count:
        cookie_list.add(getCookie())

    return list(cookie_list)

'''
    Execute the script and generate the user scenario distribution
    Usage: python3 gen_invoke_scenario.py
    output folders: lib/traffic-tool/data/scenario/ and lib/traffic-tool/data/runtime_data/
'''

try:
    # read and load the ip database
    ip_dataset = pd.read_csv(abs_path+'/../../../../resources/libraries/{}'.format(ip_dataset_name))

    # generate a set of ips and cookies for each user
    with open(abs_path+'/../../data/scenario/{}/data/user_generation.csv'.format(scenario_name)) as file:
        userlist = file.readlines()

        cookie_list = genUniqueCookieList(len(userlist))

        for user in userlist:
            username = user.split('$$ ')[0]
            country = user.split('$$ ')[5]
            user_country.update({username: country})
            user_ip.update({username: ipGen(country)})
            user_cookie.update({username: cookie_list.pop()})

    # read user token csv file
    user_token = pd.read_csv(abs_path + '/../../data/scenario/{}/api_invoke_tokens.csv'.format(scenario_name))

except FileNotFoundError as e:
    print('[ERROR] {} gen_invoke_scenario.py: {}: {}'.format(str(datetime.now()), e.strerror, e.filename))
    log('ERROR', '{}: {}'.format(e.strerror, e.filename))
    sys.exit()
except pd.errors.EmptyDataError as e:
    print('[ERROR] {} gen_invoke_scenario.py: {}'.format(str(datetime.now()), e))
    log('ERROR', '{}'.format(str(e)))
    sys.exit()
except Exception as e:
    print('[ERROR] {} gen_invoke_scenario.py: {}'.format(str(datetime.now()), e))
    log('ERROR', '{}'.format(str(e)))
    sys.exit()

# filter out unique app names and prepare dictionary
appNames = user_token.drop_duplicates(subset=['app_name'], keep='first')[['app_name']]

for row in appNames.itertuples():
    users_apps.update({row.app_name: []})

# set ips with username, access tokens and append to relevant lists
for row in user_token.itertuples():
    username = row.username
    app_name = row.app_name
    token = row.access_token
    ip = user_ip.get(username)
    cookie = user_cookie.get(username)
    user_agent = random.choice(user_agents)
    (users_apps[app_name]).append([username, token, ip, cookie, user_agent])
    existing_no_of_user_combinations += 1

    if username not in scenario_pool:
        scenario_pool.update({username: {}})
    scenario_pool.get(username).update({app_name: []})

try:
    # generate scenario data according to the script and append to the pool
    with open(abs_path+'/../../data/scenario/{}/data/invoke_scenario.yaml'.format(scenario_name)) as file:
        invoke_scenario = yaml.load(file, Loader=yaml.FullLoader)
    scenario_data = invoke_scenario['invoke_scenario']

except FileNotFoundError as e:
    print('[ERROR] {} gen_invoke_scenario.py: {}: {}'.format(str(datetime.now()), e.strerror, e.filename))
    log('ERROR', '{}: {}'.format(e.strerror, e.filename))
    sys.exit()

for item in scenario_data:
    app_name = item.get('app_name')
    user_count = int(item.get('no_of_users'))
    time_pattern = item.get('time_pattern')
    invokes = item.get('api_calls')

    # check whether the user count is valid (not more than the created number of users)
    total_no_of_user_combinations += user_count
    if total_no_of_user_combinations > existing_no_of_user_combinations:
        # invalid no of users (cannot execute the scenario)
        log("ERROR", "Invalid number of user count declared in 'invoke_scenario.yaml'. Expected {} user combinations. Found {} or more.".format(existing_no_of_user_combinations, total_no_of_user_combinations))
        raise ArithmeticError("Invalid number of user count declared in 'invoke_scenario.yaml'. Expected {} user combinations. Found {} or more.".format(existing_no_of_user_combinations, total_no_of_user_combinations))

    users = []
    for i in range(user_count):
        users.append(users_apps.get(app_name).pop())

    for invoke in invokes:
        api_name = invoke.get('api')
        method = invoke.get('method')
        call_median = int(invoke.get('no_of_requests'))
        full_path = getPath(api_name, method)

        for user in users:  # user[username,token,ip,cookie,user_agent]
            no_of_requests = varySlightly(call_median)
            scenario_pool.get(user[0]).get(app_name).append([no_of_requests, api_name, full_path, user[1], method, user[2], user[3], user[4], time_pattern])
            scenario_distribution.append([api_name, user[1], user[2], user[3]])

# save scenario data
write_str = "access_token,api_name,ip_address,user_cookie\n"

for row in scenario_distribution:
    api_name = row[0]
    access_token = row[1]
    ip_address = row[2]
    user_cookie = row[3]
    write_str += access_token + ',' + api_name + ',' + ip_address + ',' + user_cookie + "\n"

with open(abs_path + '/../../data/scenario/{}/token_ip_cookie.csv'.format(scenario_name), 'w') as file:
    file.write(write_str)

# saving scenario pool to a pickle file
pickle.dump(scenario_pool, open(abs_path + "/../../data/runtime_data/scenario_pool.sav", "wb"))

log("INFO", "User scenario distribution generated successfully")
print('[INFO] {}: User scenario distribution generated successfully'.format(str(datetime.now())))


import cv2
import numpy as np

img = cv2.imread("Koala_small.bmp")

size_lank = 3
k_size = (size_lank*2)+1
amount = 1/k_size
result = img.copy()
answer = 0*result

#0 padding
H, W, C = img.shape
out = np.zeros((H + size_lank*2, W + size_lank*2, C), dtype = np.float)
out[size_lank:size_lank + H, size_lank:size_lank + W] = img.copy()

#kernel
k = np.eye(k_size)*amount

for c in [0, 1, 2]:
    for i in range(img.shape[1]):
        for j in range(img.shape[0]):

            im_c = out[:,:,c].copy()
            h = np.sum(np.multiply(im_c[j : j+k_size, i : i+k_size],k))
            answer[j, i, c] = h

cv2.imwrite("answer.bmp",answer)
cv2.imshow("result",answer)
cv2.waitKey(0)
cv2.destroyAllwindows()


#contains imp functions

def checkmv(charac):
    a=["|","@","x"]
    if charac in a:
        return(0)
    else:
        return(1)

def checkrv(charac1,charac2):
    if charac1=="~" and charac2=="~":
        return(-1)
    else:
        return(0)

#tells which objects to climb on
def checkj(charac1,charac2):
    a=["|","@","O","M","Q","?","C","$","P"]
    if charac1 in a or charac2 in a:
        return(-1)
    else:
        return(0)


from redis import StrictRedis
if __name__ == "__main__":
    # 创建一个StrictRedis对象,链接redis数据库
    try:
        sr = StrictRedis(host='192.168.21.100')
        # 添加一对键值
        #res = sr.set('name','guido')
        # print(res)

        # 获取name的值
        # res = sr.get('name')
        # print(res)

        # 删除name及对应的值
        #res = sr.delete('name')
        #print(res)
        #删除多个键值
        #res = sr.delete('a1','a2')
        #print(res)

        # 获取数据库中所有的键
        res = sr.keys()
        print(res)
    except Exception as e:
        print(e)


from os import access
import dropbox

class TransferData:
    def __init__(self, access_token):
        self.access_token= access_token

    def upload_files(self, file_from, file_to):
        dbx=dropbox.Dropbox(self.access_token)
        f=open(file_from, "rb")
        dbx.files_upload(f.read(), file_to)

def main():
    access_token="wslHcaboW6sAAAAAAAAAAcAMNwLbCUkjfVa8ygrgZb1XHl0V7PSH2qVLbSzxYLWw"
    transfer_data=TransferData(access_token)
    file_from=input("Enter the file path to upload: ")
    file_to=input("Enter the file path for dropbox: ")

    transfer_data.upload_files(file_from, file_to)
    print("File successfully uploaded!")

main()


"""13549 숨바꼭질 3"""
# 나중에 추가되어 문제 번호가 겹침
# 실마리: https://my-coding-notes.tistory.com/415
# 2배로 갈 수 있는 곳을 왜 한 번에 찾으려 했을까

import heapq

INF = float("inf")

def dijkstra(now):
    dp[now] = 0
    heapq.heappush(heap, (0, now))

    while heap:
        weight, curr = heapq.heappop(heap)

        if dp[curr] < weight:
            continue

        if curr * 2 <= 100000 and dp[curr * 2] > weight:
            dp[curr * 2] = weight
            heapq.heappush(heap, (weight, curr * 2))

        if curr + 1 <= 100000 and dp[curr + 1] > weight + 1:
            dp[curr + 1] = weight + 1
            heapq.heappush(heap, (weight + 1, curr + 1))

        if curr - 1 >= 0 and dp[curr - 1] > weight + 1:
            dp[curr - 1] = weight + 1
            heapq.heappush(heap, (weight + 1, curr - 1))

subin, sister = map(int, input().split())
dp = [INF] * 100001
heap = []

dijkstra(subin)
print(dp[sister])

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

# queue를 사용한 풀이
# dijkstra보다 약간 더 빠르다
# https://velog.io/@aonee/%EB%B0%B1%EC%A4%80-boj-13549-%EC%88%A8%EB%B0%94%EA%BC%AD%EC%A7%883-%ED%8C%8C%EC%9D%B4%EC%8D%AC

from collections import deque

def bfs(now):
    queue = deque()
    queue.append(now)
    check[now] = 1
    dist[now] = 0

    while queue:
        curr = queue.popleft()
        if curr * 2 <= 100000 and check[curr * 2] == 0:
            queue.appendleft(curr * 2)
            check[curr * 2] = 1
            dist[curr * 2] = dist[curr]
        if curr + 1 <= 100000 and check[curr + 1] == 0:
            queue.append(curr + 1)
            check[curr + 1] = 1
            dist[curr + 1] = dist[curr] + 1
        if curr - 1 >= 0 and check[curr - 1] == 0:
            queue.append(curr - 1)
            check[curr - 1] = 1
            dist[curr - 1] = dist[curr] + 1

check = [0] * 100001
dist = [-1] * 100001

subin, sister = map(int, input().split())
bfs(subin)
print(dist[sister])


from django.db import models
from django.urls import reverse
from datetime import date
from django.contrib.auth.models import User

PROCEDURES = (
    ('R', 'Root Canal'),
    ('C', 'Cleaning'),
    ('F', 'Filling'),
    ('E', 'Extraction'),
    ('B', 'BiteWings'),
    ('P', 'Panoramic')
)

ALLERGIES = (
    ('F', 'Fissure sealent'),
    ('T', 'Titanium'),
    ('L', 'Local Anaesthesia'),
    ('I', 'Impression materials'),
    ('L', 'Latex'),
    ('C', 'Composites'),
    ('N', 'No Allergies')
)

INSURANCE = (
    ('D', 'Delta Dental'),
    ('H', 'Humana'),
    ('U', 'United Concordia'),
    ('C', 'CareFirst'),
    ('C', 'Cigna'),
    ('M', 'MetLife')
)

class Provider(models.Model):
    name = models.CharField(max_length=50)

    def get_absolute_url(self):
        return reverse('providers_detail', kwargs={'pk': self.id})

class Patient(models.Model):
    name = models.CharField(max_length=100)
    age = models.IntegerField()
    allergies = models.CharField(
        max_length=1,
        choices=ALLERGIES,
        default=ALLERGIES[0][0])
    insurance = models.CharField(
        max_length=1,
        choices=INSURANCE,
        default=INSURANCE[0][0])
    providers = models.ManyToManyField(Provider)
    user = models.ForeignKey(User, on_delete=models.CASCADE)

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        return reverse('detail', kwargs={'patient_id': self.id})

class Procedure(models.Model):
    date = models.DateField('Procedure Date')
    type = models.CharField(
        max_length=1,
        choices=PROCEDURES,
        default=PROCEDURES[0][0]

    )
    location = models.CharField(max_length=100)
    patient = models.ForeignKey(Patient, on_delete=models.CASCADE)

    def __str__(self):
        return f"{self.get_type_display()} on {self.date}"

class Meta:
    ordering = ['-date']


#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2019/7/16 19:01
# @Author  : Wei Lu
# @File    : 51kanong-spider.py
import requests
from lxml import etree
from fake_useragent import UserAgent

import smtplib
from email.mime.text import MIMEText
from email.header import Header
import datetime
headers  = {
    'User-Agent':UserAgent().random
}

def load_data_dean():
    url = 'https://www.51kanong.com/plugin.php?id=xiaoyu_mi&t=l'
    response=requests.get(url=url,headers=headers).text
    html=etree.HTML(response)
    post_name1=html.xpath('//a[@class="t_name"]/text()')
    post_time1=html.xpath('//span[@class="time txt"]/text()')
    return post_name1,post_time1

def load_data_forum():
    post_time2=[]
    post_name2=[]
    for i in range(1,21):
        url = 'https://www.51kanong.com/forum.php?mod=forumdisplay&fid=140&orderby=lastpost&orderby=lastpost&filter=lastpost&page=' + str(i)
        response = requests.get(url=url, headers=headers).text
        html = etree.HTML(response)
        post_name2 += (html.xpath('//a[@class="deanforumtitname"]/text()'))
        post_time2 += (html.xpath('//div[@class="deanforump5"]/a/text()'))
    return post_name2,post_time2

def load_data_tech():
    url = 'https://www.51kanong.com/forum.php?mod=forumdisplay&fid=120&filter=lastpost&orderby=lastpost'
    response = requests.get(url=url, headers=headers).text
    html = etree.HTML(response)
    post_name3=html.xpath('//a[@class="deanforumtitname"]/text()')
    post_time3=html.xpath('//div[@class="deanforump5"]/a/text()')
    return post_name3,post_time3

def data_all():
    post_name=load_data_dean()[0]+load_data_forum()[0]+load_data_tech()[0]
    post_time=load_data_dean()[1]+load_data_forum()[1]+load_data_tech()[1]

def send_mail(post_name,post_time):
    mail_host = "smtp.quantum1tech.com"
    mail_user = "jiank@quantum1tech.com"
    mail_pass = "Hello1234"

    sender = 'jiank@quantum1tech.com'
    receivers = ['xiongge@quantum1tech.com']

    message = MIMEText('卡农论坛预警，论坛上有人在搜：'+ post_name + post_time, 'plain', 'utf-8')
    message['From'] = Header("卡农论坛预警！", 'utf-8')
    message['To'] = Header("卡农论坛预警！", 'utf-8')

    subject = '卡农论坛预警！'
    message['Subject'] = Header(subject, 'utf-8')

    try:
        smtpObj = smtplib.SMTP()
        smtpObj.connect(mail_host, 25)
        smtpObj.login(mail_user, mail_pass)
        smtpObj.sendmail(sender, receivers, message.as_string())
        print("邮件发送成功")
    except smtplib.SMTPException:
        print("Error: 无法发送邮件")

if __name__ == '__main__':
    check_list = ['花分期', '花猪', '51花', '小白钱包', '花无极', '微现金']
    white_list = ['趣花分期']
    post_name = load_data_dean()[0] + load_data_forum()[0] + load_data_tech()[0]
    post_time = load_data_dean()[1] + load_data_forum()[1] + load_data_tech()[1]
    for i in range(len(post_name)):
        for j in check_list:
            for k in white_list:
                if((datetime.datetime.now() - datetime.datetime.strptime(post_time[i], "%Y-%m-%d %H:%M")).seconds) <=3600 and (j in post_name[i]) and (k not in post_name[i]):
                    print(post_name[i])
                    print(post_time[i])
                    send_mail(post_name[i],post_time[i])


import turtle
import math

mars = turtle.Turtle()
earth = turtle.Turtle()
spacecraft = turtle.Turtle()

def way_to_orbit(x, y, object, colors):
    object.dot(50, "yellow")
    object.color("white")
    object.fillcolor(colors)
    object.shape("circle")
    object.penup()
    object.setposition(x, y)
    object.pendown()

def ellipse(object1, object2, object3):

    loop = True
    object2_xvel = 0
    object2_yvel = 1
    object1_xvel = 0
    object1_yvel = 1
    object3_xvel = 0
    object3_yvel = 1
    a = 0

    while loop:
        distance = 1000 / (object2.xcor()**2 + object2.ycor()**2)
        rad = math.radians(object2.towards(0, 0))
        object2_xvel += math.cos(rad) * distance
        object2_yvel += math.sin(rad) * distance
        object2.setposition(object2.xcor() + object2_xvel,
                            object2.ycor() + object2_yvel)

        distance = (1000 / (object1.xcor() ** 2 + object1.ycor() ** 2))
        rad = math.radians(object1.towards(0, 0))
        object1_xvel += math.cos(rad) * distance
        object1_yvel += math.sin(rad) * distance
        object1.setposition(object1.xcor() + object1_xvel,
                            object1.ycor() + object1_yvel)

        # move `spacecraft` with `earth`
        object3.setposition(object3.xcor() + object2_xvel,
                            object3.ycor() + object2_yvel)

        #distance = ( (object3.xcor()**2)-(object2.xcor()**2) ) + ( (object3.ycor()**2)-(object2.ycor()**2) )
        distance = 1000/3441  # constant value
        rad = math.radians(object3.towards(object2.xcor(), object2.ycor()))
        object3_xvel += math.cos(rad) * distance
        object3_yvel += math.sin(rad) * distance
        object3.setposition(object3.xcor() + object3_xvel,
                            object3.ycor() + object3_yvel)

way_to_orbit(620, 0, mars, "red")
way_to_orbit(375, 0, earth, "blue")
way_to_orbit(436, 0, spacecraft, "green")

ellipse(mars, earth, spacecraft)

turtle.done()


# Leetcode practice
# author: orange
# date: 2021/6/1

#python自带去重功能set()函数

class Solution(object):
    def containsDuplicate(self, nums):
        """
        :type nums: List[int]
        :rtype: bool
        """
        return len(set(nums)) != len(nums)

alist=[1,2,2,4,4,6,7]
b=set(alist)
print(list(b))


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""Tests for svd."""

import unittest

import numpy as np

from sknetwork.data import movie_actor
from sknetwork.linalg import LanczosSVD, SparseLR

def svd_err(matrix, u, v, sigma):
    """Approximation error for singular vectors."""
    err = matrix.dot(v) - u * sigma
    return np.linalg.norm(err)

# noinspection DuplicatedCode
class TestSolvers(unittest.TestCase):

    def setUp(self):
        """Simple biadjacency for tests."""
        self.biadjacency = movie_actor()
        n_row, n_col = self.biadjacency.shape
        self.slr = SparseLR(self.biadjacency, [(np.random.rand(n_row), np.random.rand(n_col))])

    def test_lanczos(self):
        solver = LanczosSVD()
        solver.fit(self.biadjacency, 2)
        self.assertEqual(len(solver.singular_values_), 2)
        self.assertAlmostEqual(svd_err(self.biadjacency, solver.singular_vectors_left_, solver.singular_vectors_right_,
                                       solver.singular_values_), 0)

        solver.fit(self.slr, 2)
        self.assertEqual(len(solver.singular_values_), 2)
        self.assertAlmostEqual(svd_err(self.slr, solver.singular_vectors_left_, solver.singular_vectors_right_,
                                       solver.singular_values_), 0)


from acunetix.acunetix import Acunetix

list_target = [ {"address": 'http://google.com',"description": "ndqk"}]

new_targets = Acunetix.create_targets(list_target)

if new_targets:
    new_target = new_targets[0]
    new_scan = Acunetix.create_scan_from_target(new_target)
    print(new_scan)


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

# Note: To use the 'upload' functionality of this file, you must:
#   $ pipenv install twine --dev

import codecs
import os
import re
import sys

from shutil import rmtree

from setuptools import Command, find_packages, setup

NAME = "zelos"
PACKAGES = find_packages(where="src")
META_PATH = os.path.join("src", "zelos", "__init__.py")
KEYWORDS = ["emulation", "dynamic analysis", "binary analysis"]
PROJECT_URLS = {
    "Documentation": "https://zelos.zeropointdynamics.com/",
    "Bug Tracker": "https://github.com/zeropointdynamics/zelos/issues",
    "Source Code": "https://github.com/zeropointdynamics/zelos",
}
CLASSIFIERS = [
    "Development Status :: 4 - Beta",
    "Natural Language :: English",
    "License :: OSI Approved :: GNU Affero General Public License v3",
    "Operating System :: OS Independent",
    "Programming Language :: Python",
    "Programming Language :: Python :: 3",
    "Programming Language :: Python :: 3.6",
    "Programming Language :: Python :: 3.7",
    "Programming Language :: Python :: 3.8",
]
INSTALL_REQUIRES = [
    "wheel",
    "colorama==0.4.1",
    "termcolor==1.1.0",
    "capstone==4.0.1",
    "sortedcontainers==2.1.0",
    "verboselogs==1.7",
    "dnslib>=0.9.17",
    "hexdump==3.3",
    "dpkt==1.9.2",
    "coloredlogs==10.0",
    "configargparse==0.15.1",
    "pypacker==4.9",
    "lief>=0.9.0",
    "zebracorn==0.0.1",
    "lark-parser==0.7.8",
]
EXTRAS_REQUIRE = {
    "docs": [
        "docutils==0.16",
        "sphinx==2.4.4",
        "sphinx_rtd_theme",
        "sphinxcontrib-apidoc",
        "recommonmark",
        "sphinx-argparse",
    ],
    "tests": [
        "coverage",
        "hypothesis",
        "pympler",
        "pytest-cov",
        "pytest>=4.3.0",
        "pytest-xdist",
        "filelock",
        "yara-python",
        "mock",
    ],
}
EXTRAS_REQUIRE["dev"] = (
    EXTRAS_REQUIRE["tests"] + EXTRAS_REQUIRE["docs"] + ["pre-commit", "tox"]
)
EXTRAS_REQUIRE["azure-pipelines"] = EXTRAS_REQUIRE["tests"] + [
    "pytest-azurepipelines"
]

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

HERE = os.path.abspath(os.path.dirname(__file__))

def read(*parts):
    """
    Build an absolute path from *parts* and and return the contents of
    the resulting file.  Assume UTF-8 encoding.
    """
    with codecs.open(os.path.join(HERE, *parts), "rb", "utf-8") as f:
        return f.read()

META_FILE = read(META_PATH)

def find_meta(meta):
    """
    Extract __*meta*__ from META_FILE.
    """
    meta_match = re.search(
        r"^__{meta}__ = ['\"]([^'\"]*)['\"]".format(meta=meta), META_FILE, re.M
    )
    if meta_match:
        return meta_match.group(1)
    raise RuntimeError("Unable to find __{meta}__ string.".format(meta=meta))

VERSION = find_meta("version")
URL = find_meta("url")
LONG = (
    read("README.md")
    + "\n\n"
    + read("CHANGELOG.md")
    + "\n\n"
    + read("AUTHORS.md")
)

class UploadCommand(Command):
    """Support setup.py upload."""

    description = "Build and publish the package."
    user_options = []

    @staticmethod
    def status(s):
        """Prints things in bold."""
        print("\033[1m{0}\033[0m".format(s))

    def initialize_options(self):
        pass

    def finalize_options(self):
        pass

    def run(self):
        try:
            self.status("Removing previous builds…")
            rmtree(os.path.join(HERE, "dist"))
        except OSError:
            pass

        self.status("Building Source and Wheel (universal) distribution…")
        os.system(
            "{0} setup.py sdist bdist_wheel --universal".format(sys.executable)
        )

        self.status("Uploading the package to PyPI via Twine…")
        os.system("twine upload dist/*")

        self.status("Pushing git tags…")
        os.system("git tag v{0}".format(VERSION))
        os.system("git push --tags")

        sys.exit()

if __name__ == "__main__":
    setup(
        name=NAME,
        description=find_meta("description"),
        license=find_meta("license"),
        url=URL,
        project_urls=PROJECT_URLS,
        version=VERSION,
        author=find_meta("author"),
        author_email=find_meta("email"),
        maintainer=find_meta("author"),
        maintainer_email=find_meta("email"),
        keywords=KEYWORDS,
        long_description=LONG,
        long_description_content_type="text/markdown",
        packages=PACKAGES,
        package_dir={"": "src"},
        python_requires=">=3.6.0",
        zip_safe=False,
        classifiers=CLASSIFIERS,
        install_requires=INSTALL_REQUIRES,
        extras_require=EXTRAS_REQUIRE,
        include_package_data=True,
        options={"bdist_wheel": {"universal": "1"}},
        setup_requires=["wheel"],
        cmdclass={"upload": UploadCommand},
        entry_points={"console_scripts": [f"{NAME} = {NAME}.__main__:main"]},
    )


from torch import nn
import torch.nn.functional as F

from .conv import Conv1d, Conv2d
from .linear import FC

class MLP(nn.ModuleList):
    """Multilayer perceptron

    Args:
        in_channels (int): the number of channels of input tensor
        mlp_channels (tuple): the numbers of channels of fully connected layers
        dropout (float or None): dropout ratio
        bn (bool): whether to use batch normalization

    """

    def __init__(self,
                 in_channels,
                 mlp_channels,
                 dropout=None,
                 bn=True,
                 bn_momentum=0.1):
        super(MLP, self).__init__()

        self.in_channels = in_channels
        self.dropout = dropout

        for ind, out_channels in enumerate(mlp_channels):
            self.append(FC(in_channels, out_channels,
                           relu=True, bn=bn, bn_momentum=bn_momentum))
            in_channels = out_channels

        self.out_channels = in_channels

    def forward(self, x):
        for module in self:
            x = module(x)
            if self.dropout:
                x = F.dropout(x, self.dropout, self.training, inplace=False)
        return x

class SharedMLP(nn.ModuleList):
    def __init__(self,
                 in_channels,
                 mlp_channels,
                 ndim=1,
                 bn=True,
                 bn_momentum=0.1):
        """Multilayer perceptron shared on resolution (1D or 2D)

        Args:
            in_channels (int): the number of channels of input tensor
            mlp_channels (tuple): the numbers of channels of fully connected layers
            ndim (int): the number of dimensions to share
            bn (bool): whether to use batch normalization
        """
        super(SharedMLP, self).__init__()

        self.in_channels = in_channels

        if ndim == 1:
            mlp_module = Conv1d
        elif ndim == 2:
            mlp_module = Conv2d
        else:
            raise ValueError()

        for ind, out_channels in enumerate(mlp_channels):
            self.append(mlp_module(in_channels, out_channels, 1,
                                   relu=True, bn=bn, bn_momentum=bn_momentum))
            in_channels = out_channels

        self.out_channels = in_channels

    def forward(self, x):
        for module in self:
            x = module(x)
        return x


'''InputHandler is an extension to add "Input commands" to bottery views
Usage:

On an Application:
app = App()
input = InputHandler(app)

On Patterns:
hang_user_pattern_input = HangUserPattern(input_example)
input.set_hang(hang_user_pattern_input, 'project')
patterns = [
    hang_user_pattern_input,
    Pattern('project', input_example),

On a View:

    # This block will be executed on first call
    if not app.input_queue:
        app.hang_in(message)
        app.input(message, 'name', 'Enter Project Name:')
        app.input(message, 'language', 'Enter Project Language: ',
                  ['python2', 'python3'])
        return app.print_next_input(message) # To return first message of queue

    # On next calls, this block wil be executed

    stay, response = app.next_input_queue(message)
    if stay:
        return response # Contains message from Input Command
    # Queue ended, now you could save resulting Project and exit view
    app.hang_out(message)
    return 'Project created: ' + response # Response contains user entries
'''
from collections import OrderedDict

class InputHandler:
    '''Adds Input Command to views'''
    def __init__(self, app):
        self.hang = dict()
        self.input_queue = dict()
        self.user_inputs = dict()
        self._app = app

    def set_hang(self, hang, hang_pattern):
        self.hang[hang_pattern] = hang

    def hang_in(self, message):
        '''Used in conjunction with HangUserPattern. Mantains app on the view'''
        self.hang[message.text].activate_hang(message)
        self.user_inputs[message.user.id] = dict()

    def hang_out(self, message, hang_pattern):
        self.hang[hang_pattern].deactivate_hang(message)
        self.user_inputs.pop(message.user.id, None)

    def input(self, message, name, prompt, valid_values=None):
        '''Adds a input message to the dict'''
        if not self.input_queue.get(message.user.id, None):
            self.input_queue[message.user.id] = OrderedDict()
        self.user_inputs[message.user.id] = dict()
        user_input_dict = self.input_queue[message.user.id]
        user_input_dict[name] = (prompt, valid_values)

    def print_next_input(self, message):
        user_input_dict = self.input_queue[message.user.id]
        if not user_input_dict:
            return _('No messages on the input command queue')

        actual_prompt, _valid_values = list(user_input_dict.values())[0]
        print(actual_prompt)
        return actual_prompt

    def next_input_queue(self, message):
        '''Validates user input, saves user input.
         Returns a "stay" flag to say if views mantains hang or not
         Returns actual prompt OR
          a dict of name:user_input on end of prompts'''
        user_input_dict = self.input_queue[message.user.id]
        if not user_input_dict:
            return False, _('No messages on the input command queue')

        _actual_prompt, valid_values = list(user_input_dict.values())[0]
        if valid_values:
            if message.text not in valid_values:
                # If validation fail, remain on actual item
                return True, _('Enter a Valid Value: ') + ' '.join(valid_values)

        user_inputs = self.user_inputs[message.user.id]
        name = list(user_input_dict.keys())[0]
        user_inputs[name] = message.text
        user_input_dict.popitem(last=False)
        if not user_input_dict:
            # Ended! Return what user entered
            return False, user_inputs

        next_prompt, valid_values = list(user_input_dict.values())[0]
        if valid_values:
            next_prompt = next_prompt + ' - ' + ' '.join(valid_values)
        return True, next_prompt


from tkinter import *

def say_hi():
	print('Hi')

def helloInWindow():
	from tkinter import messagebox
	messagebox.showinfo( "Hello Python", "Hello World")

tk=Tk()

frame = Frame(tk,relief=RIDGE,borderwidth=2)
frame.pack(fill=BOTH,expand=1)

label = Label(frame,text='Hi~')
label.pack(fill=X,expand=1)

button = Button(frame,text='Exit',command=tk.destroy)
button.pack(side=BOTTOM)

btn_hi = Button(frame,text='Hi',command=say_hi)
btn_hi.pack(side=BOTTOM)

btn_hello = Button(frame,text='Hello in Window',command=helloInWindow)
btn_hello.pack(side=RIGHT)

tk.mainloop()


"""
Description:
    keep all the mtpy global params constants in this module.

Author: fei.zhang@ga.gov.au

FZ Last Updated: 2017-12-04
JP (2021-01-18) updated to use Path and get relative path locations.

"""
from pathlib import Path
import tempfile

epsg_dict = {
    28350: [
        "+proj=utm +zone=50 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs",
        50,
    ],
    28351: [
        "+proj=utm +zone=51 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs",
        51,
    ],
    28352: [
        "+proj=utm +zone=52 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs",
        52,
    ],
    28353: [
        "+proj=utm +zone=53 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs",
        53,
    ],
    28354: [
        "+proj=utm +zone=54 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs",
        54,
    ],
    28355: [
        "+proj=utm +zone=55 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs",
        55,
    ],
    28356: [
        "+proj=utm +zone=56 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs",
        56,
    ],
    3112: [
        "+proj=lcc +lat_1=-18 +lat_2=-36 +lat_0=0 +lon_0=134 +x_0=0 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs",
        0,
    ],
    4326: ["+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs", 0],
}

MTPY_ROOT = Path(__file__).parent.parent
EDI_DATA_DIR = Path(MTPY_ROOT, "examples/data/edi_files")
EDI_DATA_DIR2 = Path(MTPY_ROOT, "examples/data/edi_files_2")
AUS_TOPO_FILE = Path(MTPY_ROOT, "examples/data/AussieContinent_etopo1.asc")
SAMPLE_DIR = Path(MTPY_ROOT, "examples/model_files")

SYSTEM_TEMP_DIR = tempfile.gettempdir()

NEW_TEMP_DIR = tempfile.mkdtemp(prefix="mtpy_tmpdir_")


from models import *
from sqlalchemy import create_engine, inspect
from sqlalchemy.orm import sessionmaker, configure_mappers

s = Session()
if __name__ == '__main__':
    decals = s.query(Decal).filter(Decal.rarity != 9).all()
    for paint in s.query(Paint):
        paint.decals = decals
        s.merge(paint)
    s.commit()
    s.close()


import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
import numpy as np
import datetime
import matplotlib.pyplot as plt
import torchvision.transforms as T
import car_racing as cr
import replay_memory as rm
import data_collector as dc
import random

class VAE(nn.Module):
    # In part taken from:
    # https://github.com/pytorch/examples/blob/master/vae/main.py

    def __init__(self, n_screens, n_latent_states, lr=1e-5, device='cpu'):
        super(VAE, self).__init__()

        self.device = device

        self.n_screens = n_screens
        self.n_latent_states = n_latent_states

        # The convolutional encoder
        self.encoder = nn.Sequential(
                nn.Conv2d(self.n_screens, 32, 4, 2), # (1, 8, 42, 42) --> (1, 32, 20, 20)
                nn.BatchNorm2d(32),
                nn.ReLU(inplace=True),

                nn.Conv2d(32, 64, 4, 2), # (1, 32, 20, 20) --> (1, 64, 9, 9)
                nn.BatchNorm2d(64),
                nn.ReLU(inplace=True),

                nn.Conv2d(64, 128, 5, 2), # (1, 64, 9, 9) --> (1, 128, 3, 3)
                nn.BatchNorm2d(128),
                nn.ReLU(inplace=True),

                nn.Conv2d(128, 256, 3, 2), # (1, 128, 3, 3) --> (1, 256, 1, 1)
                nn.ReLU(inplace=True),

                ).to(self.device)

        # The size of the encoder output
        self.encoder_output_shape = (256, 1, 1)
        self.encoder_output_size = np.prod(self.encoder_output_shape)

        # The convolutional decoder
        self.decoder = nn.Sequential(
                nn.ConvTranspose2d(256, 128, 3, 2), # (1, 256, 1, 1) --> (1, 128, 3, 3)
                nn.BatchNorm2d(128),
                nn.ReLU(inplace=True),

                nn.ConvTranspose2d(128, 64, 5, 2), # (1, 128, 3, 3) --> (1, 64, 9, 9)
                nn.BatchNorm2d(64),
                nn.ReLU(inplace=True),

                nn.ConvTranspose2d(64, 32, 4, 2), # (1, 64, 9, 9) --> (1, 32, 20, 20)
                nn.BatchNorm2d(32),
                nn.ReLU(inplace=True),

                nn.ConvTranspose2d(32, self.n_screens, 4, 2), # (1, 32, 20, 20) --> (1, n_screens, 42, 42)
                nn.BatchNorm2d(self.n_screens),
                nn.ReLU(inplace=True),

                nn.Sigmoid()
                ).to(self.device)

        # Fully connected layers connected to encoder
        self.fc1 = nn.Linear(self.encoder_output_size, self.encoder_output_size // 2) # 1024 --> 512
        self.fc2_mu = nn.Linear(self.encoder_output_size // 2, self.n_latent_states) # 512 --> 128
        self.fc2_logvar = nn.Linear(self.encoder_output_size // 2, self.n_latent_states) # 512 --> 128

        # Fully connected layers connected to decoder
        self.fc3 = nn.Linear(self.n_latent_states, self.encoder_output_size // 2) # 128 --> 512
        self.fc4 = nn.Linear(self.encoder_output_size // 2, self.encoder_output_size) # 512 --> 1024

        self.optimizer = optim.Adam(self.parameters(), lr)

        self.to(self.device)

    def encode(self, x):
        # Deconstruct input x into a distribution over latent states
        conv = self.encoder(x)
        h1 = F.relu(self.fc1(conv.view(conv.size(0), -1)))
        mu, logvar = self.fc2_mu(h1), self.fc2_logvar(h1)
        return mu, logvar

    def reparameterize(self, mu, logvar):
        # Apply reparameterization trick
        std = torch.exp(0.5*logvar)
        eps = torch.randn_like(std)
        return mu + eps*std

    def decode(self, z, batch_size=1):
        # Reconstruct original input x from the (reparameterized) latent states
        h3 = F.relu(self.fc3(z))
        deconv_input = self.fc4(h3)
        deconv_input = deconv_input.view([batch_size] + [dim for dim in self.encoder_output_shape])
        y = self.decoder(deconv_input)
        return y

    def forward(self, x, batch_size=1):
        # Deconstruct and then reconstruct input x
        mu, logvar = self.encode(x)
        z = self.reparameterize(mu, logvar)
        recon = self.decode(z, batch_size)
        return recon, mu, logvar

    # Reconstruction + KL divergence losses summed over all elements and batch
    def loss_function(self, recon_x, x, mu, logvar, batch=True):
        if batch:
            BCE = F.binary_cross_entropy(recon_x, x, reduction='none')
            BCE = torch.sum(BCE, dim=(1, 2, 3))

            KLD = -0.5 * torch.sum(1 + logvar - mu.pow(2) - logvar.exp(), dim=1)
        else:
            BCE = F.binary_cross_entropy(recon_x, x, reduction='sum')
            # see Appendix B from VAE paper:
            # Kingma and Welling. Auto-Encoding Variational Bayes. ICLR, 2014
            # https://arxiv.org/abs/1312.6114
            # 0.5 * sum(1 + log(sigma^2) - mu^2 - sigma^2)
            KLD = -0.5 * torch.sum(1 + logvar - mu.pow(2) - logvar.exp())

        return BCE + KLD

class Model(nn.Module):

   def __init__(self, n_inputs, n_outputs, n_hidden=64, lr=1e-3, softmax = False, device='cpu'):
        super(Model, self).__init__()

        self.n_inputs = n_inputs   # Number of inputs
        self.n_hidden = n_hidden   # Number of hidden units
        self.n_outputs = n_outputs # Number of outputs
        self.softmax = softmax

        self.fc1 = nn.Linear(self.n_inputs, self.n_hidden)  # Hidden layer
        self.fc2 = nn.Linear(self.n_hidden, self.n_outputs) # Output layer

        self.optimizer = optim.Adam(self.parameters(), lr)  # Adam optimizer

        self.device = device
        self.to(self.device)

   def forward(self, x):
        # Define the forward pass:
        x = x.to(self.device)
        h1 = F.relu(self.fc1(x))

        if self.softmax: # If true apply a softmax function to the output
            y = F.softmax(self.fc2(h1), dim=-1).clamp(min=1e-9, max=1-1e-9) # This is used to get a proper distribution over all actions with a sum of 1.
        else:
            y = self.fc2(h1)

        return y

class Agent():

    def __init__(self, device = 'cuda'):

        self.run_id = 1
        self.device = device
        self.env = cr.CarRacing()
        self.render_view = False      # Set to True if you want to see what it is doing
        self.print_timer = 10         # Print average result of Agent every '...' episodes

        self.height = self.width = 42 # observation size (height and width)
        self.color = 1                # number of colors
        self.n_screens = 8            # number of observations stacked

        self.obs_shape = (self.height, self.width)
        self.obs_size = int(np.prod(self.obs_shape))     # The size of the observation
        self.linear = False                              # True if the input is a vector

        # Initialize last observations array
        self.obs_batch = np.array([np.zeros((self.height, self.width), dtype = 'float32') for i in range(self.n_screens)])

        # Discretization of continuous action space for CarRacing-v0
        # [0] = steering, [1] = accelerating, [2] = braking
        self.discrete_actions = {0 : np.array([0,0,0]),       # do nothing
                                 1 : np.array([-1,0,0]),      # steer sharp left
                                 2 : np.array([1,0,0]),       # steer sharp right
                                 3 : np.array([-0.5,0,0]),    # steer left
                                 4 : np.array([0.5,0,0]),     # steer right
                                 5 : np.array([0,1,0]),       # accelerate 100%
                                 6 : np.array([0,0.5,0]),     # accelerate 50%
                                 7 : np.array([0,0.25,0]),    # accelerate 25%
                                 8 : np.array([0,0,1]),       # brake 100%
                                 9 : np.array([0,0,0.5]),     # brake 50%
                                 10 : np.array([0,0,0.25])}   # brake 25%

        # The number of actions available to the agent
        self.n_actions = len(self.discrete_actions)

        self.freeze_cntr = 0           # Keeps track of when to (un)freeze the target network
        self.freeze_period = 50        # How long the network is frozen
        self.batch_size = 250
        self.freeze_vae = True

        self.memory_capacity = 100000     # memory size
        self.VAE_memory_capacity = 10000  # VAE pre-train memory size
        self.n_episodes = 1000            # number of episodes
        self.n_play_episodes = 150        # number of episodes used for average reward test
        self.max_length_episode = 1000    # max number of steps a episode of the CarRacing environment lasts

        self.gamma = 12                   # Precision parameter
        self.Beta = 0.99                  # Discount factor
        self.alpha = 18000                # VAE loss scaler

        self.n_hidden_trans = 512         # number of hidden units transition network
        self.lr_trans = 1e-3              # learning rate transition network
        self.n_hidden_pol = 512           # number of hidden units policy network
        self.lr_pol = 1e-4                # learning rate policy network
        self.n_hidden_val = 512           # number of hidden units value network
        self.lr_val = 1e-5                # learning rate value network

        self.n_latent_states = 128        # size latent space
        self.lr_vae = 5e-6                # learning rate VAE
        self.vae_data = 'pre_train_data/vae_data_10000.pt'
        self.vae_plot = False
        self.pre_train_vae = True         # if True pre-trains the VAE

        self.load_pre_trained_vae = True
        self.pt_vae_load_path = "networks/pre_trained_vae/vae_daif_CarRacing_{}_end.pth".format(self.n_latent_states)

        self.load_network = True
        self.network_load_path = "networks/daif/daif_CarRacing_{}net_r{}.pth".format("{}", self.run_id)

        # Initialize the networks:
        self.vae = VAE(self.n_screens, self.n_latent_states, lr = self.lr_vae, device=self.device)
        self.transition_net = Model(self.n_latent_states*2 + 1, self.n_latent_states, self.n_hidden_trans, lr=self.lr_trans, device=self.device)  # + 1, for 1 action
        self.policy_net = Model(self.n_latent_states*2, self.n_actions, self.n_hidden_pol, lr=self.lr_pol, softmax=True, device=self.device)
        self.value_net = Model(self.n_latent_states*2, self.n_actions, self.n_hidden_val, lr=self.lr_val, device=self.device)
        self.target_net = Model(self.n_latent_states*2, self.n_actions, self.n_hidden_val, lr=self.lr_val, device=self.device)
        self.target_net.load_state_dict(self.value_net.state_dict())

        if self.load_pre_trained_vae: # If true: load a pre-trained VAE
            self.vae.load_state_dict(torch.load(self.pt_vae_load_path, map_location=self.device))
            self.vae.eval()
            print("Succesfully loaded a pre-trained VAE")

        if self.load_network: # If true: load the networks given paths
            self.vae.load_state_dict(torch.load(self.network_load_path.format("vae"), map_location=self.device))
            self.vae.eval()
            self.transition_net.load_state_dict(torch.load(self.network_load_path.format("trans"), map_location=self.device))
            self.transition_net.eval()
            self.policy_net.load_state_dict(torch.load(self.network_load_path.format("pol"), map_location=self.device))
            self.policy_net.eval()
            self.value_net.load_state_dict(torch.load(self.network_load_path.format("val"), map_location=self.device))
            self.value_net.eval()
            print("Succesfully loaded networks")

        # Initialize the replay memory
        self.memory = rm.ReplayMemory(self.memory_capacity, self.obs_shape, self.obs_size, self.linear, device=self.device)
        if self.pre_train_vae:
            self.VAE_memory = rm.ReplayMemory(self.VAE_memory_capacity, self.obs_shape, self.obs_size, self.linear, device=self.device)

        # When sampling from memory at index i, obs_indices indicates that we want observations with indices i-obs_indices, works the same for the others
        self.obs_indices = [(self.n_screens+1)-i for i in range(self.n_screens+2)]
        self.action_indices = [2, 1]
        self.reward_indices = [1]
        self.done_indices = [0]
        self.max_n_indices = max(max(self.obs_indices, self.action_indices, self.reward_indices, self.done_indices)) + 1

        # Used to pre-process the observations (screens)
        self.preprocess = T.Compose([T.ToPILImage(),
                    T.Grayscale(num_output_channels=1),
                    T.Resize((self.height, self.width)),
                    T.ToTensor()])

        self.save_results = True
        self.save_network = True
        self.results_path = "results/daif/daif_CarRacing_results_r{}.npz".format(self.run_id)
        self.network_save_path = "networks/daif/daif_CarRacing_{}net_r{}.pth".format("{}",self.run_id)

        self.log_path = "logs/daif_CarRacing_log_r{}.txt".format(self.run_id)
        self.record = open(self.log_path, "a")
        self.record.write("\n\n-----------------------------------------------------------------\n")
        self.record.write("File opened at {}\n".format(datetime.datetime.now()))

    def get_screen(self, device='cuda'):
        # Get observation, reshape and but in right order.
        screen = self.env.render(mode='state_pixels')
        screen = screen.reshape(96, 96, 3)
        screen = screen.transpose((2, 1, 0))

        # stips of bottom part of the image which contains a black bar with the accumulated reward and control value bars, and makes sure the width is equal size as height
        screen = screen[:, 6:90, int(96*0):int(96 * 0.875)]

        # Convert to to float and normalize
        screen = np.ascontiguousarray(screen, dtype=np.float32) / 255

        # Add resize
        screen = self.preprocess(torch.from_numpy(np.flip(screen, axis=0).copy()))

        return screen

    """ stack the X latest observations into one batch """
    def get_obs_batch(self, obs):
        # add new observation to obs_batch, remove oldest.
        self.obs_batch = np.concatenate((obs.numpy(), self.obs_batch[0:self.n_screens-1]), axis = 0)

        # resize to (1, self.n_screens, 84, 84) and convert to torch
        obs_batch2 = torch.from_numpy(np.flip(self.obs_batch, axis=0).copy()).unsqueeze(0).to(self.device)

        return obs_batch2

    def select_action(self, obs):
        with torch.no_grad():
            action_index = 0

            if self.memory.push_count < self.batch_size + self.n_screens:
                action_index = random.randint(0, self.n_actions - 1)
            else:
                # Derive a distribution over states state from the last n observations (screens):
                prev_n_obs = self.get_obs_batch(obs)
                state_mu, state_logvar = self.vae.encode(prev_n_obs)
                x = torch.cat((state_mu, torch.exp(state_logvar)), dim=1) # does not work?
                policy = self.policy_net(x)
                action_index = torch.multinomial(policy, 1).item()

            return action_index

    def get_mini_batches(self):
        # Retrieve transition data in mini batches
        all_obs_batch, all_actions_batch, reward_batch_t1, done_batch_t2 = self.memory.sample(
                self.obs_indices, self.action_indices, self.reward_indices,
                self.done_indices, self.max_n_indices, self.batch_size)

        # Retrieve a batch of observations for 3 consecutive points in time
        obs_batch_t0 = all_obs_batch[:, 0:self.n_screens, :, :]
        obs_batch_t1 = all_obs_batch[:, 1:self.n_screens+1, :, :]
        obs_batch_t2 = all_obs_batch[:, 2:self.n_screens+2, :, :]

        # Retrieve a batch of distributions over states for 3 consecutive points in time
        state_mu_batch_t0, state_logvar_batch_t0 = self.vae.encode(obs_batch_t0)
        state_mu_batch_t1, state_logvar_batch_t1 = self.vae.encode(obs_batch_t1)
        state_mu_batch_t2, state_logvar_batch_t2 = self.vae.encode(obs_batch_t2)

        # Combine the sufficient statistics (mean and variance) into a single vector
        state_batch_t0 = torch.cat((state_mu_batch_t0, torch.exp(state_logvar_batch_t0)), dim=1)
        state_batch_t1 = torch.cat((state_mu_batch_t1, torch.exp(state_logvar_batch_t1)), dim=1)
        state_batch_t2 = torch.cat((state_mu_batch_t2, torch.exp(state_logvar_batch_t2)), dim=1)

        # Reparameterize the distribution over states for time t1
        z_batch_t1 = self.vae.reparameterize(state_mu_batch_t1, state_logvar_batch_t1)

        # Retrieve the agent's action history for time t0 and time t1
        action_batch_t0 = all_actions_batch[:, 0].unsqueeze(1)
        action_batch_t1 = all_actions_batch[:, 1].unsqueeze(1)

        # At time t0 predict the state at time t1:
        X = torch.cat((state_batch_t0.detach(), action_batch_t0.float()), dim=1)
        pred_batch_t0t1 = self.transition_net(X)

        # Determine the prediction error wrt time t0-t1:
        pred_error_batch_t0t1 = torch.mean(F.mse_loss(
                pred_batch_t0t1, state_mu_batch_t1, reduction='none'), dim=1).unsqueeze(1)

        return (state_batch_t1, state_batch_t2, action_batch_t1,
                reward_batch_t1, done_batch_t2, pred_error_batch_t0t1,
                obs_batch_t1, state_mu_batch_t1,
                state_logvar_batch_t1, z_batch_t1)

    def compute_value_net_loss(self, state_batch_t1, state_batch_t2,
                           action_batch_t1, reward_batch_t1,
                           done_batch_t2, pred_error_batch_t0t1):

        with torch.no_grad():
            # Determine the action distribution for time t2:
            policy_batch_t2 = self.policy_net(state_batch_t2)

            # Determine the target EFEs for time t2:
            target_EFEs_batch_t2 = self.target_net(state_batch_t2)

            # Weigh the target EFEs according to the action distribution:
            weighted_targets = ((1-done_batch_t2) * policy_batch_t2 *
                                target_EFEs_batch_t2).sum(-1).unsqueeze(1)

            # Determine the batch of bootstrapped estimates of the EFEs:
            EFE_estimate_batch = -reward_batch_t1 + pred_error_batch_t0t1 + self.Beta * weighted_targets

        # Determine the EFE at time t1 according to the value network:
        EFE_batch_t1 = self.value_net(state_batch_t1).gather(1, action_batch_t1)

        # Determine the MSE loss between the EFE estimates and the value network output:
        value_net_loss = F.mse_loss(EFE_estimate_batch, EFE_batch_t1)

        return value_net_loss

    def compute_VFE(self, vae_loss, state_batch_t1, pred_error_batch_t0t1):
        # Determine the action distribution for time t1:
        policy_batch_t1 = self.policy_net(state_batch_t1)

        # Determine the EFEs for time t1:
        EFEs_batch_t1 = self.value_net(state_batch_t1)

        # Take a gamma-weighted Boltzmann distribution over the EFEs:
        boltzmann_EFEs_batch_t1 = torch.softmax(-self.gamma * EFEs_batch_t1, dim=1).clamp(min=1e-9, max=1-1e-9)

        # Weigh them according to the action distribution:
        energy_term_batch = -(policy_batch_t1 * torch.log(boltzmann_EFEs_batch_t1)).sum(-1).unsqueeze(1)

        # Determine the entropy of the action distribution
        entropy_batch = -(policy_batch_t1 * torch.log(policy_batch_t1)).sum(-1).unsqueeze(1)

        # Determine the VFE, then take the mean over all batch samples:
        VFE_batch = vae_loss + pred_error_batch_t0t1 + (energy_term_batch - entropy_batch)
        VFE = torch.mean(VFE_batch)

        return VFE

    def learn(self, ith_episode):

        # If there are not enough transitions stored in memory, return
        if self.memory.push_count - self.max_n_indices*2 < self.batch_size:
            return

        # After every freeze_period time steps, update the target network
        if self.freeze_cntr % self.freeze_period == 0:
            self.target_net.load_state_dict(self.value_net.state_dict())
        self.freeze_cntr += 1

        # Retrieve mini-batches of data from memory
        (state_batch_t1, state_batch_t2, action_batch_t1,
        reward_batch_t1, done_batch_t2, pred_error_batch_t0t1,
        obs_batch_t1, state_mu_batch_t1,
        state_logvar_batch_t1, z_batch_t1) = self.get_mini_batches()

        # Determine the reconstruction loss for time t1
        recon_batch = self.vae.decode(z_batch_t1, self.batch_size)

        # Determine the VAE loss for time t1
        vae_loss = self.vae.loss_function(recon_batch, obs_batch_t1, state_mu_batch_t1, state_logvar_batch_t1, batch=True) / self.alpha

        # Compute the value network loss:
        value_net_loss = self.compute_value_net_loss(state_batch_t1, state_batch_t2,
                           action_batch_t1, reward_batch_t1,
                           done_batch_t2, pred_error_batch_t0t1)

        # Compute the variational free energy:
        VFE = self.compute_VFE(vae_loss, state_batch_t1.detach(), pred_error_batch_t0t1)

        # Reset the gradients:
        if not self.freeze_vae:
            self.vae.optimizer.zero_grad()
        self.policy_net.optimizer.zero_grad()
        self.transition_net.optimizer.zero_grad()
        self.value_net.optimizer.zero_grad()

        # Compute the gradients:
        VFE.backward(retain_graph=True)
        value_net_loss.backward()

        # Perform gradient descent:
        if not self.freeze_vae:
            self.vae.optimizer.step()
        self.policy_net.optimizer.step()
        self.transition_net.optimizer.step()
        self.value_net.optimizer.step()

    ''' Run a trained model without it learning. '''
    def play(self):

        rewards = []

        self.memory.push_count = self.memory_capacity - 1

        for ith_episode in range(self.n_play_episodes):

            total_reward = 0
            nr_steps = 0
            obs = self.env.reset()
            obs = self.get_screen(self.device)
            done = False

            while not done and nr_steps <= self.max_length_episode:

                # get action
                action = self.select_action(obs)

                # get actual action from discrete actions dictionary
                action_todo = self.discrete_actions.get(int(action))

                # take step
                obs, reward, done, _ = self.env.step([action_todo[0], action_todo[1], action_todo[2]])
                nr_steps = nr_steps + 1
                obs = self.get_screen(self.device)

                # render in visible window if True
                if self.render_view:
                    self.env.render('human')

                # add reward to total
                total_reward += reward

            rewards.append(total_reward)
            print("Reward for this episode:", total_reward)
            total_reward = 0

        self.env.close()

        np.savez("rewards/daif_CarRacing_rewards", np.array(rewards))

    def train_vae(self):
        """ Train the VAE using data collected via user play. """
        vae_batch_size = 256
        vae_obs_indices = [self.n_screens-i for i in range(self.n_screens)]

        self.VAE_memory.push_count = vae_batch_size + self.n_screens*2

        try:
            # Load the pre-collected data into device
            self.VAE_memory.obs_mem = torch.load(self.vae_data, map_location = torch.device(self.device))
        except:
            # Generate data to train VAE on
            print("No data found to train the vae on.")
            data_collector = dc.DataCollector(self.VAE_memory_capacity, self.n_screens, self.height, self.width, device = self.device)
            data_collector.generate_data()
            self.VAE_memory.obs_mem = torch.load(data_collector.obs_data_path, map_location = torch.device(self.device))

        losses = []

        for data_point in range(0, len(self.VAE_memory.obs_mem)):
            self.VAE_memory.push_count = self.VAE_memory.push_count + 1

            obs_batch, _, _, _ = self.VAE_memory.sample(vae_obs_indices, [], [], [], len(vae_obs_indices), vae_batch_size)
            obs_batch = obs_batch.view(vae_batch_size, self.n_screens, self.height, self.width)

            recon, mu, logvar = self.vae.forward(obs_batch, vae_batch_size)
            loss = torch.mean(self.vae.loss_function(recon, obs_batch, mu, logvar))

            self.vae.optimizer.zero_grad()
            loss.backward()
            self.vae.optimizer.step()

            losses.append(loss)
            if data_point % 50 == 0:
                print("obs: %2f vae loss=%5.2f"%(data_point, loss.item()))

            if data_point % 1000 == 0 and data_point > 0 and self.vae_plot:
                plt.plot(losses)
                plt.show()
                plt.plot(losses[-1000:])
                plt.show()

                for i in range(self.n_screens):
                    plt.imsave("vae_images/obs/vae_obs_CarRacing_ep_{}_{}.png".format(data_point, i), obs_batch[0, i, :, :].detach().cpu().squeeze(0).permute(1, 0).numpy(), cmap='gray')
                    plt.imsave("vae_images/recon/vae_recon_CarRacin_ep_{}_{}.png".format(data_point, i), recon[0, i, :, :].detach().cpu().squeeze(0).permute(1, 0).numpy(), cmap='gray')

        self.VAE_memory.push_count = 0
        torch.save(self.vae.state_dict(), "networks/pre_trained_vae/vae_daif_CarRacing_{}_test_end.pth".format(self.n_latent_states))

    def train(self):

        if self.pre_train_vae and not self.load_pre_trained_vae: # If True: pre-train the VAE
            msg = "Environment is: {}\nPre-training vae. Starting at {}".format("CarRacing-v0", datetime.datetime.now())
            print(msg)
            self.record.write(msg+"\n")
            self.train_vae()

        msg = "Environment is: {}\nTraining started at {}".format("CarRacing-v0", datetime.datetime.now())
        print(msg)
        self.record.write(msg+"\n")

        results = []
        for ith_episode in range(self.n_episodes):

            total_reward = 0
            self.env.reset()
            obs = self.get_screen(self.device)
            done = False
            reward = 0
            nr_steps = 0

            self.prev_screen = self.env.render('rgb_array')

            while not done and nr_steps <= self.max_length_episode:

                # get action
                action = self.select_action(obs)

                # push to memory
                self.memory.push(obs, action, reward, done)

                # get actual action input
                action_real = self.discrete_actions.get(int(action))

                # take step
                obs, reward, done, _ = self.env.step([action_real[0], action_real[1], action_real[2]])
                obs = self.get_screen(self.device)
                nr_steps = nr_steps + 1

                # render in visible window if True
                if self.render_view:
                    self.env.render('human')

                # add reward to total
                total_reward += reward

                # have the networks learn
                self.learn(ith_episode)

                if done or nr_steps == self.max_length_episode:
                    self.memory.push(obs, -99, -99, True)

            results.append(total_reward)

            # Print and keep a (.txt) record of stuff
            if ith_episode > 0 and ith_episode % self.print_timer == 0:
                avg_reward = np.mean(results)
                last_x = np.mean(results[-self.print_timer:])
                msg = "Episodes: {:4d}, avg score: {:3.2f}, over last {:d}: {:3.2f}".format(ith_episode, avg_reward, self.print_timer, last_x)
                print(msg)

                # write to log
                self.record.write(msg+"\n")

                # save log
                self.record.close()
                self.record = open(self.log_path, "a")

        self.env.close()

        # If enabled, save the results and the network (state_dict)
        if self.save_results:
            np.savez(self.results_path, np.array(results))
        if self.save_network:
            torch.save(self.transition_net.state_dict(), self.network_save_path.format("trans"))
            torch.save(self.policy_net.state_dict(), self.network_save_path.format("pol"))
            torch.save(self.value_net.state_dict(), self.network_save_path.format("val"))
            torch.save(self.VAE.state_dict(), self.network_save_path.format("VAE"))

        # Print and keep a (.txt) record of stuff
        msg = "Training finished at {}".format(datetime.datetime.now())
        print(msg)
        self.record.write(msg)
        self.record.close()

if __name__ == "__main__":
    agent = Agent()
    agent.train()


# -*- encoding:utf-8 -*-
# __author__=='Gan'

# N couples sit in 2N seats arranged in a row and want to hold hands.
# We want to know the minimum number of swaps so that every couple is sitting side by side.
# A swap consists of choosing any two people, then they stand up and switch seats.
# The people and seats are represented by an integer from 0 to 2N-1,
# the couples are numbered in order, the first couple being (0, 1),
# the second couple being (2, 3), and so on with the last couple being (2N-2, 2N-1).
# The couples' initial seating is given by row[i] being the value of the person
# who is initially sitting in the i-th seat.
# Example 1:
# Input: row = [0, 2, 1, 3]
# Output: 1
# Explanation: We only need to swap the second (row[1]) and third (row[2]) person.
# Example 2:
# Input: row = [3, 2, 0, 1]
# Output: 0
# Explanation: All couples are already seated side by side.
# Note:
# len(row) is even and in the range of [4, 60].
# row is guaranteed to be a permutation of 0...len(row)-1.

# Leetcode Weekly Contest 67.
# 56 / 56 test cases passed.
# Status: Accepted
# Runtime: 36 ms
# Scan from left to right, if non-couple sitting in 2 seat block, swap row[i-1] with the spouse one which in row[i:].
class Solution(object):
    def minSwapsCouples(self, row):
        """
        :type row: List[int]
        :rtype: int
        """
        row = [c // 2 for c in row]
        count = 0
        for i in range(0, len(row) - 1, 2):
            if row[i] != row[i + 1]:
                p = row.index(row[i], i + 1)
                row[p] = row[i + 1]
                row[i + 1] = row[i]
                count += 1
        return count

# 56 / 56 test cases passed.
# Status: Accepted
# Runtime: 38 ms
class Solution(object):
    def minSwapsCouples(self, row):
        """
        :type row: List[int]
        :rtype: int
        """
        hash_row = {x: i for i, x in enumerate(row)}
        count = 0
        for i in range(0, len(row) - 1, 2):
            if row[i] % 2 == 0:
                spouse_one = row[i] + 1
            else:
                spouse_one = row[i] - 1
            j = hash_row[spouse_one]

            if abs(i - j) > 1:
                row[i + 1], row[j] = row[j], row[i + 1]
                hash_row[row[i + 1]] = i + 1
                hash_row[row[j]] = j
                count += 1
        return count

if __name__ == '__main__':
    print(Solution().minSwapsCouples([0, 2, 1, 3]))


import tkinter as tk
from tkinter import ttk

root = tk.Tk()
root.config(width=350, height=250)
root.title("Aplica el ingreso")
frame = tk.Frame(root)
frame.place(x=0, y=0, width=350, height=250)
button = tk.Button(frame, text="click me")
button.place(x=50, y=50)
textbox = tk.Entry(frame)
textbox.insert(0,"ingrese su nombre" )
textbox.place(x=50, y=100)
checkbox = ttk.Checkbutton(frame, text="activar ia")
checkbox.place(x=50, y=150)
root.mainloop()