# ---
# jupyter:
#   jupytext:
#     cell_metadata_json: true
#     formats: ipynb,py:light
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.4.2
#   kernelspec:
#     display_name: Python [conda env:anaconda-spark30_prev2]
#     language: python
#     name: conda-env-anaconda-spark30_prev2-py
# ---

# +
import pyspark
from pyspark.sql import SparkSession
import pyspark.sql.functions as f
import pyspark.sql.types as t

import glow
import os
# -

import json

# +
MEM = os.popen("ulimit -m").read()
if MEM.startswith("unlimited"):
    print("Memory not constrained, using all available memory...")
    import psutil
    MEM = psutil.virtual_memory().available / 1024
MEM = int(MEM)

N_CPU = int(os.popen("nproc").read())

print("memory: %dk" % MEM)
print("number of cores: %d" % N_CPU)
# -

MEM = int(MEM * 0.8)

#os.environ['PYSPARK_SUBMIT_ARGS'] = '--packages io.projectglow:glow_2.12:0.3.1-SNAPSHOT,io.delta:delta-core_2.11:0.5.0 --driver-memory %dk pyspark-shell' % MEM
os.environ['PYSPARK_SUBMIT_ARGS'] = " ".join([
#     '--packages ' + ",".join([
#         "io.projectglow:glow_2.12:0.3.1-SNAPSHOT",
#         "io.delta:delta-core_2.12:0.5.1-SNAPSHOT",
#     ]),
    '--driver-memory %dk' % MEM,
    '--jars ' + ",".join([
        "/data/nasif12/home_if12/hoelzlwi/Projects/glow/core/target/scala-2.12/glow-assembly-0.3.1-SNAPSHOT.jar",
        "/data/nasif12/home_if12/hoelzlwi/Projects/deltalake/target/scala-2.12/delta-core-assembly-0.5.1-SNAPSHOT.jar",
    ]),
    'pyspark-shell'
])
os.environ['PYSPARK_SUBMIT_ARGS']

MAX_FAILURES=4

spark = (
    SparkSession.builder
    .appName('abc')
    #.config("spark.local.dir", os.environ.get("TMP"))
    .config("spark.local.dir", "/data/cephrbgssd/scratch/hoelzlwi")
    .config("spark.master", f"local[{N_CPU},{MAX_FAILURES}]")
    .config("spark.sql.shuffle.partitions", "2001")
    .config("spark.sql.execution.arrow.enabled", "true")
    #.config("spark.network.timeout", "1800s")
    #.config("spark.executor.heartbeatInterval", "600s")
    .config("spark.driver.maxResultSize", "48G")
#     .config("spark.databricks.io.cache.enabled", "true") # only enable when local storage is actually on local SSD
    .config("spark.task.maxFailures", MAX_FAILURES)
    .getOrCreate()
)
glow.register(spark)
spark

spark.sparkContext.getConf().get("spark.local.dir")

spark.sparkContext.getConf().get("spark.task.maxFailures")

## define custom display Head to simplify looking at spark DataFrames.
def displayHead(df, nrows = 5):
    return df.limit(nrows).toPandas()

# GTEX_PATH = '/s/project/variantDatabase/deltaLake/gtex_normalized'
GTEX_PATH = '/s/project/variantDatabase/gtex/v8/hg38/normalized.delta/'
GTEX_VEP_PATH = '/s/project/variantDatabase/gtex/v8/hg38/vep.delta/'

def zip_explode_cols(df: pyspark.sql.dataframe.DataFrame, cols: list, target_struct, target_colnames=None):
    if target_colnames is None:
        target_colnames = cols

    df = df.withColumn(target_struct, f.explode(f.arrays_zip(*cols)))
    df = df.withColumn(target_struct, f.struct(*[
        f.col(target_struct + "." + actualName).alias(targetName)
        for targetName, actualName in zip(target_colnames, df.schema[target_struct].dataType.fieldNames())
    ]))

    return df

gtex_df = (
    spark
    .read
    .format('parquet')
    .load(GTEX_PATH)
    .withColumn("num_alt_alleles", f.expr("genotype_states(genotypes)"))
    .drop("names")
)

gtex_df.printSchema()

# + {"active": ""}
# # TODO: remove
# gtex_df = (
#     gtex_df
#     .withColumn("call_summary_stats", f.expr("call_summary_stats(genotypes)"))
#     .withColumn("dp_summary_stats", f.expr("dp_summary_stats(genotypes)"))
#     .withColumn("gq_summary_stats", f.expr("gq_summary_stats(genotypes)"))
#     .drop("names")
# )

# +
# filter out low-quality variants
gtex_df = gtex_df.filter(f.array_contains(f.col("filters"), "PASS") & (f.col("qual") >= 99))

# convert one-sized arrays to scalars
gtex_df = (
    gtex_df
    .withColumnRenamed("alternateAlleles", "alternateAllele").withColumn("alternateAllele", f.expr("alternateAllele[0]"))
    .withColumn("INFO_AC", f.expr("INFO_AC[0]"))
    .withColumn("INFO_AF", f.expr("INFO_AF[0]"))
    .withColumn("INFO_MLEAC", f.expr("INFO_MLEAC[0]"))
    .withColumn("INFO_MLEAF", f.expr("INFO_MLEAF[0]"))
)

# count unique elements
gtex_df = (
    gtex_df
    .withColumn(
        "zygocity",
        f.struct(
            f.expr('size(num_alt_alleles)').alias("n_samples"),
            f.expr('size(filter(num_alt_alleles, x -> x == 2))').alias("n_homo"),
            f.expr('size(filter(num_alt_alleles, x -> x == 1))').alias("n_hetero"),
            f.expr('size(filter(num_alt_alleles, x -> x == 0))').alias("n_ref"),
            f.expr('size(filter(num_alt_alleles, x -> x == -1))').alias("n_not_measured"),
            f.expr('array_distinct(filter(num_alt_alleles, x -> not x in (-1, 0, 1, 2)))').alias("other")
        )
    )
#     .withColumn("n_homozygous", f.expr('size(filter(num_alt_alleles, x -> x == 2))'))
#     .withColumn("n_heterozygous", f.expr('size(filter(num_alt_alleles, x -> x == 1))'))
#     .withColumn("n_ref", f.expr('size(filter(num_alt_alleles, x -> x == 0))'))
#     .withColumn("n_not_measured", f.expr('size(filter(num_alt_alleles, x -> x == -1))'))
#     .withColumn("n_not_measured", f.expr('size(filter(num_alt_alleles, x -> x == -1))'))
)
# -

gtex_df.printSchema()

x = displayHead(gtex_df)
x.T

alleleCounts = gtex_df.select("INFO_AC", f.expr("zygocity.*")).drop("other").toPandas()

alleleCounts

import plotnine as pn

pn.ggplot(alleleCounts, pn.aes(x="INFO_AC")) + pn.stat_ecdf() + pn.scale_x_log10() + pn.ylab("ECDF") + pn.ggtitle("ECDF of allele counts")

(
    pn.ggplot(alleleCounts, pn.aes(x="n_homo"))
    + pn.stat_ecdf()
    + pn.scale_x_log10()
    + pn.xlab("Nr. of homozygous samples per variant")
    + pn.ylab("ECDF")
    + pn.ggtitle("ECDF of homozygous allele counts")
)

(
    pn.ggplot(alleleCounts, pn.aes(x="n_hetero"))
    + pn.stat_ecdf()
    + pn.scale_x_log10()
    + pn.xlab("Nr. of heterozygous samples per variant")
    + pn.ylab("ECDF")
    + pn.ggtitle("ECDF of heterozygous allele counts")
)

gtex_singlegt = (
    zip_explode_cols(
        gtex_df,
        cols=[
            "genotypes",
            "num_alt_alleles",
        ],
        target_colnames=[
            "gt",
            "num_alt_alleles",
        ],
        target_struct="genotype"
    )
    .drop(
        "genotypes",
        "num_alt_alleles",
    )
)
gtex_singlegt.printSchema()

# +
# # filter for variants that have either an exclusive heterozygous or an exclusive homozygous sample
# gtex_singlegt = gtex_singlegt.filter(
#     f"(genotype.num_alt_alleles == 1 AND zygocity.n_hetero == 1)"
# + f" OR {"incorrectly_encoded_metadata": "(genotype.num_alt_alleles == 2 AND zygocity.n_homo == 1)\""}
# )
# -

vep_df = (
    spark
    .read
    .format('parquet')
    .load(GTEX_VEP_PATH)
)

vep_df.printSchema()

displayHead(vep_df)

# +
IMPACT_LEVELS = ["HIGH", "MODERATE", "LOW", "MODIFIER"]
LOF_LEVELS = ["HC", "LC"]

csq_terms = {}
for csq_type in ['intergenic_consequences','motif_feature_consequences', 'regulatory_feature_consequences', 'transcript_consequences']:
    unique_consequences = (
        vep_df
        .selectExpr(csq_type + ".consequence_terms as " + csq_type)
        .withColumn(csq_type, f.explode(csq_type))
        .withColumn(csq_type, f.explode(csq_type))
        .drop_duplicates()
    )
    # unique_consequences.printSchema()

    unique_consequences = unique_consequences.toPandas()
    csq_terms[csq_type] = unique_consequences

# -

csq_terms

exploded_df = (
    vep_df
    .withColumn("transcript_consequence", f.expr("explode(transcript_consequences)")).drop("transcript_consequences")
    .drop(
        "colocated_variants",
        "intergenic_consequences",
        'most_severe_consequence',
        'motif_feature_consequences',
        'regulatory_feature_consequences',
    )
)

exploded_df.printSchema()

transcript_consequences = exploded_df.select(
    "*",
    f.struct(*[
        f.array_contains("transcript_consequence.consequence_terms", name).cast("byte").alias(name)
        for name in csq_terms["transcript_consequences"].iloc[:,0].values
    ]).alias("consequences"),
    f.struct(*[
        (f.col("transcript_consequence.impact") == name).alias(name)
        for name in IMPACT_LEVELS
    ]).alias("impact_level"),
    f.struct(*[
        (f.col("transcript_consequence.lof") == name).alias(name)
        for name in LOF_LEVELS
    ]).alias("lof_level"),
)
transcript_consequences.printSchema()

# + {"active": ""}
# # unused
#
# def array_to_onehot_columns(df, input_col, output_col):
#     from pyspark.ml.feature import CountVectorizer
#
#     vectorizer = CountVectorizer(inputCol=input_col, outputCol=output_col, binary=True).fit(df)
#     transformed_df = vectorizer.transform(df)
#     vocabulary = vectorizer.vocabulary
#
#     udf_to_array = f.udf(lambda v: v.toArray().tolist(), 'array<double>')
#
#     transformed_df = (
#         transformed_df
#         .withColumn(output_col, udf_to_array(output_col)) \
#         .withColumn(output_col, f.struct(*[
#             f.col(output_col)[i].astype('boolean').alias(vocabulary[i]) for i in range(len(vocabulary))
#         ]))
#     )
#
#     return transformed_df
# -

gtex_with_consequences = gtex_singlegt.withColumn("start", f.expr("start + 1")).join(
    transcript_consequences.withColumnRenamed("seq_region_name", "contigName"),
    ["contigName", "start", "end"],
    how="inner"
)

gtex_with_consequences.printSchema()

grouped_df = gtex_with_consequences.groupby(
    "contigName",
    "genotype.gt.sampleId",
    "genotype.num_alt_alleles",
    "transcript_consequence.gene_id"
)

# +
counts = grouped_df.agg(
    f.struct(*[
        # sum booleans as (0, 1) integer types
        f.sum(
            f.col("consequences." + c).cast("int")
        ).alias(c)
        for c in transcript_consequences.schema["consequences"].dataType.fieldNames()
    ]).alias("consequences"),
    f.struct(*[
        # sum booleans as (0, 1) integer types
        f.sum(
            f.col("impact_level." + c).cast("int")
        ).alias(c)
        for c in transcript_consequences.schema["impact_level"].dataType.fieldNames()
    ]).alias("impact_level"),
    f.struct(*[
        # sum booleans as (0, 1) integer types
        f.sum(
            f.col("lof_level." + c).cast("int")
        ).alias(c)
        for c in transcript_consequences.schema["lof_level"].dataType.fieldNames()
    ]).alias("lof_level"),
    f.struct(*[
        f.min(f.col("transcript_consequence.sift_score")).alias("sift_min"),
        f.mean(f.col("transcript_consequence.sift_score")).alias("sift_mean"),
        f.max(f.col("transcript_consequence.sift_score")).alias("sift_max"),
        f.min(f.col("transcript_consequence.polyphen_score")).alias("polyphen_min"),
        f.mean(f.col("transcript_consequence.polyphen_score")).alias("polyphen_mean"),
        f.max(f.col("transcript_consequence.polyphen_score")).alias("polyphen_max"),
        f.min(f.col("transcript_consequence.cadd_raw")).alias("cadd_min"),
        f.mean(f.col("transcript_consequence.cadd_raw")).alias("cadd_mean"),
        f.max(f.col("transcript_consequence.cadd_raw")).alias("cadd_max"),
    ]).alias("scores"),

)
# -

counts.printSchema()

counts = counts.groupby("contigName", "gene_id", "sampleId").pivot("num_alt_alleles", [1, 2]).agg(
    f.struct([
        f.struct(*[
            f.sum(f.col("consequences." + c)).alias(c)
            for c in counts.schema["consequences"].dataType.fieldNames()
        ]).alias("consequences"),
        f.struct(*[
            f.sum(f.col("impact_level." + c)).alias(c)
            for c in counts.schema["impact_level"].dataType.fieldNames()
        ]).alias("impact_level"),
        f.struct(*[
            f.sum(f.col("lof_level." + c)).alias(c)
            for c in counts.schema["lof_level"].dataType.fieldNames()
        ]).alias("lof_level"),
        f.struct(*[
            f.sum(f.col("scores." + c)).alias(c)
            for c in counts.schema["scores"].dataType.fieldNames()
        ]).alias("scores"),
    ])
)

counts = counts.withColumnRenamed("1", "heterozygous").withColumnRenamed("2", "homozygous")

counts.printSchema()

counts.write.format("delta").save('/s/project/rep/processed/VEP/vep_counts3.deltalake')

written_counts = (
    spark
    .read
    .format('delta')
    .load('/s/project/rep/processed/VEP/vep_counts3.deltalake')
)
displayHead(written_counts)

# +
from pyspark.sql import functions as F
from pyspark.sql.types import DataType, StructType, ArrayType
from pyspark.sql import DataFrame
import re

def __rename_nested_field__(in_field: DataType, fieldname_normaliser):
	if isinstance(in_field, ArrayType):
		dtype = ArrayType(__rename_nested_field__(in_field.elementType, fieldname_normaliser), in_field.containsNull)
	elif isinstance(in_field, StructType):
		dtype = StructType()
		for field in in_field.fields:
			dtype.add(fieldname_normaliser(field.name), __rename_nested_field__(field.dataType, fieldname_normaliser))
	else:
		dtype = in_field
	return dtype

def __normalise_fieldname__(raw: str):
	return re.sub('[^A-Za-z0-9_]+', '_', raw.strip())

def __get_fields_info__(dtype: DataType, name: str = ""):
	ret = []
	if isinstance(dtype, StructType):
		for field in dtype.fields:
			for child in __get_fields_info__(field.dataType, field.name):
				wrapped_child = ["{prefix}{suffix}".format(
					prefix=("" if name == "" else "`{}`.".format(name)), suffix=child[0])] + child[1:]
				ret.append(wrapped_child)
	elif isinstance(dtype, ArrayType) and (
			isinstance(dtype.elementType, ArrayType) or isinstance(dtype.elementType, StructType)):
		for child in __get_fields_info__(dtype.elementType):
			wrapped_child = ["`{}`".format(name)] + child
			ret.append(wrapped_child)
	else:
		return [["`{}`".format(name)]]
	return ret

def normalise_fields_names(df: DataFrame, fieldname_normaliser=__normalise_fieldname__):
	return df.select([
		F.col("`{}`".format(field.name)).cast(__rename_nested_field__(field.dataType, fieldname_normaliser))
			.alias(fieldname_normaliser(field.name)) for field in df.schema.fields
	])

def flatten(df: DataFrame, fieldname_normaliser=__normalise_fieldname__):
	cols = []
	for child in __get_fields_info__(df.schema):
		if len(child) > 2:
			ex = "x.{}".format(child[-1])
			for seg in child[-2:0:-1]:
				if seg != '``':
					ex = "transform(x.{outer}, x -> {inner})".format(outer=seg, inner=ex)
			ex = "transform({outer}, x -> {inner})".format(outer=child[0], inner=ex)
		else:
			ex = ".".join(child)
		cols.append(F.expr(ex).alias(fieldname_normaliser("_".join(child).replace('`', ''))))
	return df.select(cols)
# -

flattened_counts = flatten(written_counts, lambda name: name)
flattened_counts.printSchema()

flattened_counts.write.format("delta").save('/s/project/rep/processed/VEP/vep_counts_flattened3.deltalake')

displayHead(flattened_counts)


import tensorflow as tf
import cPickle
import numpy as np
def assign_as_blocks_v2(a,b):
        shape1 = tf.shape(a)
        shape2 = tf.shape(b)
        m1 = shape1[0]
        n1 = shape1[1]
        m2 = shape2[0]
        n2 = shape2[1]
        p1 = tf.tile(a,[1,n2])
        p2 = tf.reshape(tf.tile(tf.expand_dims(b, 1),[1,1,n1]), [m2,-1])
        out = tf.concat((p1,p2),axis=0)
        return out

class DIS():
    def __init__(self, itemNum, userNum, emb_dim, lamda, param=None, initdelta=0.05, learning_rate=0.05):
        self.itemNum = itemNum
        self.userNum = userNum
        self.emb_dim = emb_dim
        self.lamda = lamda  # regularization parameters
        self.param = param
        self.initdelta = initdelta
        self.learning_rate = learning_rate
        self.d_params = []
        self.hidden_num_units = 5

        with tf.variable_scope('discriminator'):
            if self.param == None:
                self.user_embeddings = tf.Variable(
                    tf.random_uniform([self.userNum, self.emb_dim], minval=-self.initdelta, maxval=self.initdelta,
                                      dtype=tf.float32))
                self.item_embeddings = tf.Variable(
                    tf.random_uniform([self.itemNum, self.emb_dim], minval=-self.initdelta, maxval=self.initdelta,
                                      dtype=tf.float32))
                self.item_bias = tf.Variable(tf.zeros([self.itemNum]))
            else:
                self.user_embeddings = tf.Variable(self.param[0])
                self.item_embeddings = tf.Variable(self.param[1])
                self.item_bias = tf.Variable(self.param[2])

        # placeholder definition
        self.u = tf.placeholder(tf.int32)
        self.i = tf.placeholder(tf.int32)
        self.label = tf.placeholder(tf.float32)

        self.u_embedding = tf.nn.embedding_lookup(self.user_embeddings, self.u)
        self.i_embedding = tf.nn.embedding_lookup(self.item_embeddings, self.i)
        self.i_bias = tf.gather(self.item_bias, self.i)

        self.x = tf.concat([self.u_embedding, self.i_embedding],1)

        self.weights = {
                'hidden': tf.Variable(tf.random_normal([2*self.emb_dim, self.hidden_num_units], seed=4350)),
                'output': tf.Variable(tf.random_normal([self.hidden_num_units, 1], seed=4350))
        }

        self.biases = {
                'hidden': tf.Variable(tf.random_normal([self.hidden_num_units], seed=4350)),
                'output': tf.Variable(tf.random_normal([1], seed=4350))
        }

        self.d_params = [self.user_embeddings, self.item_embeddings, self.item_bias, self.weights['hidden'], self.weights['output'], self.biases['hidden'], self.biases['output']]

        self.hidden_layer = tf.add(tf.matmul(self.x, self.weights['hidden']), self.biases['hidden'])

        self.hidden_layer = tf.nn.relu(self.hidden_layer)

        self.pre_logits = tf.matmul(self.hidden_layer, self.weights['output']) + self.biases['output']

        # self.pre_logits = tf.reduce_sum(tf.multiply(self.u_embedding, self.i_embedding), 1) + self.i_bias
        self.pre_loss = tf.nn.sigmoid_cross_entropy_with_logits(labels=self.label,
                                                                logits=self.pre_logits) + self.lamda * (
            tf.nn.l2_loss(self.u_embedding) + tf.nn.l2_loss(self.i_embedding) + tf.nn.l2_loss(self.i_bias)
        )

        d_opt = tf.train.GradientDescentOptimizer(self.learning_rate)
        self.d_updates = d_opt.minimize(self.pre_loss, var_list=self.d_params)

        #reward_logits calculation
        temp_embedding = tf.reshape(self.u_embedding, [-1, 1])
        shape = tf.shape(self.i_embedding)
        conc_embedding = tf.transpose(tf.tile(temp_embedding, [1, shape[0]]))
        self.input_embed = tf.concat([conc_embedding, self.i_embedding], 1)

        hidden_layer = tf.add(tf.matmul(self.input_embed, self.weights['hidden']), self.biases['hidden'])

        hidden_layer = tf.nn.relu(hidden_layer)

        self.reward_logits = tf.matmul(hidden_layer, self.weights['output']) + self.biases['output']

        # self.reward_logits = tf.reduce_sum(tf.multiply(self.u_embedding, self.i_embedding),
                                           # 1) + self.i_bias
        #reward_logits calculation

        self.reward = 2 * (tf.sigmoid(self.reward_logits) - 0.5)

        #all_rating calculation
        # for test stage, self.u: [batch_size]
        # self.all_pairs = [[ tf.concat(x,y) for x in self.u_embedding ] for y in self.item_embeddings]
        self.all_pairs = tf.transpose(assign_as_blocks_v2(tf.transpose(self.u_embedding), tf.transpose(self.item_embeddings)))
        hidden_layer = tf.add(tf.matmul(self.all_pairs, self.weights['hidden']), self.biases['hidden'])
        hidden_layer = tf.nn.relu(hidden_layer)
        self.all_rating = tf.matmul(hidden_layer, self.weights['output']) + self.biases['output']
        # self.all_rating = tf.matmul(self.u_embedding, self.item_embeddings, transpose_a=False,
                                    # transpose_b=True) + self.item_bias
        #all_rating calculation

        #all_logits calculation
        shape2 = tf.shape(self.item_embeddings)
        conc_embedding2 = tf.transpose(tf.tile(temp_embedding, [1, shape2[0]]))
        self.input_embed2 = tf.concat([conc_embedding2, self.item_embeddings], 1)

        hidden_layer = tf.add(tf.matmul(self.input_embed2, self.weights['hidden']), self.biases['hidden'])

        hidden_layer = tf.nn.relu(hidden_layer)

        self.all_logits = tf.matmul(hidden_layer, self.weights['output']) + self.biases['output']
        # self.all_logits = tf.reduce_sum(tf.multiply(self.u_embedding, self.item_embeddings), 1) + self.item_bias
        #all_logits calculation

        self.NLL = -tf.reduce_mean(tf.log(
            tf.gather(tf.reshape(tf.nn.softmax(tf.reshape(self.all_logits, [1, -1])), [-1]), self.i))
        )
        # for dns sample
        self.dns_rating = tf.reduce_sum(tf.multiply(self.u_embedding, self.item_embeddings), 1) + self.item_bias

    def save_model(self, sess, filename):
        param = sess.run(self.d_params)
        cPickle.dump(param, open(filename, 'w'))


import openai

from src.models import ModelFinder

from src.ai.config import CODE_DEFAULT_MAX_TOKENS, CODE_DEFAULT_TEMPERATURE

class CodePromptResult:
    def __init__(self, result: str, used_tokens: int) -> None:
        self.result = result
        self.used_tokens = used_tokens

def code_prompt(
    input: str,
    temperature: float = CODE_DEFAULT_TEMPERATURE,
    max_tokens: int = CODE_DEFAULT_MAX_TOKENS,
    echo_prompt: bool = True
) -> CodePromptResult:
    response = openai.Completion.create(
        model=ModelFinder.get_best_for_code().as_str,
        prompt=input,
        temperature=temperature,
        max_tokens=max_tokens,
        echo=echo_prompt
    )
    result = CodePromptResult(
        result=response.choices[0].text,
        used_tokens=response.usage.total_tokens
    )
    return result


from notifypy import Notify
from PySimpleGUI import PySimpleGUI as sg

# 1 ciclo pomodoro = 25 min = 1500 segundos
# OK exibir tempo restante do ciclo na tela
# OK exibir quantidade de ciclos
# OK ao finalizar ciclo, tocar som de alerta COM notificação

# Após 1 ciclo, realizar pausa de 5 min = 300 segundos
# - ao finalizar pausa, tocar som de alerta - > escolher som de alerta para pausa
# - criar função timer para pausa

# Após 4 ciclos concluídos, realizar pausa longa de 15 a 30 min = 900 / 1800 segundos
# - exibir alerta de notificação
# - perguntar se deseja iniciar novo ciclo ou finalizar

# OK Reiniciar ciclo para seguir tarefas

def notificacao(meu_titulo='Título Teste', texto_notificacao='Texto Teste'):
    notifica = Notify()
    notifica.title = meu_titulo
    notifica.message = texto_notificacao
    notifica.audio = 'files/sound/alerta.wav'
    return notifica.send()

titulo = 'Pomodoro Notipyer '
fim_tarefa = 'Tarefa concluída!'

def formatar_tempo(t):
    mins, secs = divmod(t, 60)
    tempo_formatado = '{:02d}:{:02d}'.format(mins, secs)
    return tempo_formatado

ciclos_realizados = 0

sg.theme('Reddit')

layout = [[sg.Text('Ciclos:'), sg.Text('0', key='CICLOS')],
          [sg.Text('00:00', size=(8, 2), font=('Helvetica', 20),
                   justification='center', key='TIMER')],
          [sg.Text('-HOLDER TXT-')],
          [sg.Button('Iniciar', key='INICIAR', focus=True, button_color=('black', 'white')),
           sg.Button('Pausar', key='PAUSAR', focus=False, disabled=True, button_color=('black', 'white')),
           sg.Button('Resetar', key='RESETAR', focus=False, disabled=True, button_color=('black', 'white'))]]

app = sg.Window('Notipyer Pomodoro', layout, auto_size_buttons=False, keep_on_top=False,
                grab_anywhere=True,
                element_padding=(0, 0),
                finalize=True,
                element_justification='c')

contador_esta_ativo, tempo_restante = False, 5  # contador inicia desativado // tempo do timer pomodoro em segundos

# Loop de Eventos do App
while True:
    evento, valores = app.Read(1000)
    tempo_restante -= 1 * (contador_esta_ativo is True)

    if evento == 'INICIAR':
        contador_esta_ativo = True
        if tempo_restante == 0:
            tempo_restante = 10
        app['INICIAR'].Update(disabled=True)
        app['PAUSAR'].Update(disabled=False)
        app['RESETAR'].Update(disabled=False)

    elif evento == 'PAUSAR':
        contador_esta_ativo = False
        app['INICIAR'].Update('Continuar', disabled=False)
        app['PAUSAR'].Update(disabled=True)

    elif evento == 'RESETAR':
        tempo_restante = 10
        contador_esta_ativo = False
        app['INICIAR'].Update('Iniciar', disabled=False)
        app['PAUSAR'].Update(disabled=True)
        app['RESETAR'].Update(disabled=True)

    elif tempo_restante == 0 and contador_esta_ativo:  # fim da contagem
        notificacao(titulo, fim_tarefa)
        tempo_restante = 0
        ciclos_realizados += 1
        app['CICLOS'].Update(f'{ciclos_realizados}')
        contador_esta_ativo = False

        if evento == 'INICIAR':
            tempo_restante = 10
            app['INICIAR'].Update(disabled=True)
            app['PAUSAR'].Update(disabled=False)
            app['RESETAR'].Update(disabled=False)
        app['INICIAR'].Update('Reiniciar', disabled=False)
        app['PAUSAR'].Update(disabled=True)
        app['RESETAR'].Update(disabled=True)

    elif evento is None or evento == 'Quit':
        break

    app['TIMER'].Update(formatar_tempo(tempo_restante))


import numpy as np
import pandas as pd
import cv2
from sklearn.model_selection import train_test_split
import tensorflow as tf
import keras
from keras.models import Model
from keras.models import load_model
from keras.layers import Input, Dense, Concatenate
from keras.layers import Dense, GlobalAveragePooling2D, Dropout, UpSampling2D, Conv2D, MaxPooling2D, Activation, Dropout
from keras.optimizers import adam_v2
from keras import backend as K

# Metrics

def dice_coeff(y_true, y_pred):
    smooth = 1.
    # Flatten
    y_true_f = tf.reshape(y_true, [-1])
    y_pred_f = tf.reshape(y_pred, [-1])
    intersection = tf.reduce_sum(y_true_f * y_pred_f)
    score = (2. * intersection + smooth) / (tf.reduce_sum(y_true_f) + tf.reduce_sum(y_pred_f) + smooth)
    return score

def recall(y_true, y_pred):
    true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))
    possible_positives = K.sum(K.round(K.clip(y_true, 0, 1)))
    recall_keras = true_positives / (possible_positives + K.epsilon())
    return recall_keras

def precision(y_true, y_pred):
    true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))
    predicted_positives = K.sum(K.round(K.clip(y_pred, 0, 1)))
    precision_keras = true_positives / (predicted_positives + K.epsilon())
    return precision_keras

def f1(y_true, y_pred):
    p = precision(y_true, y_pred)
    r = recall(y_true, y_pred)
    return 2 * ((p * r) / (p + r + K.epsilon()))

# Load data

masks = pd.read_csv('train_ship_segmentations_v2.csv')

print('CSV file loaded')

# Split data to train, validation and test sets (70:28:2)

train_df = masks[:230000]
test_df = masks[230000:]
test_df.reset_index(drop = True, inplace = True)
train_df = train_df.dropna(axis = 'index')       # images without ships don't need for train
train_df, val_df = train_test_split (train_df, test_size = 0.3, random_state = 42)

# Function fo decoding lables to masks

def rle_decode(mask_rle, shape = (768, 768)):
    s = mask_rle.split()
    starts, lengths = [np.asarray(x, dtype=int) for x in (s[0:][::2], s[1:][::2])]
    starts -= 1
    ends = starts + lengths
    img = np.zeros(shape[0] * shape[1], dtype = np.uint8)

    for lo, hi in zip(starts, ends):
        img[lo:hi] = 1
    return img.reshape(shape).T

# Generators for Model training (to reduce memory usage)

def img_generator(gen_df, batch_size):
    while True:
        x_batch = []
        y_batch = []

        for i in range(batch_size):
            img_name, mask_rle = gen_df.sample(1).values[0]      # get row from DF
            img = cv2.imread('train_v2/'+ img_name)              # read img

            img_masks = masks.loc[masks['ImageId'] == img_name, 'EncodedPixels'].tolist()

            all_masks = np.zeros((768, 768))                     # find ship masks for more the one ship
            for mask in img_masks:                               # create a single mask for all ships
                all_masks += rle_decode(mask)

            img = cv2.resize(img, (256, 256))                    # resize img to 256,256
            mask = cv2.resize(all_masks, (256, 256))             # resize mask to 256,256

            x_batch += [img]                                     # put into batch
            y_batch += [mask]

        x_batch = np.array(x_batch) / 255.                       # reduce color dimension img
        y_batch = np.array(y_batch)

        yield x_batch, np.expand_dims(y_batch, -1)               # return batch

# Make the Model

inp = Input(shape=(256, 256, 3))                               # input layer with shape 256x256 and 3 chanels

conv_1_1 = Conv2D(32, (3, 3), padding = 'same')(inp)           # increase filters number to 32, kernel size 3x3
conv_1_1 = Activation('relu')(conv_1_1)

conv_1_2 = Conv2D(32, (3, 3), padding = 'same')(conv_1_1)
conv_1_2 = Activation('relu')(conv_1_2)

pool_1 = MaxPooling2D(2)(conv_1_2)                             # reduce image size

conv_2_1 = Conv2D(64, (3, 3), padding = 'same')(pool_1)        # increase filters number to 64
conv_2_1 = Activation('relu')(conv_2_1)

conv_2_2 = Conv2D(64, (3, 3), padding = 'same')(conv_2_1)
conv_2_2 = Activation('relu')(conv_2_2)

pool_2 = MaxPooling2D(2)(conv_2_2)                             # reduce image size

conv_3_1 = Conv2D(128, (3, 3), padding = 'same')(pool_2)       # increase filters number to 128
conv_3_1 = Activation('relu')(conv_3_1)

conv_3_2 = Conv2D(128, (3, 3), padding = 'same')(conv_3_1)
conv_3_2 = Activation('relu')(conv_3_2)

pool_3 = MaxPooling2D(2)(conv_3_2)                             # reduce image size

conv_4_1 = Conv2D(256, (3, 3), padding = 'same')(pool_3)       # increase filters number to 256
conv_4_1 = Activation('relu')(conv_4_1)

conv_4_2 = Conv2D(256, (3, 3), padding = 'same')(conv_4_1)
conv_4_2 = Activation('relu')(conv_4_2)

pool_4 = MaxPooling2D(2)(conv_4_2)                             # reduce image size

up_1 = UpSampling2D(2, interpolation = 'bilinear')(pool_4)     # increase image size

conc_1 = Concatenate()([conv_4_2, up_1])                       # concatenate withe the same size layer before upsampling to get low level info

conv_up_1_1 = Conv2D(256, (3, 3), padding = 'same')(conc_1)
conv_up_1_1 = Activation('relu')(conv_up_1_1)

conv_up_1_2 = Conv2D(256, (3, 3), padding = 'same')(conv_up_1_1)
conv_up_1_2 = Activation('relu')(conv_up_1_2)

up_2 = UpSampling2D(2, interpolation = 'bilinear')(conv_up_1_2) # increase image size

conc_2 = Concatenate()([conv_3_2, up_2])                        # concatenate withe the same size layer before upsampling to get low level info

conv_up_2_1 = Conv2D(128, (3, 3), padding = 'same')(conc_2)     # reduce filter number to 128
conv_up_2_1 = Activation('relu')(conv_up_2_1)

conv_up_2_2 = Conv2D(128, (3, 3), padding = 'same')(conv_up_2_1)
conv_up_2_2 = Activation('relu')(conv_up_2_2)

up_3 = UpSampling2D(2, interpolation = 'bilinear')(conv_up_2_2) # increase image size

conc_3 = Concatenate()([conv_2_2, up_3])                        # concatenate withe the same size layer before upsampling to get low level info

conv_up_3_1 = Conv2D(64, (3, 3), padding = 'same')(conc_3)      # reduce filter number to 64
conv_up_3_1 = Activation('relu')(conv_up_3_1)

conv_up_3_2 = Conv2D(64, (3, 3), padding='same')(conv_up_3_1)
conv_up_3_2 = Activation('relu')(conv_up_3_2)

up_4 = UpSampling2D(2, interpolation = 'bilinear')(conv_up_3_2) # increase image size

conc_4 = Concatenate()([conv_1_2, up_4])                        # concatenate withe the same size layer before upsampling to get low level info

conv_up_4_1 = Conv2D(32, (3, 3), padding = 'same')(conc_4)      # reduce filter number to 32
conv_up_4_1 = Activation('relu')(conv_up_4_1)

conv_up_4_2 = Conv2D(1, (3, 3), padding = 'same')(conv_up_4_1)
conv_up_4_3 = Dropout(0.5)(conv_up_4_2)                         # avoid overfitting

result = Activation('sigmoid')(conv_up_4_3)                     # otput layer with sigmoid activation to get probability is a pixel ship

model = Model(inputs = inp, outputs = result)

best_w = keras.callbacks.ModelCheckpoint('r34_best.h5',           # save best weights during training
                                monitor = 'val_loss',
                                verbose = 0,
                                save_best_only = True,
                                save_weights_only = True,
                                mode = 'auto',
                                period = 1)

last_w = keras.callbacks.ModelCheckpoint('r34_last.h5',            # save last weights during training
                                monitor = 'val_loss',
                                verbose = 0,
                                save_best_only = False,
                                save_weights_only = True,
                                mode='auto',
                                period=1)

callbacks = [best_w, last_w]

adam = tf.keras.optimizers.Adam(learning_rate = 0.0001,
                                beta_1 = 0.9,
                                beta_2 = 0.999,
                                epsilon = 1e-08,
                                decay = 0.0)

model.compile(adam, 'binary_crossentropy', [f1, dice_coeff])

batch_size = 16

print ('Training is started')

model.fit(img_generator(train_df, batch_size),
              steps_per_epoch = 100,
              epochs = 300,
              verbose = 1,
              callbacks = callbacks,
              validation_data = img_generator(val_df, batch_size),
              validation_steps = 10,
              class_weight = None,
              max_queue_size = 10,
              workers = 1,
              use_multiprocessing = False,
              shuffle = True,
              initial_epoch = 0)

# Save the Model

model.save('last_saved_model.h5')

print('Training completed successfully and the Model has been saved to a file "last_saved_model.h5"')


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

'''
First script
'''

from pathlib import Path
import sys
import argparse

pathSearch = Path('.').resolve().as_posix()
sys.path.append(pathSearch)

# -----------------------------------------

description='''This is a description of what the script does.
This script:
- is to show how the 'argparse' module works
- displays the given arguments
'''

def parserFunction():
    '''Function parsing command line arguments'''
    parser = argparse.ArgumentParser(description = description)

    # Add arguments to your module: mandatory, i.e. positional and optional i.e.
    parser.add_argument('rows',     type=int,    help=u'''Number of rows''')
    parser.add_argument('cols',     type=int,    help=u'''Number of cols''')
    parser.add_argument('-p','--somePath',     type=str,    help=u'''Path to folder''')

    args = parser.parse_args()
    return args

def main(args):
    if args.somePath:
        args.fullPath = Path(args.somePath).resolve().as_posix()

    print(f'Dictionary of command line arguments:')
    for key,val in vars(args).items():
        print(f'key = {key}\tvalues = {val}')

    print('\n')

# ------------------------------------------

if __name__ == '__main__':

    args = parserFunction()
    print(f'''\nThe 'args' is of the type:\t{type(args)}\nand it looks like this:\n\t\t\t{args}\n''')

    main(args)


from LockerAssignment.repository import locker_repository
from LockerAssignment.controller import unlock_controller, request_controller, cancel_controller, quit_controller

class LockerSystem:
    optionControllers: dict
    locker_repository: locker_repository.LockerRepository

    def __init__(self):
        self.locker_repository = locker_repository.LockerRepository()
        self.optionControllers = {
            1: unlock_controller.unlockController(self.locker_repository),
            2: request_controller.requestController(self.locker_repository),
            3: cancel_controller.cancelController(self.locker_repository),
            0: quit_controller.quitController()
        }

        self.show_menu()

    # Shows the initial menu for the application.
    def show_menu(self):
        print('Welcome, please choose one of the following options')
        print('Option 1. Unlock a locker.')
        print('Option 2. Request a new locker.')
        print('Option 3. Cancel a locker.')
        print('Option 0. Quit the application')

        try:
            selected_option = int(
                input('Please enter the option number.')
            )
        except ValueError:
            return self.handle_invalid_menu_input()

        self.handle_selected_option(selected_option)

    # Handles the users input, calls the right controller for the right option.
    def handle_selected_option(self, selected_option):
        if selected_option in self.optionControllers:
            self.optionControllers[selected_option].handle_request()

            print('=============================================')
            self.show_menu()
        else:
            self.handle_invalid_menu_input()

    # Notifies the user that his input is invalid, recalls the show_menu function.
    def handle_invalid_menu_input(self):
        print('This is not a valid option, please try again.')
        print('=============================================')
        self.show_menu()

LockerSystem()


# Hash-backed maps
from queue import Queue
dictionary = {
    "harry": 101,
    "garry": 102,
    "larry": 103
}

print(dictionary["harry"])

dictionary["larry"] = 104
# all keys
for x in dictionary:
    print(x)
# all values
for x in dictionary:
    print(dictionary[x])

print("-----------------------")
# Queue
# Initialize queue
q = Queue(maxsize=3)
print(q.qsize())
# add elements to queue
q.put(3)
q.put(5)
q.put(7)
# return bool for full queue
print(q.full())
# Remove elements from queue
q.get()
# Return bool for empty queue
print(q.empty())

print("-----------------------")
# approach 1
stack = [1,2,3,4,5]
stack.pop()
stack.append(6)
print(stack)

# approach 2

class Stack:
    def __init__(self):
        self.stack = []

    # check if empty
    def isempty(self):
        return len(self.stack)==0
    # push element
    def push(self,p):
        self.stack.append(p)
    # pop element
    def pop(self):
        return self.stack.pop()


# coding: utf-8

"""
Ctypes wrapper module for BUSMUST CAN Interface on win32/win64 systems.

Authors: busmust <busmust@126.com>, BUSMUST Co.,Ltd.
"""

# Import Standard Python Modules
# ==============================
import ctypes
import logging
import sys
import time

try:
    # Try builtin Python 3 Windows API
    from _winapi import WaitForSingleObject, INFINITE
    HAS_EVENTS = True
except ImportError:
    try:
        # Try pywin32 package
        from win32event import WaitForSingleObject, INFINITE
        HAS_EVENTS = True
    except ImportError:
        # Use polling instead
        HAS_EVENTS = False

# Import Modules
# ==============
from can import BusABC, Message, CanError
from can.bus import BusState
from can.util import len2dlc, dlc2len
from .exceptions import BmError

# Define Module Logger
# ====================
LOG = logging.getLogger(__name__)

# Import safely Vector API module for Travis tests
bmapi = None
try:
    from . import bmapi
except Exception as exc:
    LOG.warning('Could not import bmapi: %s', exc)

class BmCanBus(BusABC):
    """The CAN Bus implemented for the BUSMUST USB-CAN interface."""

    __initialized = False

    @classmethod
    def __init_class__(cls):
        if bmapi is None:
            raise ImportError("The BMAPI has not been loaded")
        if not BmCanBus.__initialized:
            bmapi.BM_Init()
            BmCanBus.__initialized = True

    def __init__(self, channel,
                 fd=True, receive_own_messages=False, listen_only=False,
                 bitrate=500000, data_bitrate=500000,
                 tres=False,
                 can_filters=None,
                 **kwargs):
        """
        :param int channel:
            The channel index to create this bus with, which is the index to all available ports when enumerating Busmust devices.
            Can also be a string of the channel's full name. i.e. "BM-CANFD-X1-PRO(1234) CH1"
        :param bool fd:
            If CAN-FD frames should be supported.
        :param bool receive_own_messages:
            If Loopback mode should be supported.
        :param bool listen_only:
            If Listen only mode should be supported, this is the same as setting 'state' property to INACTIVE.
        :param int bitrate:
            Bitrate in bits/s.
        :param int data_bitrate:
            Which bitrate to use for data phase in CAN FD.
            Defaults to arbitration bitrate.
        :param bool tres:
            If 120Ohm CAN terminal register should be enabled.
        """
        BmCanBus.__init_class__()
        self._bmapi = bmapi # Enable external access

        infolist = bmapi.BM_ChannelInfoListTypeDef()
        numOfInfo = ctypes.c_int(len(infolist.entries))
        bmapi.BM_Enumerate(ctypes.byref(infolist), ctypes.byref(numOfInfo))
        if isinstance(channel, int):
            if channel < numOfInfo.value:
                self._channelinfo = infolist.entries[channel]
            else:
                raise BmError(bmapi.BM_ERROR_NODRIVER, "Channel %d is not connected or is in use by another app." % channel, "BmCanBus.__init__")
        elif isinstance(channel, str):
            for info in infolist.entries:
                if info.name.decode() == channel:
                    self._channelinfo = info
                    break
            else:
                raise BmError(bmapi.BM_ERROR_NODRIVER, "Channel %s is not connected or is in use by another app." % channel, "BmCanBus.__init__")

        self._mode = bmapi.BM_CAN_NORMAL_MODE
        if not fd:
            self._mode = bmapi.BM_CAN_CLASSIC_MODE
        elif receive_own_messages:
            self._mode = bmapi.BM_CAN_EXTERNAL_LOOPBACK_MODE
        elif listen_only:
            self._mode = bmapi.BM_CAN_LISTEN_ONLY_MODE

        self._tres = bmapi.BM_TRESISTOR_DISABLED
        if tres:
            self._tres = bmapi.BM_TRESISTOR_120

        self._bitrate = bmapi.BM_BitrateTypeDef()
        self._bitrate.nbitrate = int(bitrate / 1000)
        self._bitrate.dbitrate = int(data_bitrate / 1000)

        self._handle = bmapi.BM_ChannelHandle()
        bmapi.BM_OpenEx(
            ctypes.byref(self._handle),
            ctypes.byref(self._channelinfo),
            self._mode,
            self._tres,
            ctypes.byref(self._bitrate),
            ctypes.cast(ctypes.c_void_p(), ctypes.POINTER(bmapi.BM_RxFilterListTypeDef)), 0
        )
        self.channel_info = self._channelinfo.name.decode()

        startTimestamp = ctypes.c_uint32()
        bmapi.BM_GetTimestamp(self._handle, ctypes.byref(startTimestamp))
        self._time_offset = time.time() - startTimestamp.value * 1e-9

        self._notification = bmapi.BM_NotificationHandle()
        bmapi.BM_GetNotification(self._handle, ctypes.byref(self._notification))

        super(BmCanBus, self).__init__(channel=channel, can_filters=can_filters, **kwargs)
        time.sleep(0.05)

        self._state = BusState.ACTIVE

        self._isotp_config = bmapi.BM_IsotpConfigTypeDef()

    def _apply_filters(self, filters):
        if filters:
            # Only up to one filter per ID type allowed
            if len(filters) == 1 or (len(filters) == 2 and filters[0].get("extended") != filters[1].get("extended")):
                bmfilters = bmapi.BM_RxFilterListTypeDef()
                try:
                    for i in range(len(filters)):
                        can_filter = filters[i]
                        bmfilters.entries[i].type = bmapi.BM_RXFILTER_BASIC
                        bmfilters.entries[i].flags_mask = bmapi.BM_MESSAGE_FLAGS_IDE
                        if can_filter.get("extended"):
                            bmfilters.entries[i].flags_value = bmapi.BM_MESSAGE_FLAGS_IDE
                            bmfilters.entries[i].id_mask = (can_filter["can_mask"] >> 18) | ((can_filter["can_mask"] & 0x3FFFF) << 11)
                            bmfilters.entries[i].id_value = (can_filter["can_id"] >> 18) | ((can_filter["can_id"] & 0x3FFFF) << 11)
                        else:
                            bmfilters.entries[i].flags_value = 0
                            bmfilters.entries[i].id_mask = can_filter["can_mask"]
                            bmfilters.entries[i].id_value = can_filter["can_id"]
                    bmapi.BM_SetRxFilters(self._handle, ctypes.byref(bmfilters), len(bmfilters.entries))
                    time.sleep(0.05)
                except BmError as exc:
                    LOG.warning("Could not set filters: %s", exc)
                    # go to fallback
                else:
                    self._is_filtered = True
                    return
            else:
                LOG.warning("Only up to one filter per extended or standard ID allowed")
                # go to fallback

        # fallback: reset filters
        self._is_filtered = False
        try:
            bmfilters = bmapi.BM_RxFilterListTypeDef() # Default as invalid => allow all messages to pass
            bmapi.BM_SetRxFilters(self._handle, ctypes.byref(bmfilters), 2)
            time.sleep(0.05)
        except BmError as exc:
            LOG.warning("Could not reset filters: %s", exc)

    def _recv_internal(self, timeout):
        end_time = time.time() + timeout if timeout is not None else None

        bmmsg = bmapi.BM_CanMessageTypeDef()
        channel = ctypes.c_uint32()
        timestamp = ctypes.c_uint32()

        while True:
            try:
                bmapi.BM_ReadCanMessage(self._handle, ctypes.byref(bmmsg), ctypes.byref(channel), ctypes.byref(timestamp))
            except BmError as exc:
                if exc.error_code != bmapi.BM_ERROR_QRCVEMPTY:
                    raise
            else:
                msg_id = bmmsg.mid.getExtendedId() if bmmsg.ctrl.rx.IDE else bmmsg.mid.getStandardId()
                dlc = dlc2len(bmmsg.ctrl.rx.DLC)
                msg = Message(
                    timestamp=timestamp.value * 1e-6 + self._time_offset,
                    arbitration_id=msg_id & 0x1FFFFFFF,
                    is_extended_id=bool(bmmsg.ctrl.rx.IDE),
                    is_remote_frame=bool(bmmsg.ctrl.rx.RTR),
                    is_error_frame=bool(False),
                    is_fd=bool(bmmsg.ctrl.rx.FDF),
                    error_state_indicator=bool(bmmsg.ctrl.rx.ESI),
                    bitrate_switch=bool(bmmsg.ctrl.rx.BRS),
                    dlc=dlc,
                    data=bmmsg.payload[:dlc],
                    channel=channel.value)
                return msg, self._is_filtered

            if end_time is not None and time.time() > end_time:
                return None, self._is_filtered

            # Wait for receive event to occur
            if timeout is None:
                time_left_ms = INFINITE
            else:
                time_left = end_time - time.time()
                time_left_ms = max(0, int(time_left * 1000))
            bmapi.BM_WaitForNotifications(ctypes.byref(self._notification), 1, time_left_ms)

    def send(self, msg, timeout=None):
        bmmsg = bmapi.BM_CanMessageTypeDef()
        if msg.is_extended_id:
            bmmsg.mid.SID = msg.arbitration_id >> 18
            bmmsg.mid.EID = (msg.arbitration_id & 0x3FFFF)
        else:
            bmmsg.mid.SID = msg.arbitration_id
            bmmsg.mid.EID = 0
        bmmsg.ctrl.tx.IDE = 1 if msg.is_extended_id else 0
        bmmsg.ctrl.tx.FDF = 1 if msg.is_fd else 0
        bmmsg.ctrl.tx.BRS = 1 if msg.bitrate_switch else 0
        bmmsg.ctrl.tx.RTR = 1 if msg.is_remote_frame else 0
        bmmsg.ctrl.tx.ESI = 1 if msg.error_state_indicator else 0
        bmmsg.ctrl.tx.DLC = len2dlc(msg.dlc)
        bmmsg.payload[:len(msg.data)] = msg.data
        timestamp = ctypes.c_uint32()
        bmapi.BM_WriteCanMessage(self._handle, ctypes.byref(bmmsg), 0, int(timeout*1000) if timeout else -1, ctypes.byref(timestamp))

    def shutdown(self):
        bmapi.BM_Close(self._handle)
        self._handle = bmapi.BM_ChannelHandle()

    def reset(self):
        bmapi.BM_Reset(self._handle)

    @property
    def state(self):
        return self._state

    @state.setter
    def state(self, new_state):
        mode_changed = False
        self._state = new_state
        if new_state is BusState.ACTIVE:
            if self._mode == bmapi.BM_CAN_OFF_MODE or self._mode == bmapi.BM_CAN_LISTEN_ONLY_MODE:
                self._mode = bmapi.BM_CAN_NORMAL_MODE
                mode_changed = True
            else:
                pass # Do not change (i.e. loopback)
        elif new_state is BusState.PASSIVE:
            # When this mode is set, the CAN controller does not take part on active events (eg. transmit CAN messages)
            # but stays in a passive mode (CAN monitor), in which it can analyse the traffic on the CAN bus used by a BMCAN channel.
            if self._mode != bmapi.BM_CAN_LISTEN_ONLY_MODE:
                self._mode = bmapi.BM_CAN_LISTEN_ONLY_MODE
                mode_changed = True
        if mode_changed:
            bmapi.BM_SetCanMode(self._handle, self._mode)

    @classmethod
    def enumerate(cls):
        BmCanBus.__init_class__()
        infolist = bmapi.BM_ChannelInfoListTypeDef()
        numOfInfo = ctypes.c_int(len(infolist.entries))
        bmapi.BM_Enumerate(ctypes.byref(infolist), ctypes.byref(numOfInfo))
        channellist = []
        for i in range(numOfInfo.value):
            channellist.append({
                'index': i,
                'name': infolist.entries[i].name.decode(),
                # Add other exports here
            })
        return channellist

    def send_isotp(self, payload, timeout=-1):
        timeout_ms = int(timeout * 1000.0) if timeout >= 0 else -1
        bmapi.BM_WriteIsotp(self._handle, ctypes.c_char_p(payload), len(payload), timeout_ms, ctypes.byref(self._isotp_config))

    def receive_isotp(self, timeout=-1, max_len=4095):
        timeout_ms = int(timeout * 1000.0) if timeout >= 0 else -1
        buf = ctypes.create_string_buffer(max_len)
        received_len = ctypes.c_uint32(len(buf))
        bmapi.BM_ReadIsotp(self._handle, buf, ctypes.byref(received_len), timeout_ms, ctypes.byref(self._isotp_config))
        return bytes(buf[:received_len.value])

    def config_isotp(self, tester_msg_id, ecu_msg_id, mode=bmapi.BM_ISOTP_NORMAL_TESTER, **kwargs):
        self._isotp_config.mode = mode
        enable_fdf = kwargs.get('fd', False) or kwargs.get('fdf', False)
        enable_brs = kwargs.get('brs', enable_fdf)
        enable_ide = kwargs.get('ide', False) or tester_msg_id > 0x7FF or ecu_msg_id > 0x7FF
        dlc = kwargs.get('dlc', 0xF if enable_fdf else 0x8)
        testerMsg = self._isotp_config.testerDataTemplate.getCanMessage()
        testerMsg.ctrl.tx.FDF = enable_fdf
        testerMsg.ctrl.tx.BRS = enable_brs
        testerMsg.ctrl.tx.IDE = enable_ide
        testerMsg.ctrl.tx.DLC = dlc
        testerMsg.setMessageId(tester_msg_id)
        self._isotp_config.testerDataTemplate.setCanMessage(testerMsg)
        ecuMsg = self._isotp_config.ecuDataTemplate.getCanMessage()
        ecuMsg.ctrl.tx.FDF = enable_fdf
        ecuMsg.ctrl.tx.BRS = enable_brs
        ecuMsg.ctrl.tx.IDE = enable_ide
        ecuMsg.ctrl.tx.DLC = dlc
        ecuMsg.setMessageId(ecu_msg_id)
        self._isotp_config.ecuDataTemplate.setCanMessage(ecuMsg)
        padding = kwargs.get('padding', None)
        if padding is not None:
            self._isotp_config.paddingEnabled = 1
            self._isotp_config.paddingValue = ctypes.c_uint8(padding)
        else:
            self._isotp_config.paddingEnabled = 0


import os
import sys
import shutil
import time
import random
import torch
import logging
from pathlib import Path

import numpy as np
import statistic
from torch import multiprocessing
from torch.nn import functional as F
import nibabel as nib
from tensorboardX import SummaryWriter
from skimage.measure import label

def mkdir(path, level=2, create_self=True):
    """ Make directory for this path,
    level is how many parent folders should be created.
    create_self is whether create path(if it is a file, it should not be created)

    e.g. : mkdir('/home/parent1/parent2/folder', level=3, create_self=False),
    it will first create parent1, then parent2, then folder.

    :param path: string
    :param level: int
    :param create_self: True or False
    :return:
    """
    p = Path(path)
    if create_self:
        paths = [p]
    else:
        paths = []
    level -= 1
    while level != 0:
        p = p.parent
        paths.append(p)
        level -= 1

    for p in paths[::-1]:
        p.mkdir(exist_ok=True)

def seed_reproducer(seed=2022):
    """Reproducer for pytorch experiment.

    Parameters
    ----------
    seed: int, optional (default = 2020)
        Radnom seed.

    Example
    -------
    seed_reproducer(seed=2020).
    """
    random.seed(seed)
    os.environ["PYTHONHASHSEED"] = str(seed)
    np.random.seed(seed)
    torch.manual_seed(seed)
    if torch.cuda.is_available():
        torch.cuda.manual_seed(seed)
        torch.cuda.manual_seed_all(seed)#set all gpus seed
        torch.backends.cudnn.deterministic = True
        torch.backends.cudnn.benchmark = False#if input data type and channels' changes arent' large use it improve train efficient
        torch.backends.cudnn.enabled = True

def cutmix_config_log(save_path, tensorboard=False):
    writer = SummaryWriter(str(save_path), filename_suffix=time.strftime('_%Y-%m-%d_%H-%M-%S')) if tensorboard else None

    save_path = str(Path(save_path) / 'log.txt')
    formatter = logging.Formatter('%(levelname)s [%(asctime)s] %(message)s')

    logger = logging.getLogger(save_path.split('/')[-2])
    logger.setLevel(logging.INFO)

    handler = logging.FileHandler(save_path)
    handler.setFormatter(formatter)
    logger.addHandler(handler)

    sh = logging.StreamHandler(sys.stdout)
    handler.setFormatter(formatter)
    logger.addHandler(sh)

    return logger, writer

class AverageMeter(object):
    """Computes and stores the average and current value"""

    def __init__(self):
        self.reset()

    def reset(self):
        self.val = 0
        self.avg = 0
        self.sum = 0
        self.count = 0
        return self

    def update(self, val, n=1):
        self.val = val
        self.sum += val
        self.count += n
        self.avg = self.sum / self.count
        return self

class Measures():
    def __init__(self, keys, writer, logger):
        self.keys = keys
        self.measures = {k: AverageMeter() for k in self.keys}
        self.writer = writer
        self.logger = logger

    def reset(self):
        [v.reset() for v in self.measures.values()]

class CutPreMeasures(Measures):
    def __init__(self, writer, logger):
        keys = ['ce_loss', 'dice_loss', 'loss_all', 'train_dice']
        super(CutPreMeasures, self).__init__(keys, writer, logger)

    def update(self, out, lab, *args):
        args = list(args)
        masks = get_mask(out)
        train_dice1 = statistic.dice_ratio(masks, lab)
        args.append(train_dice1)

        dict_variables = dict(zip(self.keys, args))
        for k, v in dict_variables.items():
            self.measures[k].update(v)

    def log(self, epoch, step):
        # self.logger.info('epoch : %d, step : %d, train_loss: %.4f, train_dice: %.4f' % (
        #     epoch, step, self.measures['loss_all'].avg, self.measures['train_dice'].avg))

        log_string, params = 'Epoch : {}', []
        for k in self.keys:
            log_string += ', ' + k + ': {:.4f}'
            params.append(self.measures[k].val)
        self.logger.info(log_string.format(epoch, *params))

        for k, measure in self.measures.items():
            k = 'pretrain/' + k
            self.writer.add_scalar(k, measure.avg, step)
        self.writer.flush()

def get_mask(out, thres=0.5):
    probs = F.softmax(out, 1)
    masks = (probs >= thres).float()
    masks = masks[:, 1, :, :].contiguous()
    return masks

def save_net_opt(net, optimizer, path, epoch):
    state = {
        'net': net.state_dict(),
        'opt': optimizer.state_dict(),
        'epoch': epoch,
    }
    torch.save(state, str(path))

def load_net_opt(net, optimizer, path):
    state = torch.load(str(path))
    net.load_state_dict(state['net'])
    optimizer.load_state_dict(state['opt'])

def save_net(net, path):
    state = {
        'net': net.state_dict(),
    }
    torch.save(state, str(path))

def load_net(net, path):
    state = torch.load(str(path))
    net.load_state_dict(state['net'])

def generate_mask(img, patch_size):
    batch_l = img.shape[0]
    #batch_unlab = unimg.shape[0]
    loss_mask = torch.ones(batch_l, 96, 96, 96).cuda()
    #loss_mask_unlab = torch.ones(batch_unlab, 96, 96, 96).cuda()
    mask = torch.ones(96, 96, 96).cuda()
    w = np.random.randint(0, 96 - patch_size)
    h = np.random.randint(0, 96 - patch_size)
    z = np.random.randint(0, 96 - patch_size)
    mask[w:w+patch_size, h:h+patch_size, z:z+patch_size] = 0
    loss_mask[:, w:w+patch_size, h:h+patch_size, z:z+patch_size] = 0
    #loss_mask_unlab[:, w:w+patch_size, h:h+patch_size, z:z+patch_size] = 0
    #cordi = [w, h, z]
    return mask.long(), loss_mask.long()

def config_log(save_path, tensorboard=False):
    writer = SummaryWriter(str(save_path), filename_suffix=time.strftime('_%Y-%m-%d_%H-%M-%S')) if tensorboard else None

    save_path = str(Path(save_path) / 'log.txt')
    formatter = logging.Formatter('%(levelname)s [%(asctime)s] %(message)s')

    logger = logging.getLogger(save_path.split('/')[-2])
    logger.setLevel(logging.INFO)

    handler = logging.FileHandler(save_path)
    handler.setFormatter(formatter)
    logger.addHandler(handler)

    sh = logging.StreamHandler(sys.stdout)
    handler.setFormatter(formatter)
    logger.addHandler(sh)

    return logger, writer

class CutmixFTMeasures(Measures):
    def __init__(self, writer, logger):
        keys = ['mix_loss_lab', 'mix_loss_unlab', 'loss_all']
        super(CutmixFTMeasures, self).__init__(keys, writer, logger)

    def update(self, *args):
        args = list(args)
        # masks = get_mask(out[0])
        # train_dice = statistic.dice_ratio(masks, lab)
        # args.append(train_dice)

        dict_variables = dict(zip(self.keys, args))
        for k, v in dict_variables.items():
            self.measures[k].update(v)

    def log(self, epoch, step):
        # self.logger.info('epoch : %d, step : %d, train_loss: %.4f, train_dice: %.4f' % (
        #     epoch, step, self.measures['loss_all'].avg, self.measures['train_dice'].avg))

        log_string, params = 'Epoch : {}', []
        for k in self.keys:
            log_string += ', ' + k + ': {:.4f}'
            params.append(self.measures[k].val)
        self.logger.info(log_string.format(epoch, *params))

        for k, measure in self.measures.items():
            k = 'pretrain/' + k
            self.writer.add_scalar(k, measure.avg, step)
        self.writer.flush()

def to_cuda(tensors, device=None):
    res = []
    if isinstance(tensors, (list, tuple)):
        for t in tensors:
            res.append(to_cuda(t, device))
        return res
    elif isinstance(tensors, (dict,)):
        res = {}
        for k, v in tensors.items():
            res[k] = to_cuda(v, device)
        return res
    else:
        if isinstance(tensors, torch.Tensor):
            if device is None:
                return tensors.cuda()
            else:
                return tensors.to(device)
        else:
            return tensors

def get_cut_mask(out, thres=0.5, nms=True, connect_mode=1):
    probs = F.softmax(out, 1)
    masks = (probs >= thres).type(torch.int64)
    masks = masks[:, 1, :, :].contiguous()
    if nms==True:
        masks = LargestCC_pancreas(masks, connect_mode=connect_mode)
    return masks

def LargestCC_pancreas(segmentation, connect_mode=1):
    N = segmentation.shape[0]
    batch_list = []
    for n in range(N):
        n_prob = segmentation[n].detach().cpu().numpy()
        labels = label(n_prob, connectivity=connect_mode)
        if labels.max() != 0:
            largestCC = labels == np.argmax(np.bincount(labels.flat)[1:])+1
        else:
            largestCC = n_prob
        batch_list.append(largestCC)

    return torch.Tensor(batch_list).cuda()

@torch.no_grad()
def update_ema_variables(model, ema_model, alpha):
    for ema_param, param in zip(ema_model.parameters(), model.parameters()):
        ema_param.data.mul_(alpha).add_((1 - alpha) * param.data)


import pandas as pd
import numpy as np
from tensorflow.keras.models import model_from_json
from tensorflow.keras.preprocessing.image import load_img
from tensorflow.keras.preprocessing.image import img_to_array

df = pd.read_csv('../data/sample.csv')

# Model reconstruction from JSON file
with open('../data/model_architecture.json', 'r') as f:
    model = model_from_json(f.read())

# Load weights into the new model
model.load_weights('../data/model_weights.h5')

no_of_images = 15984
images = []

# Adding the images to array
for i in range(1, no_of_images + 1):
    image_name = '../data/test_images/f' + str(i) + '.png'
    image = load_img(image_name, target_size = (224,224), color_mode = "grayscale")
    image = img_to_array(image)
    images.append(image)

images = np.array(images)

# Making predictions on images
predictions = model.predict(images)

# Storing the predictions in dataframe
for i in range(len(predictions)):
    df['label'][i] = np.argmax(predictions[i])

# Generating output file
df.to_csv('../output/output.csv')


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sun May 21 13:23:27 2017

Plots two mass spectra on one set of axes and notates m/z of the peak(s)
with the highest relative intensity.

@author: emeryusher
"""

# import python modules for plotting etc.
import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import argrelextrema

# import files into two separate arrays (one is the control; one is the reaction)
temp1 = np.loadtxt('chloro_ref_rxnA_0_F3_1.txt')
temp2 = np.loadtxt('chloro_ref_rxnC_0_F5_1.txt')

# normalize data set to the maximum intensity in the dataset
temp1[:,1] = temp1[:,1]/(np.amax(temp1[:,1]))
temp2[:,1] = temp2[:,1]/(np.amax(temp2[:,1]))

# determine local extrema; if you find that it picks too many peaks, increase
#   the value for "order"
max1 = argrelextrema(temp1[:,1], np.greater, order = 5000)
max2 = argrelextrema(temp2[:,1], np.greater, order = 5000)

#plot intensity versus m/z
plt.plot(temp1[:,0], temp1[:,1], color = "grey", linewidth = 1.0, label = 'H3K9R')
plt.plot(temp2[:,0], temp2[:,1], color = "k", linewidth = 1.0, label = 'H3K9RMe')

# enter the bounds to be used for picking the maxima to plot (m/z)
win1_max = 2300
win1_min = 2200

win2_max = 2400
win2_min = 2200

# pick extrema for each data set
for i in max1[0]:
    # Conditional statement to calculate maxima of points in a specfic range.
    # adds a m/z label for picked maxima
   if ((temp1[:,0][i] > win1_) and (temp1[:,0][i] < 2300 )):
       plt.annotate(str(temp1[:,0][i]), xy=(temp1[:,0][i], temp1[:,1][i]+0.1), horizontalalignment = 'center', fontsize = 8, rotation=45)

for i in max2[0]:
    # Conditional statement to calculate maxima of points in a specfic range.
    # adds a m/z label for picked maxima
    if ((temp2[:,0][i] > 2200 ) and (temp2[:,0][i] < 2400 )):
       plt.annotate(str(temp2[:,0][i]), xy=(temp2[:,0][i], temp2[:,1][i]+0.1), horizontalalignment = 'center', fontsize = 8, rotation=45)

## plotting stuff ##
plt.legend(loc='upper right')
plt.xlabel('m/z')
plt.ylabel('Intensity')
plt.title('H3K9R peptide methylation')
plt.xlim(2240, 2340)
plt.ylim([-0.05, 1.2])
plt.tight_layout()

# uncomment the following line to save spectrum plot
#plt.savefig('PRDM9_methylation.png', format = 'png', dpi = 300)
plt.show()


#!/usr/bin/env python3
from enum import Enum
from copy import deepcopy
import sys
import readline # make input() use readline <3

CODE_BASE_ADDR = 0x1000 # where code is loaded
MEMORY_SIZE = 0xFFFF # How big memory is

INSTR_PTR_LOC = 0x0
STACK_PTR_LOC = 0x1
BASE_PTR_LOC = 0x2

class InstructionFamily(Enum):
    IMM = 0
    ARTIH = 1
    JMP = 2

class Opcode(Enum):
    MI = 0x0
    MV = 0x1
    MD = 0x2
    LD = 0x3
    ST = 0x4
    AD = 0x5
    SB = 0x6
    ND = 0x7
    OR = 0x8
    XR = 0x9
    SR = 0xa
    SL = 0xb
    SA = 0xc
    JG = 0xd
    JL = 0xe
    JQ = 0xf

class Instruction:
    def __init__(self, address, opcode, *args):
        self.address = address
        self.opcode = Opcode(opcode)
        if self.opcode in [Opcode.MI]:
            self.family = InstructionFamily.IMM
            self.rm = args[0]
            self.imm = args[1]
            self.length = 2 # num words
        elif self.opcode in [Opcode.MV, Opcode.MD, Opcode.LD, Opcode.ST, \
                             Opcode.AD, Opcode.SB, Opcode.ND, Opcode.OR, \
                             Opcode.XR, Opcode.SR, Opcode.SL, Opcode.SA]:
            self.family = InstructionFamily.ARTIH
            self.rm = args[0]
            self.mem = args[1]
            self.length = 2 # num words
        elif self.opcode in [Opcode.JG, Opcode.JL, Opcode.JQ]:
            self.family = InstructionFamily.JMP
            self.rm = args[0]
            self.mem = args[1]
            self.label = args[2]
            self.length = 3 # num words
        else:
            raise NotImplemented('WHAT EVEN THATS NOT A POSSIBLE OPCODE: {:x}'.format(self.opcode))

    def mnemonic(self):
        mnemonics = {
            Opcode.MI: 'MI',
            Opcode.MV: 'MV',
            Opcode.MD: 'MD',
            Opcode.LD: 'LD',
            Opcode.ST: 'ST',
            Opcode.AD: 'AD',
            Opcode.SB: 'SB',
            Opcode.ND: 'ND',
            Opcode.OR: 'OR',
            Opcode.XR: 'XR',
            Opcode.SR: 'SR',
            Opcode.SL: 'SL',
            Opcode.SA: 'SA',
            Opcode.JG: 'JG',
            Opcode.JL: 'JL',
            Opcode.JQ: 'JQ'
        }
        mnemonic = mnemonics[self.opcode]
        if mnemonic == 'JQ' and self.rm == 0x0 and self.mem == 0x0 and self.address == self.label:
            mnemonic = 'HF' # special case for halt-and-catch-fire, which is a specialization of jmp to self
        return mnemonic

    def __repr__(self):
        if self.family == InstructionFamily.IMM:
            return 'Instruction(0x{:x}, 0x{:x}, [0x{:x}, 0x{:x}])'.format( \
                    self.address, self.opcode, \
                    self.rm, self.imm)
        elif self.family == InstructionFamily.ARTIH:
            return 'Instruction(0x{:x}, 0x{:x}, [0x{:x}, 0x{:x}])'.format( \
                    self.address, self.opcode, \
                    self.rm, self.mem)
        elif self.family == InstructionFamily.JMP:
            return 'Instruction(0x{:x}, 0x{:x}, [0x{:x}, 0x{:x}, 0x{:x}])'.format( \
                    self.address, self.opcode, \
                    self.rm, self.mem, self.label)
        else:
            raise NotImplemented('What even instruction did you give me')

    def __str__(self):
        """
        If you want a prettier version, use .nice_str
        """
        if self.family == InstructionFamily.IMM:
            return '{} 0x{:x}, 0x{:x}'.format(self.mnemonic(), self.rm, self.imm)
        elif self.family == InstructionFamily.ARTIH:
            return '{} 0x{:x}, 0x{:x}'.format(self.mnemonic(), self.rm, self.mem)
        elif self.family == InstructionFamily.JMP:
            if self.opcode == Opcode.JQ and self.rm == 0x0 and self.mem == 0x0 and self.address == self.label:
                return 'HF' # special case for halt-and-catch-fire
            return '{} 0x{:x}, 0x{:x}, 0x{:x}'.format(self.mnemonic(), self.rm, self.mem, self.label)

    def nice_str(self, symbol_fn):
        """
        symbol_fn takes an address and returns a pretty string for it.
        """
        if self.family == InstructionFamily.IMM:
            return '{} {}, {}'.format(self.mnemonic(), symbol_fn(self.rm), symbol_fn(self.imm))
        elif self.family == InstructionFamily.ARTIH:
            return '{} {}, {}'.format(self.mnemonic(), symbol_fn(self.rm), symbol_fn(self.mem))
        elif self.family == InstructionFamily.JMP:
            if self.opcode == Opcode.JQ and self.rm == 0x0 and self.mem == 0x0 and self.address == self.label:
                return 'HF' # special case for halt-and-catch-fire
            return '{} {}, {}, {}'.format(self.mnemonic(), symbol_fn(self.rm), symbol_fn(self.mem), symbol_fn(self.label))

    @classmethod
    def decode(cls, address, instruction_memory):
        opcode = (instruction_memory[0] >> 12) & 0xF
        args = []
        args.append(instruction_memory[0] & 0xFFF)
        args.append(instruction_memory[1])
        args.append(instruction_memory[2])
        return cls(address, opcode, *args)

class InvalidAccess(Exception):
    """
    Quick helper for invalid accesses
    """
    pass

def invalid_access(state, addr, *args):
    """
    Interrupt to represent things as invalid
    """
    raise InvalidAccess('Cannot read/write memory at addr {:x}'.format(addr))

def getchar_interrupt(state, addr, *args):
    """
    getchar interrupt
    """
    return state.get_input()

def putchar_interrupt(state, addr, *args):
    """
    putchar interrupt
    """
    char = args[0]
    state.add_output(chr(char))

class BreakpointHit(Exception):
    """
    Raise when a bp is hit
    """
    pass

class Memory:
    def __init__(self, memory):
        self.memory = memory
        self.state = None # fill this in l8r

    def __getitem__(self, key):
        if not isinstance(key, slice) and \
                key in self.state.read_interrupts:
            return self.state.read_interrupts[key](self.state, key)
        return self.memory[key]

    def __setitem__(self, key, value):
        if key in self.state.write_interrupts:
            self.state.write_interrupts[key](self.state, key, value)
            return
        self.memory[key] = value

class State:
    def __init__(self, memory):
        self.memory = memory
        self.halt = False # is cpu halted
        # addr read -> function to call for value to be read
        self.read_interrupts = {
            0x200: invalid_access, # reading output register
            0x201: getchar_interrupt, # getchar
            0x202: invalid_access,  # gen key write
            0x203: None,  # gen key read
            0x204: invalid_access,  # load key write
            0x205: None,  # load key read
            0x206: invalid_access,  # mul write
            0x207: None,  # mul read
            0x208: None,  # rng
            0x209: invalid_access,  # set timeout
            0x20A: None,  # timeout addr
        }
        # addr written -> function to call with writen value
        self.write_interrupts = {
            0x200: putchar_interrupt, # putchar
            0x201: invalid_access, # writing input register
            0x202: None,  # gen key write
            0x203: invalid_access,  # gen key read
            0x204: None,  # load key write
            0x205: invalid_access,  # load key read
            0x206: None,  # mul write
            0x207: invalid_access,  # mul read
            0x208: invalid_access,  # rng
            0x209: None,  # set timeout
            0x20A: None,  # timeout addr
        }
        self.all_input = ''
        self.all_output = ''

    def decode_instruction_at(self, addr):
        instr_memory = self.memory[addr : addr + 3] # we need 3 words for jmp family instructions
        return Instruction.decode(addr, instr_memory)

    def instruction_pointer(self):
        return self.memory[INSTR_PTR_LOC]

    def stack_pointer(self):
        return self.memory[STACK_PTR_LOC]

    def step(self):
        ip = self.instruction_pointer()
        instr = self.decode_instruction_at(ip)
        next_ip = self.instruction_pointer() + instr.length
        self.memory[INSTR_PTR_LOC] = next_ip # advance ip
        if instr.opcode == Opcode.MI:
            self.memory[instr.rm] = instr.imm
        elif instr.opcode == Opcode.MV:
            self.memory[instr.rm] = self.memory[instr.mem]
        elif instr.opcode == Opcode.MD:
            self.memory[instr.rm] = self.memory[self.memory[instr.mem]]
        elif instr.opcode == Opcode.LD:
            self.memory[self.memory[instr.rm]] = self.memory[instr.mem]
        elif instr.opcode == Opcode.ST:
            self.memory[self.memory[instr.mem]] = self.memory[instr.rm]
        elif instr.opcode == Opcode.AD:
            self.memory[instr.rm] += self.memory[instr.mem]
        elif instr.opcode == Opcode.SB:
            self.memory[instr.rm] -= self.memory[instr.mem]
        elif instr.opcode == Opcode.ND:
            self.memory[instr.rm] &= self.memory[instr.mem]
        elif instr.opcode == Opcode.OR:
            self.memory[instr.rm] |= self.memory[instr.mem]
        elif instr.opcode == Opcode.XR:
            self.memory[instr.rm] ^= self.memory[instr.mem]
        elif instr.opcode == Opcode.SR:
            self.memory[instr.rm] >>= self.memory[instr.mem]
        elif instr.opcode == Opcode.SL:
            self.memory[instr.rm] <<= self.memory[instr.mem]
        elif instr.opcode == Opcode.SA:
            rm = self.memory[instr.rm]
            mem = self.memory[instr.mem]
            to_signed = lambda x: int.from_bytes(x.to_bytes(2, 'little'), 'little', True)
            to_unsigned = lambda x: int.from_bytes(x.to_bytes(2, 'little', True), 'little')
            rm = to_signed(rm)
            res = rm >> mem
            memory[rm] = to_unsigned(rm)
        elif instr.opcode == Opcode.JG:
            if self.memory[instr.rm] > self.memory[instr.mem]:
                self.memory[INSTR_PTR_LOC] = instr.label
        elif instr.opcode == Opcode.JL:
            if self.memory[instr.rm] < self.memory[instr.mem]:
                self.memory[INSTR_PTR_LOC] = instr.label
        elif instr.opcode == Opcode.JQ:
            if instr.rm == 0 and instr.mem == 0 and instr.label == ip:
                # halt-and-catch-fire
                self.cpu_abort()
            elif self.memory[instr.rm] == self.memory[instr.mem]:
                self.memory[INSTR_PTR_LOC] = instr.label

    def run(self):
        while not self.halt:
            instr = self.decode_instruction_at(self.instruction_pointer())
            self.step()

    def cpu_abort(self):
        self.halt = True

    def get_input(self):
        char = sys.stdin.read(1)
        self.all_input += char
        return ord(char)

    def add_output(self, value):
        self.all_output += value
        sys.stdout.write(value)
        sys.stdout.flush()

    @classmethod
    def from_file(cls, filename):
        with open(filename, 'rb') as f:
            contents = f.read()

        # reinterpret contents as an array of little-endian words
        code = []
        for i in range(0, len(contents), 2):
            mem = contents[i : i+2]
            word = int.from_bytes(mem, 'little')
            code.append(word)

        # memory space, all 0's to start
        memory = [0 for _ in range(MEMORY_SIZE+1)]

        # initialize stack ptr
        memory[STACK_PTR_LOC] = 0x300
        # initialize instruction ptr
        memory[INSTR_PTR_LOC] = 0x1000

        # initialize code
        for offset, word in enumerate(code):
            memory[CODE_BASE_ADDR + offset] = word

        st = State(Memory(memory))
        st.memory.state = st
        return st

class InteractiveDebugger:
    """
    An interactive debugger.

    Commands:
    again: repeat last command (just hitting return also does this)
    r: run, start the program if not running
    s, ni, n: single step.
        - Takes argument of number of instructions to step (default 1)
    c: run until breakpoint.
    b: break at address.
        - for example, b 0x1234 creates a breakpoint at the instruction 0x1234
    p: print expression. Takes a format specifier, defaulting to "word"
        - Format specifiers come in the form p/NX,
          where N is a number of consecutive version of the argument type to print,
          and X is the specifier.
          supports the following specifiers:
            w, x: word
            c: character
            i: instruction
    load-labels: Load labels from a file (argument required)

    Expressions: **TODO**
    right now just hex numbers for an addr haha
    """
    def __init__(self, state):
        self.initial_state = state
        self.state = None
        self.running = False

        self.symbols = {
            INSTR_PTR_LOC: 'IP',
            STACK_PTR_LOC: 'SP',
            0x3: 'SC0',
            0x4: 'SC1',
            0x200: 'OUTPUT',
            0x201: 'INPUT',
        }
        # rNN registers
        for i, x in enumerate(range(0x10, 0x40)):
            name = 'r{:02x}'.format(i)
            self.symbols[x] = name

        # sNN registers
        for i, x in enumerate(range(0x40, 0x100)):
            name = 's{:02x}'.format(i)
            self.symbols[x] = name

        self.breakpoints = {} # bp number -> bp addr
        self.highest_breakpoint_num = 0 # breakpoint #s monotonically increment

        self.last_command = ''

        # commands to run always
        self.autocmds = [
            #'p/10i *$ip', # instruction leadup
        ]

        self.watch_addrs = [INSTR_PTR_LOC, STACK_PTR_LOC]

    def input_loop(self):
        while True:
            self.print_banner()
            self.handle_input()

    def handle_input(self):
        """
        Handle getting input, parsing it, executing commands
        """
        inp = input('ctdbg> ')
        self.runcmd(inp)

    def runcmd(self, cmd, user=True):
        def print_stuff(num, specifier, loc):
            specifiers = {
                'x': lambda addr: hex(self.state.memory[addr]),
                'c': lambda addr: bytes([self.state.memory[addr]]),
                'i': lambda addr: hex(addr) + ': ' + self.state.decode_instruction_at(addr).nice_str(self.nice_format_addr),
            }
            specifiers['w'] = specifiers['x'] # w = x

            joinchrs = {
                'x': ' ',
                'c': b'',
                'i': '\n',
            }
            joinchrs['w'] = joinchrs['x'] # ditto to above

            try:
                fmt_fn = specifiers[specifier]
                # gather all outs into this nice lil array
                outs = []
                offset = 0
                for i in range(num):
                    addr = loc + offset
                    if specifier != 'i':
                        offset += 1
                    else:
                        offset += self.state.decode_instruction_at(addr).length
                    outs.append((addr, fmt_fn(addr)))
                #TODO: decide ways of formatting based on length
                out = joinchrs[specifier] + joinchrs[specifier].join(y for x,y in outs)
                if specifier == 'c': # get a repr for non-printables :)
                    out = repr(out)
                return out
            except Exception as e:
                print("err> Error formatting:", e)

        def step(n):
            if not self.running:
                self.restart()

            if self.state.halt:
                print('err> STATE HALTED, USE r TO RESTART')
                return

            for _ in range(n):
                self.state.step()

        def run():
            self.restart()
            self.run()

        def add_watch(addr):
            self.watch_addrs.append(addr)
            return 'Added a watchpoint for {:x}'.format(addr)

        cmd_dict = {
            'again': lambda: self.runcmd(self.last_command),
            'r': lambda: run(), # different then self.run
            's': lambda n: step(n),
            'c': lambda: self.run(),
            'b': lambda target: self.add_breakpoint(target),
            'p': lambda num, specifier, loc: print_stuff(num, specifier, loc),
            'd': lambda num: self.del_breakpoint(num),
            'watch': add_watch,
            'load-labels': lambda filename: self.load_symbols_from_file(filename),
        }

        try:
            parsed = self.parse_command(cmd)
            cmd_fn = cmd_dict[parsed[0]]
            args = parsed[1:]
            res = cmd_fn(*args)

            if res:
                print('out>', res)

            # only set last_command if user-initiated and not a repeat command
            if user and cmd not in {'again', ''}:
                self.last_command = cmd
        except ValueError as e:
            print('err> Unknown command:', cmd)
            print(e)

    def run(self):
        if not self.running:
            self.restart()

        try:
            while not self.state.halt:
                self.state.step()
                # bp check
                if self.state.instruction_pointer() in self.breakpoints.values():
                    raise BreakpointHit()
        except BreakpointHit:
            print('out> breakpoint hit!!')
        except KeyboardInterrupt:
            print('out> paused!!')

        if self.state.halt:
            self.running = False
            print('out> program hlt!!')

    def nice_format_addr(self, addr):
        """
        Format an address in the nicest way we can figure out
        """
        if addr in self.symbols:
            return '{} (0x{:x})'.format(self.symbols[addr], addr)

        return hex(addr)

    def print_banner(self):
        """
        Print a banner of watched variables, plus some other info
        (if cpu is halted, upcoming instructions, etc)
        """
        print('<===================')
        if self.state:
            for addr in self.watch_addrs:
                nice_addr, val = self.nice_format_addr(addr), self.state.memory[addr]
                print('{} = {:x}'.format(nice_addr, val))

            if self.state.halt:
                print('CPU HALTED')

            print('\n====================\n')

            for cmd in self.autocmds:
                try:
                    self.runcmd(cmd, user=False)
                except Exception as e:
                    pass
        else:
            print('Not running!')
        print('===================>')

    def parse_command(self, cmd):
        operation = cmd.split(' ')[0]
        arg = ' '.join(cmd.split(' ')[1:])
        if operation == '' or operation == 'again':
            return ('again',) # do last command again
        elif operation == 'r':
            return ('r',)
        elif operation in {'s', 'ni', 'n'}:
            if arg:
                arg = self.parse_expression(arg)
            else:
                arg = 1
            return ('s', 1)
        elif operation == 'c':
            return ('c',)
        elif operation == 'b':
            if not arg:
                raise ValueError('Argument required for b command')
            return ('b', self.parse_expression(arg))
        elif operation == 'watch':
            if not arg:
                raise ValueError('Argument required for watch command')
            return ('watch', self.parse_expression(arg))
        elif operation[0] in {'p', 'x'}:
            if '/' in operation:
                p_len = operation[operation.index('/') + 1 : -1]
                if p_len:
                    p_len = int(p_len)
                else:
                    p_len = 1
                p_specifier = operation[-1]
            else:
                p_len = 1
                p_specifier = 'w'
            return ('p', p_len, p_specifier, self.parse_expression(arg))
        elif operation == 'load-labels':
            if arg:
                return ('load-labels', arg)
            raise ValueError('Argument required for load-labels command')
        else:
            raise ValueError('Unknown command!')

    def parse_expression(self, expression):
        #TODO: * for deref, + and -
        # TODO: better gooder parsing?
        expression = expression.lower()
        for addr, name in self.symbols.items():
            expression = expression.replace('$' + name.lower(), hex(addr))
        needs_deref = False
        if expression[0] == '*':
            expression = expression[1:]
            needs_deref = True
        val = int(expression, 16)
        if needs_deref:
            val = self.state.memory[val]
        return val

    def add_breakpoint(self, addr):
        max_bp = self.highest_breakpoint_num
        bp_num = max_bp + 1
        self.breakpoints[bp_num] = addr
        self.highest_breakpoint_num += 1
        return bp_num

    def del_breakpoint(self, num):
        self.breakpoints.pop(num)

    def restart(self):
        """
        Restart the program under test (basically the `r` command)
        """
        self.state = deepcopy(self.initial_state)
        self.running = True

    def load_symbols_from_file(self, filename):
        new_symbols = {}
        with open(filename, 'r') as f:
            for line in f:
                if line.strip():
                    addr, name = line.split(':')
                    addr = int(addr, 0)
                    name = name.strip()
                    new_symbols[addr] = name
        print('Loaded {} symbols'.format(len(new_symbols)))
        self.symbols.update(new_symbols)

def main(argv):
    if len(argv) != 2:
        print('ERROR: ROM argument required!')
        return

    st = State.from_file(argv[1])
    dbg = InteractiveDebugger(st)
    dbg.runcmd('load-labels symbols')
    dbg.input_loop()

if __name__ == '__main__':
    main(sys.argv)


try:
    from setuptools import setup, find_packages
except ImportError:
    from distutils.core import setup

config = {
    'description': 'SNAPS OpenStack Installer',
    'author': 'Steve Pisarski',
    'url': 'https://github.com/cablelabs/snaps-openstack',
    'download_url': 'https://github.com/cablelabs/snaps-openstack/archive/master.zip',
    'author_email': 's.pisarski@cablelabs.com',
    'version': '1.0',
    'packages': find_packages(),
    'install_requires': ['ansible==2.7.10',
                         'pathlib',
                         'six',
                         'pyyaml'],
    'scripts': [],
    'name': 'snaps-openstack'
}

setup(**config)


from termcolor import cprint
from tkinter import *
from ttkthemes import themed_tk
from tkinter import ttk , messagebox, filedialog
from PIL import Image, ImageTk

vendara = ['Vendara', 14]
root = themed_tk.ThemedTk()
root.geometry('900x600+500+200')
root.title('Admission-helper: Administrator Version')
root.set_theme('plastik')

# Functions
def callback():
    print(name_var.get())
    print(age_var.get())
    æ = parent_var.get().split(',')
    ś = []
    for ā in æ:
        if ā.replace(' ','') != '':
            ś.append(ā.replace(' ', ''))
    del æ
    æ = ś
    del ś
    print(æ)
    messagebox.showinfo('Info!', 'Admission succesfully added!')

def parents():
    messagebox.showinfo('Help', 'Parent name(s) seperated by commas(spaces not allowed!)\n\nexample:\n\n    parent.A, parent.B')

# Vars
name_var = StringVar()
age_var = IntVar()
age_var.set(6)
parent_var = StringVar()
parent_info = ImageTk.PhotoImage(image=Image.open('assets/icons/info-sign-icon.png'))

min_age = 6
max_age = 18
ages = []

for i in range(min_age, max_age + 1):
    ages.append(i)

# Buttons
submit_btn = ttk.Button(root, text='Submit', command=callback, width=12)
btn_pname_info = Button(root, image=parent_info, border=0, command=parents)

# Labels
lbl_sname = ttk.Label(root, font=vendara, text='Student Full Name:', )
lbl_sage = ttk.Label(root, font=vendara, text='Student Age:')
lbl_pname = ttk.Label(root, font=vendara, text='Parent Name(s):')

# Entrys
ent_sname = ttk.Entry(root, font=vendara, textvariable=name_var ,width=50)
ent_sage = ttk.Spinbox(root, font=vendara, textvariable=age_var ,width=48, values=ages, state='readonly')
ent_pname = ttk.Entry(root, font=vendara, textvariable=parent_var, width=50)

# grid
lbl_sname.grid(row=0, column=0)
ent_sname.grid(row=0, column=1, pady=10)
lbl_sage.grid(row=1, column=0)
ent_sage.grid(row=1, column=1)
lbl_pname.grid(row=2, column=0)
ent_pname.grid(row=2, column=1, pady=10)
btn_pname_info.grid(row=2, column=2, ipadx=10)

submit_btn.grid(row=3, column=0)

root.resizable(False, False)

# Mainloop
if __name__ == '__main__':
    root.mainloop()


from decimal import Decimal

from django.db import models
from django_countries.fields import CountryField

class Partner(models.Model):
    uid = models.AutoField(primary_key=True)
    partner_id = models.CharField(
        max_length=3,
        unique=True,
        error_messages={"unique": "This Partner ID is already in use."},
    )
    company = models.CharField(max_length=64, unique=True)
    contact_name = models.CharField(max_length=64)
    contact_email = models.EmailField()
    contact_phone = models.CharField(
        max_length=16,
        blank=True,
        help_text="Must have only digits and an optional country code prefixed with a plus sign",
    )
    address1 = models.CharField(max_length=48, help_text="Street address, P.O. box")
    address2 = models.CharField(
        max_length=32, blank=True, help_text="Apartment, suite, unit, building, floor"
    )
    city = models.CharField(max_length=32)
    state = models.CharField(
        max_length=32, help_text="Should use 2 letter abbreviations for U.S. states"
    )
    zipcode = models.CharField(max_length=16)
    country = CountryField(blank_label="")
    notes = models.TextField(blank=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ["company"]

    def __str__(self):
        return self.company

    def get_pretty_contact_phone(self):
        if len(self.contact_phone) == 10:
            return f"({self.contact_phone[:3]}) {self.contact_phone[3:6]}-{self.contact_phone[6:10]}"
        elif len(self.contact_phone) in [12, 13] and self.contact_phone[0] == "+":
            return f"{self.contact_phone[:-10]} ({self.contact_phone[-10:-7]}) {self.contact_phone[-7:-4]}-{self.contact_phone[-4:]}"
        else:
            return self.contact_phone

    def get_address1(self):
        address = self.address1
        if self.address2:
            address += ", " + self.address2
        return address

    def get_address2(self):
        address = self.city
        address += ", " + self.state
        address += " " + self.zipcode
        return address

    def get_statistics(self):
        statistics = {
            "non_void_invoices_count": self.invoices.exclude(status=4).count()
        }

        # The total amount of money this partner has been billed for
        statistics["total_billed"] = Decimal("0.00")
        for invoice in self.invoices.exclude(status=4).exclude(status=0):
            statistics["total_billed"] += invoice.get_total()

        return statistics

    def get_last_invoice(self):
        return self.invoices.exclude(status=4).exclude(status=0).last()


from argparse import ArgumentParser
from time import sleep
from src.netreq import setContractAddress, requestPrice, requestSymbol
from src.grapher import setGraphSymbol, startGraphThread,addPrice, initanim
from src.contracts import contract_list
import threading

def priceThread():
    while True:
        price = requestPrice()
        if price is not None:
            addPrice(price)
        else:
            print("An error occured while trying to get the price for token")
        sleep(4) # As observed from Trader Joe's request intervals

if __name__ == "__main__":
    parser = ArgumentParser(
        prog="acpy",
        description="A python script that utilizes graphql traderjoe subgraph to pull prices from Avalanche's C-Chain tokens")
    parser.add_argument("-c", "--contract", help="Address of the contract present on the C-Chain")
    parser.add_argument("--token", "-t", choices=contract_list.keys(), required=False, default="PNG", help="Use a built in contract address if you prefer")

    args = parser.parse_args()
    if args.contract is None and args.token is None:
        parser.print_help()
        exit(0)
    contract_addr = ""
    if args.token is not None:
        contract_addr = contract_list[args.token]
    else:
        contract_addr = args.contract
    symbol = setContractAddress(contract_addr)

    if symbol is None:
        print("Error while getting the contract symbol.")
        exit(1)

    setGraphSymbol(symbol)
    initanim()
    pricethread = threading.Thread(target=priceThread)
    pricethread.start()
    startGraphThread()


# BOJ_18870
# 좌표 압축

import sys

def solution():
    n = int(sys.stdin.readline())
    arr = [[i] for i in range(n)]
    in_arr = list(map(int, sys.stdin.readline().split()))
    for i in range(n):
        arr[i].append(in_arr[i])
        arr[i].append(0)

    arr.sort(key=lambda x: x[1])

    for i in range(1, n):
        if arr[i][1] > arr[i - 1][1]:
            arr[i][2] = arr[i - 1][2] + 1
        else:
            arr[i][2] = arr[i - 1][2]

    arr.sort()
    for i in arr:
        print(i[2], end=' ')

if __name__ == "__main__":
    solution()


import sys
filename = sys.argv[1]
lines = []
with open(filename) as f:
    lines = f.read().splitlines()

print("starting part1")

def unique(pkt,sze):
    i = 0
    while i < len(pkt)-sze:
        if len(set(pkt[i:i+sze])) == sze:
            return i+sze
        i+=1
    return(-1)

for pkt in lines:
    print(unique(pkt,4))

print("starting part2")

for pkt in lines:
    print(unique(pkt,14))