"""
    @author: ADSL007 from ustc
    mindspore version of inception v4 described in http://arxiv.org/abs/1602.07261.

"""
import mindspore.nn as nn
from mindspore import Tensor
from mindspore.ops import operations as P
from mindspore.common.initializer import Initializer
import numpy as np

class avginitializer(Initializer):
    """
    Initialize the weight to 1/m*n,  (m, n) is the shape of kernel.
    """
    def __init__(self):
        super(avginitializer, self).__init__()

    def _initialize(self, arr):
        arr[:] = 0
        for i in range(arr.shape[0]):
            for j in range(arr.shape[2]):
                for k in range(arr.shape[3]):
                    arr[i][i][j][k] = 1/(arr.shape[2]*arr.shape[3])

class Avgpool(nn.Cell):
    """
    Average pooling for temporal data.

    Using a custom initializer to turn conv2d into avgpool2d. The weights won't be trained.

    """
    def __init__(self, channel, kernel_size, stride=1, pad_mode='same'):
        super(Avgpool, self).__init__()
        self.init = avginitializer()
        self.conv = nn.Conv2d(channel, channel, kernel_size,
                              stride=stride, pad_mode=pad_mode, weight_init=self.init)
        self.conv.set_train(False)

    def construct(self, x):
        x = self.conv(x)
        return x

class Conv2d(nn.Cell):
    """
    Set the default configuration for Conv2dBnAct
    """
    def __init__(self, in_channels, out_channels, kernel_size, stride=1, pad_mode='valid', padding=0,
                                    has_bias=False, weight_init="XavierUniform", bias_init='zeros'):
        super(Conv2d, self).__init__()
        self.conv = nn.Conv2dBnAct(in_channels, out_channels, kernel_size, stride=stride, pad_mode=pad_mode, padding=padding,
                                    weight_init=weight_init, bias_init=bias_init, has_bias=has_bias, has_bn=True, activation="relu")

    def construct(self, x):
        x = self.conv(x)
        return x

class Stem(nn.Cell):
    """
    Inceptionv4 stem

    """
    def __init__(self, in_channels):
        super(Stem, self).__init__()
        self.conv2d_1a_3x3 = Conv2d(
            in_channels, 32, 3, stride=2, padding=0, has_bias=False)

        self.conv2d_2a_3x3 = Conv2d(
            32, 32, 3, stride=1, padding=0, has_bias=False)
        self.conv2d_2b_3x3 = Conv2d(
            32, 64, 3, stride=1, pad_mode='pad', padding=1, has_bias=False)

        self.mixed_3a_branch_0 = nn.MaxPool2d(3, stride=2)
        self.mixed_3a_branch_1 = Conv2d(
            64, 96, 3, stride=2, padding=0, has_bias=False)

        self.mixed_4a_branch_0 = nn.SequentialCell([
            Conv2d(160, 64, 1, stride=1, padding=0, has_bias=False),
            Conv2d(64, 96, 3, stride=1, padding=0,  pad_mode='valid', has_bias=False)]
        )
        self.mixed_4a_branch_1 = nn.SequentialCell([
            Conv2d(160, 64, 1, stride=1, padding=0, has_bias=False),
            Conv2d(64, 64, (1, 7), pad_mode='same', stride=1,
                   has_bias=False),
            Conv2d(64, 64, (7, 1), pad_mode='same', stride=1, has_bias=False),
            Conv2d(64, 96, 3, stride=1, padding=0,  pad_mode='valid', has_bias=False)]
        )

        self.mixed_5a_branch_0 = Conv2d(
            192, 192, 3, stride=2, padding=0, has_bias=False)
        self.mixed_5a_branch_1 = nn.MaxPool2d(3, stride=2)
        self.concat0 = P.Concat(1)
        self.concat1 = P.Concat(1)
        self.concat2 = P.Concat(1)

    def construct(self, x):
        x = self.conv2d_1a_3x3(x)  # 149 x 149 x 32
        x = self.conv2d_2a_3x3(x)  # 147 x 147 x 32
        x = self.conv2d_2b_3x3(x)  # 147 x 147 x 64

        x0 = self.mixed_3a_branch_0(x)
        x1 = self.mixed_3a_branch_1(x)
        x = self.concat0((x0, x1))  # 73 x 73 x 160

        x0 = self.mixed_4a_branch_0(x)
        x1 = self.mixed_4a_branch_1(x)
        x = self.concat1((x0, x1))  # 71 x 71 x 192

        x0 = self.mixed_5a_branch_0(x)
        x1 = self.mixed_5a_branch_1(x)
        x = self.concat2((x0, x1))  # 35 x 35 x 384
        return x

class Inception_A(nn.Cell):
    def __init__(self, in_channels):
        super(Inception_A, self).__init__()
        self.branch_0 = Conv2d(
            in_channels, 96, 1, stride=1, padding=0, has_bias=False)
        self.branch_1 = nn.SequentialCell([
            Conv2d(in_channels, 64, 1, stride=1, padding=0, has_bias=False),
            Conv2d(64, 96, 3, stride=1, pad_mode='pad', padding=1, has_bias=False)]
        )
        self.branch_2 = nn.SequentialCell([
            Conv2d(in_channels, 64, 1, stride=1, padding=0, has_bias=False),
            Conv2d(64, 96, 3, stride=1, pad_mode='pad',
                   padding=1, has_bias=False),
            Conv2d(96, 96, 3, stride=1, pad_mode='pad', padding=1, has_bias=False), ]
        )
        self.branch_3 = nn.SequentialCell([
            Avgpool(384, kernel_size=3, stride=1, pad_mode='same'),
            Conv2d(384, 96, 1, stride=1, padding=0, has_bias=False)]
        )
        self.concat = P.Concat(1)

    def construct(self, x):
        x0 = self.branch_0(x)
        x1 = self.branch_1(x)
        x2 = self.branch_2(x)
        x3 = self.branch_3(x)
        x4 = self.concat((x0, x1, x2, x3))
        return x4

class Inception_B(nn.Cell):
    def __init__(self, in_channels):
        super(Inception_B, self).__init__()
        self.branch_0 = Conv2d(in_channels, 384, 1,
                               stride=1, padding=0, has_bias=False)
        self.branch_1 = nn.SequentialCell([
            Conv2d(in_channels, 192, 1, stride=1, padding=0, has_bias=False),
            Conv2d(192, 224, (1, 7), pad_mode='same',
                   stride=1, has_bias=False),
            Conv2d(224, 256, (7, 1), pad_mode='same',
                   stride=1, has_bias=False),
        ])
        self.branch_2 = nn.SequentialCell([
            Conv2d(in_channels, 192, 1, stride=1, padding=0, has_bias=False),
            Conv2d(192, 192, (7, 1), pad_mode='same',
                   stride=1, has_bias=False),
            Conv2d(192, 224, (1, 7), pad_mode='same',
                   stride=1, has_bias=False),
            Conv2d(224, 224, (7, 1), pad_mode='same',
                   stride=1, has_bias=False),
            Conv2d(224, 256, (1, 7), pad_mode='same', stride=1, has_bias=False)
        ])
        self.branch_3 = nn.SequentialCell([
            Avgpool(in_channels, kernel_size=3, stride=1, pad_mode='same'),
            Conv2d(in_channels, 128, 1, stride=1, padding=0, has_bias=False)
        ])
        self.concat = P.Concat(1)

    def construct(self, x):
        x0 = self.branch_0(x)
        x1 = self.branch_1(x)
        x2 = self.branch_2(x)
        x3 = self.branch_3(x)
        x4 = self.concat((x0, x1, x2, x3))
        return x4

class Reduction_A(nn.Cell):
    def __init__(self, in_channels, k, l, m, n):
        super(Reduction_A, self).__init__()
        self.branch_0 = Conv2d(in_channels, n, 3, stride=2, padding=0)
        self.branch_1 = nn.SequentialCell([
            Conv2d(in_channels, k, 1, stride=1, padding=0, has_bias=False),
            Conv2d(k, l, 3, stride=1, pad_mode='pad',
                   padding=1, has_bias=False),
            Conv2d(l, m, 3, stride=2, padding=0, has_bias=False),
        ])
        self.branch_2 = nn.MaxPool2d(3, stride=2)
        self.concat = P.Concat(1)

    def construct(self, x):
        x0 = self.branch_0(x)
        x1 = self.branch_1(x)
        x2 = self.branch_2(x)
        x3 = self.concat((x0, x1, x2))
        return x3         # 17 x 17 x 1024

class Reduction_B(nn.Cell):
    def __init__(self, in_channels):
        super(Reduction_B, self).__init__()
        self.branch_0 = nn.SequentialCell([
            Conv2d(in_channels, 192, 1, stride=1, padding=0, has_bias=False),
            Conv2d(192, 192, 3, stride=2, padding=0, has_bias=False),
        ])
        self.branch_1 = nn.SequentialCell([
            Conv2d(in_channels, 256, 1, stride=1, padding=0, has_bias=False),
            Conv2d(256, 256, (1, 7), pad_mode='same',
                   stride=1, has_bias=False),
            Conv2d(256, 320, (7, 1), pad_mode='same',
                   stride=1, has_bias=False),
            Conv2d(320, 320, 3, stride=2, padding=0, has_bias=False)
        ])
        self.branch_2 = nn.MaxPool2d(3, stride=2)
        self.concat = P.Concat(1)

    def construct(self, x):
        x0 = self.branch_0(x)
        x1 = self.branch_1(x)
        x2 = self.branch_2(x)
        x3 = self.concat((x0, x1, x2))
        return x3     # 8 x 8 x 1536

class Inception_C(nn.Cell):
    def __init__(self, in_channels):
        super(Inception_C, self).__init__()
        self.branch_0 = Conv2d(in_channels, 256, 1,
                               stride=1, padding=0, has_bias=False)

        self.branch_1 = Conv2d(in_channels, 384, 1,
                               stride=1, padding=0, has_bias=False)
        self.branch_1_1 = Conv2d(
            384, 256, (1, 3), pad_mode='same', stride=1, has_bias=False)
        self.branch_1_2 = Conv2d(
            384, 256, (3, 1), pad_mode='same', stride=1, has_bias=False)

        self.branch_2 = nn.SequentialCell([
            Conv2d(in_channels, 384, 1, stride=1, padding=0, has_bias=False),
            Conv2d(384, 448, (3, 1), pad_mode='same',
                   stride=1, has_bias=False),
            Conv2d(448, 512, (1, 3), pad_mode='same',
                   stride=1, has_bias=False),
        ])
        self.branch_2_1 = Conv2d(
            512, 256, (1, 3), pad_mode='same', stride=1, has_bias=False)
        self.branch_2_2 = Conv2d(
            512, 256, (3, 1), pad_mode='same', stride=1, has_bias=False)

        self.branch_3 = nn.SequentialCell([
            Avgpool(in_channels, kernel_size=3, stride=1, pad_mode='same'),
            Conv2d(in_channels, 256, 1, stride=1, padding=0, has_bias=False)
        ])
        self.concat0 = P.Concat(1)
        self.concat1 = P.Concat(1)
        self.concat2 = P.Concat(1)

    def construct(self, x):
        x0 = self.branch_0(x)
        x1 = self.branch_1(x)
        x1_1 = self.branch_1_1(x1)
        x1_2 = self.branch_1_2(x1)
        x1 = self.concat0((x1_1, x1_2))
        x2 = self.branch_2(x)
        x2_1 = self.branch_2_1(x2)
        x2_2 = self.branch_2_2(x2)
        x2 = self.concat1((x2_1, x2_2))
        x3 = self.branch_3(x)
        return self.concat2((x0, x1, x2, x3))  # 8 x 8 x 1536

class Inceptionv4(nn.Cell):
    """
    Inceptionv4 architecture

    Args.
        is_train : in train mode, turn on the dropout.

    """
    def __init__(self, in_channels=3, classes=1000, k=192, l=224, m=256, n=384, is_train=True):
        super(Inceptionv4, self).__init__()
        blocks = []
        blocks.append(Stem(in_channels))
        for i in range(4):
            blocks.append(Inception_A(384))
        blocks.append(Reduction_A(384, k, l, m, n))
        for i in range(7):
            blocks.append(Inception_B(1024))
        blocks.append(Reduction_B(1024))
        for i in range(3):
            blocks.append(Inception_C(1536))
        self.features = nn.SequentialCell(blocks)

        self.avgpool = P.ReduceMean(keep_dims=False)
        self.softmax = nn.DenseBnAct(
            1536, classes, weight_init="XavierUniform", has_bias=True, has_bn=True, activation="logsoftmax")

        if is_train:
            self.dropout = nn.Dropout(0.20)
        else:
            self.dropout = nn.Dropout(1)
        self.bn0 = nn.BatchNorm1d(1536, eps=0.001, momentum=0.1)

    def construct(self, x):
        x = self.features(x)
        x = self.avgpool(x, (2, 3))
        x = self.bn0(x)
        x = self.dropout(x)
        x = self.softmax(x)
        return x


import PIL.Image
import tensorflow as tf
import numpy as np
import pandas as pd
from tensorflow import keras
from keras.preprocessing.image import ImageDataGenerator
import matplotlib.pyplot as plt
from keras.datasets import cifar10
from keras.layers import Dense, Dropout, Conv2D, MaxPool2D, Flatten, Input
from keras.models import Model
from PIL import Image, ImageDraw

def draw_rectangle(draw, p1, p2):
    draw.line([(p1[0], p1[1]),
               (p1[0], p2[1]),
               (p2[0], p2[1]),
               (p2[0], p1[1]),
               (p1[0], p1[1])], "yellow", 5)
    return img

img = Image.open(r'..\data\bild1.jpg')
img = img.resize((round(img.size[0]/10), round(img.size[1]/10)), resample=Image.Resampling.LANCZOS)
# img.rotate(90, expand=True)

#draw = ImageDraw.Draw(img)
draw = ImageDraw.Draw(img)
#img = draw_rectangle(draw, [50, 50], [150, 150])

# plt.imshow(img)
# plt.show()

# load fitted model from "car_detector"
model = tf.keras.models.load_model(r"..\models\cnn_car_detector")

# sliding window over image to find car
# cropping
window_size = 100
step_size = 20
nsteps_x = int(img.size[0] / step_size) + 1
nsteps_y = int(img.size[1] / step_size) + 1

y_data = []
for i in range(nsteps_x):
    for j in range(nsteps_y):
        img_cropped = img.crop((i * step_size, j * step_size,
                                i * step_size + window_size, j * step_size + window_size))\
                                .resize((32, 32), resample=Image.Resampling.BICUBIC)

        data = np.asarray(img_cropped).astype(np.float32) / 255.
        data = data.reshape((1, 32, 32, 3))
        y_data.append(model.predict(data)[0][0])

assert len(y_data) == nsteps_x * nsteps_y, "length of prediction array is not as expected"
y_data = np.reshape(y_data, (nsteps_x, nsteps_y))

# (i_opt, j_opt) = np.unravel_index(y_data.argmax(), y_data.shape)
# point_corner_opt = [i_opt * step_size, j_opt * step_size]
# point_corner_opt2 = [i_opt * step_size + window_size, j_opt * step_size + window_size]
# draw = ImageDraw.Draw(img)
# img_signed = draw_rectangle(draw, point_corner_opt, point_corner_opt2)

points = []
points2 = []
img_signed = img.copy()
for ix in range(y_data.shape[0]):
    for iy in range(y_data.shape[1]):
        if y_data[ix, iy] >= 0.4:
            points.append([ix * step_size, iy*step_size])
            points2.append([ix * step_size + window_size, iy*step_size + window_size])
            draw = ImageDraw.Draw(img_signed)
            img_signed = draw_rectangle(draw, points[-1], points2[-1])

plt.imshow(img_signed)
plt.show()

print('finished')


'''
The Idea:
1. We have to find the sum of "contiguous" subarray, therefore we must not change the order of array elements.
2. Let `current_sum` denotes the sum of a subarray, and `max_sum` denotes the maximum value of `current_sum`.
3. LOOP STARTS: For each element of the array, update the `current_sum` with the MAXIMUM of either:
 - The element added to the `current_sum` (denotes the addition of the element to the current subarray)
 - The element itself  (denotes the starting of a new subarray)
 - Update (overwrite) `max_sum`, if it is lower than the updated `current_sum`
4. Return `max_sum`
'''

def max_sum_subarray(arr):
    """
    :param - arr - input array
    return - number - largest sum in contiguous subarry within arr
    """
    current_sum = arr[0]
    max_sum = arr[0]
    for el in arr[1:]:
        current_sum = max(current_sum + el, el)
        max_sum = max(current_sum, max_sum)

    return max_sum

def test_function(test_case):
    arr = test_case[0]
    solution = test_case[1]

    output = max_sum_subarray(arr)
    if output == solution:
        print("Pass")
    else:
        print("Fail")

if __name__ == "__main__":
    arr = [1, 2, 3, -4, 6]
    solution = 8  # sum of array

    test_case = [arr, solution]
    test_function(test_case)

    arr = [1, 2, -5, -4, 1, 6]
    solution = 7  # sum of last two elements

    test_case = [arr, solution]
    test_function(test_case)

    arr = [-12, 15, -13, 14, -1, 2, 1, -5, 4]
    solution = 18  # sum of subarray = [15, -13, 14, -1, 2, 1]

    test_case = [arr, solution]
    test_function(test_case)


# **********************************************
#  Lote 01 - Exercício 16 - Estrutura Sequencial
#
#  16 - Receba a quantidade de horas trabalhadas, o valor por hora, o percentual de desconto e o número de descendentes.
#  Calcule o salário que serão as horas trabalhadas x o valor por hora. Calcule o salário líquido (= Salário Bruto – desconto).
#  A cada dependente será acrescido R$ 100 no Salário Líquido. Exiba o salário a receber.
#
#  Programador: Henrique Souza Lima
# ***********************************************

quantidade_horas = int(input("Digite a quantidade de horas trabalhadas:"))
valor_hora = float(input("Digite o valor/hora trabalhada:"))
desconto = int(input("Digite o percentual de desconto %:"))
desconto = desconto/100
dependentes = int(input("Digite a quantidade de dependentes:"))
dependentes = dependentes * 100
salario_bruto = quantidade_horas * valor_hora
salario_liquido = salario_bruto - (salario_bruto * desconto) + dependentes
salario_liquido = salario_liquido * 30

print("O valor do salário a receber é de: ", salario_liquido)


import argparse
import logging

import hail as hl

from gnomad.sample_qc.filtering import compute_stratified_metrics_filter
from gnomad.utils.annotations import bi_allelic_expr
from gnomad.utils.filtering import (
    filter_low_conf_regions,
    filter_to_autosomes,
)
from gnomad.utils.slack import slack_notifications
from ukbb_qc.resources.basics import (
    array_sample_map_ht_path,
    get_ukbb_data,
    logging_path,
)
from ukbb_qc.resources.resource_utils import CURRENT_FREEZE
from ukbb_qc.resources.sample_qc import (
    ancestry_hybrid_ht_path,
    platform_pca_assignments_ht_path,
    platform_pop_outlier_ht_path,
    qc_temp_data_prefix,
)
from ukbb_qc.slack_creds import slack_token
from ukbb_qc.utils.utils import annotate_interval_qc_filter, remove_hard_filter_samples

logging.basicConfig(format="%(levelname)s (%(name)s %(lineno)s): %(message)s")
logger = logging.getLogger("outlier_filter")
logger.setLevel(logging.INFO)

def run_sample_qc(mt: hl.MatrixTable) -> hl.Table:
    """
    Filter input MatrixTable to bi-allelic sites, removes problematic intervals, and computes sample QC metrics

    :param MatrixTable mt: Input MatrixTable on which sample QC metrics need to be computed
    :return: MatrixTable filtered to autosomes and high-confidence regions, with computed sample QC column annotations
    :rtype: hl.MatrixTable
    """
    # Filtering to bi-allelic sites outside of low confidence regions
    mt = filter_to_autosomes(mt)
    mt = filter_low_conf_regions(mt, filter_decoy=False)
    mt = mt.filter_rows(bi_allelic_expr(mt))

    logger.info("Starting sample QC...")
    mt = hl.sample_qc(mt)
    return mt.cols().select("sample_qc")

def main(args):

    hl.init(log="/outlier_detection.log", default_reference="GRCh38")

    data_source = "broad"
    freeze = args.freeze
    pop_assignment_method = args.pop_assignment_method

    try:
        if args.run_mini_qc:
            # NOTE: we run outlier detection without adj filtration to get better separation between high and low quality samples
            # this is per Julia's discussion with Konrad in #ukbb_qc
            # Need all workers for the mini qc
            mt = get_ukbb_data(data_source, freeze, adj=False)
            mt = annotate_interval_qc_filter(
                data_source,
                freeze,
                mt,
                cov_filter_field=args.cov_filter_field,
                pct_samples=args.pct_samples,
                autosomes_only=True,
            )
            mt = mt.filter_rows(mt.interval_qc_pass)

            logger.info("Filtering samples that fail hard filters...")
            mt = remove_hard_filter_samples(data_source, freeze, mt, gt_field="GT")
            logger.info(f"Sample count post filtering: {mt.count_cols()}")

            logger.info(
                "Running mini sample QC for platform- and population-specific filtering..."
            )
            sample_qc_ht = run_sample_qc(mt)
            sample_qc_ht = sample_qc_ht.repartition(args.n_partitions)
            sample_qc_ht.write(
                qc_temp_data_prefix(data_source, freeze)
                + "outlier_sample_qc_intervals.ht",
                args.overwrite,
            )

        sample_qc_ht = hl.read_table(
            qc_temp_data_prefix(data_source, freeze) + "outlier_sample_qc_intervals.ht"
        )
        strata = {}

        logger.info("Annotating population assignments...")
        pop_ht = hl.read_table(ancestry_hybrid_ht_path(data_source, freeze))
        sample_qc_ht = sample_qc_ht.annotate(
            qc_pop=pop_ht[sample_qc_ht.key][pop_assignment_method].pop
        )
        logger.info("Annotating inferred platform assignments...")
        platform_ht = hl.read_table(
            platform_pca_assignments_ht_path(data_source, freeze)
        )
        sample_qc_ht = sample_qc_ht.annotate(
            qc_platform=platform_ht[sample_qc_ht.key].qc_platform
        )
        logger.info("Annotating with batch (tranche) as a proxy for platform...")
        sample_map_ht = hl.read_table(array_sample_map_ht_path(freeze))
        sample_qc_ht = sample_qc_ht.annotate(
            batch=sample_map_ht[sample_qc_ht.key].batch
        )

        if args.population_filter:
            strata["qc_pop"] = sample_qc_ht.qc_pop
        else:
            pop_assignment_method = "no_pop"

        if args.platform_filter or args.batch_filter:
            if args.platform_filter:
                strata["qc_platform"] = sample_qc_ht.qc_platform
                platform_assignment_method = "qc_platform"

            if args.batch_filter:
                # NOTE: used tranche as a proxy for platform in tranche 2/freeze 5/200K
                strata["qc_platform"] = sample_qc_ht.batch
                platform_assignment_method = "batch"
        else:
            platform_assignment_method = "no_platform"

        # Make qc_metrics a dict (needs to be dict for compute_stratified_metrics_filter)
        metrics = args.filtering_qc_metrics.split(",")
        qc_metrics = {}
        for m in metrics:
            qc_metrics[m] = sample_qc_ht.sample_qc[f"{m}"]

        # For each platform and population, aggregate sample QC metrics and calculate the MAD/mean/stdev
        logger.info(
            "Flagging samples failing pop/platform-specific sample qc thresholds..."
        )
        pop_platform_filter_ht = compute_stratified_metrics_filter(
            sample_qc_ht, qc_metrics, strata
        )
        pop_platform_filter_ht = pop_platform_filter_ht.repartition(args.n_partitions)
        pop_platform_filter_ht.write(
            platform_pop_outlier_ht_path(
                data_source, freeze, pop_assignment_method, platform_assignment_method
            ),
            overwrite=args.overwrite,
        )
        num_pass = pop_platform_filter_ht.aggregate(
            hl.agg.count_where(hl.len(pop_platform_filter_ht.qc_metrics_filters) == 0)
        )
        logger.info(
            f"{num_pass} exome samples found passing pop/platform-specific filtering"
        )

    finally:
        logger.info("Copying hail log to logging bucket...")
        hl.copy_log(logging_path(data_source, freeze))

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "-o",
        "--overwrite",
        help="Overwrite all data from this subset (default: False)",
        action="store_true",
    )
    parser.add_argument(
        "--slack_channel", help="Slack channel to post results and notifications to."
    )
    parser.add_argument(
        "-f", "--freeze", help="Data freeze to use", default=CURRENT_FREEZE, type=int
    )
    parser.add_argument(
        "--n_partitions",
        help="Desired number of partitions. Used for ALL output HTs",
        default=5000,
        type=int,
    )

    parser.add_argument(
        "--run_mini_qc",
        help="Run mini sample qc needed for outlier filtering",
        action="store_true",
    )
    parser.add_argument(
        "--cov_filter_field",
        help="Coverage field to use to filter high coverage intervals",
        default="pct_samples_20x",
    )
    parser.add_argument(
        "--pct_samples",
        help="Percent samples at specified coverage to filter intervals",
        default=0.85,
        type=float,
    )
    platform_group = parser.add_mutually_exclusive_group()
    platform_group.add_argument(
        "--platform_filter",
        help="Include inferred platforms in outlier filtering",
        action="store_true",
    )
    platform_group.add_argument(
        "--batch_filter",
        help="Include batch (tranche) as proxy for platform in outlier filtering",
        action="store_true",
    )
    parser.add_argument(
        "--population_filter",
        help="Included inferred population in outlier filtering",
        action="store_true",
    )
    parser.add_argument(
        "--pop_assignment_method",
        help="Population assignment method to use for stratification",
        default="hybrid_pop_data",
        choices=["gnomad_pc_project_pop_data", "hybrid_pop_data"],
    )
    parser.add_argument(
        "--filtering_qc_metrics",
        help="List of QC metrics for filtering.",
        default=",".join(
            [
                "n_snp",
                "r_ti_tv",
                "r_insertion_deletion",
                "n_insertion",
                "n_deletion",
                "r_het_hom_var",
            ]
        ),
    )

    args = parser.parse_args()

    if args.slack_channel:
        with slack_notifications(slack_token, args.slack_channel):
            main(args)
    else:
        main(args)


import os
import homology
import utils
import filters
import hpa
import go
import pandas as pd

def get_proteins(config_file):
    """
    Retrieve all proteins for all species
    :param str config_file: path to config file

    :return: dictionary with all proteins for all species. Key -> tax id, value -> dictionary: key -> protein id, value -> protein name"""
    proteins = {}
    hosts = utils.read_config(filepath=config_file, field='hosts')
    parasites = utils.read_config(filepath=config_file, field='parasites')
    urls = utils.read_config(filepath=config_file, field='urls')
    if "string_protein_url" in urls:
        string_file = urls['string_protein_url']
        if hosts is not None and parasites is not None:
            taxids = list(hosts.keys()) + list(parasites.keys())
            for taxid in taxids:
                proteins[taxid] = parse_proteins(string_file, taxid)

    return proteins

def parse_proteins(string_file, taxid):
    """
    Retrieve proteins for a given specie
    :param str string_file: url to string PPI file
    :param int taxid: taxonomic id of the species of interest

    :return: dictionary with all proteins. Key -> Ensembl protein id, value -> protein name
    """
    proteins = {}
    if string_file is not None:
        filename = utils.download_file(url=string_file.replace('TAXID', str(taxid)), data_dir='data')
        sp = utils.read_gzipped_file(filename)
        first = True
        for line in sp:
            if first:
                first = False
                continue

            data = line.decode("utf-8").rstrip().split('\t')
            identifier = data[0]
            name = data[1]
            proteins[identifier] = name

    return proteins

def get_tissue_cell_type_annotation(tissues, output_file):
    tissues_df = pd.concat({k: pd.Series(v) for k, v in tissues.items()}).reset_index()
    tissues_df = tissues_df.iloc[:, [0, 2]]
    tissues_df.columns = ['Gene', 'Tissue']
    tissues_df = tissues_df[tissues_df['Gene'].isin(proteins.keys())]
    hpa_data = hpa.parse_hpa(config_file, valid_proteins=proteins.keys())
    tissues_df = pd.merge(tissues_df, hpa_data, on=['Gene', 'Tissue'], how='left')

    utils.save_to_parquet(tissues_df, output_file)

def setup(config_file, output_file_path):
    """
    Downloads all necessary files according to the urls specified in the configuration file
    except the protein files and host PPIs that are downloaded for each species. The go terms
    will also be downloaded and formatted.

    :param str config_file: path to the configuration file
    """
    urls = utils.read_config(filepath=config_file, field='urls')
    for url_name in urls:
        url = urls[url_name]
        if url_name != "string_protein_url" and url_name != "string_ppi_url" and url_name != "string_go_url":
            filename = utils.download_file(url=url, data_dir=output_file_path)

    go.get_gene_ontology(config_file, output_dir=output_file_path)

if __name__ == "__main__":
    data_dir = 'data'
    config_file = 'config.yml'

    setup(config_file=config_file, output_file_path=data_dir)

    hosts = utils.read_config(filepath=config_file, field='hosts')
    parasites = utils.read_config(filepath=config_file, field='parasites')

    #Get host and parasite proteins
    proteins = get_proteins(config_file)

    #Apply filters -- secretome, tissue, cellular compartment context
    proteins = filters.get_secretome_predictions(config_file=config_file, secretome_dir='data/secretome_pred_input_data/input_data', valid_proteins=proteins)
    tissues = filters.apply_tissue_filter(config_file, proteins, cutoff=2.5)
    compartments = filters.apply_compartment_filter(config_file, proteins, cutoff=2.5)
    proteins = utils.merge_dict_of_dicts(dict_of_dicts=proteins)

    #Annotate tissue and cell type expression
    get_tissue_cell_type_annotation(tissues, output_file=os.path.join(data_dir, 'tissues_cell_types.parquet'))

    #Get eggnog groups and transfer PPIs
    valid_groups = homology.get_eggnog_groups(filepath=os.path.join(data_dir, '2759_members.tsv.gz'), proteins=proteins.keys())
    homology.get_links(filepath=os.path.join(data_dir, 'COG.links.detailed.v11.5.txt.gz'), valid_groups=valid_groups, proteins=proteins,
              ouput_filepath=os.path.join(data_dir, 'predictions.parquet'), config_file=config_file)

    predictions = pd.read_parquet(os.path.join(data_dir, 'predictions.parquet'))
    predictions = utils.annotate_alias_id(predictions_df=predictions,
                            taxids=list(parasites.keys()), config_file=config_file,
                            sources=['BLAST_UniProt_AC'], new_col="source_uniprot",
                            mapping_col="source")

    predictions = utils.annotate_alias_id(predictions_df=predictions,
                            taxids=list(hosts.keys()), config_file=config_file,
                            sources=['Ensembl_HGNC_UniProt_ID(supplied_by_UniProt)'],
                            new_col="target_uniprot", mapping_col="target")

    utils.save_to_parquet(df=predictions, output_file=os.path.join(data_dir, 'annotated_predictions.parquet'))


import logging
import re

logger = logging.getLogger(__name__)

import sublime

try:
    from DynamicCompletions import FileLoader
except ImportError as e:
    logger.error('DynamicCompletions package not installed')
    raise e

from .tools.classes import get_ring_file
from .tools.settings import get_completion_source_enabled_setting

from .misc.completion_types import (
    CT_ALIAS,
    CT_FOCUS_LOCAL,
    CT_SUBROUTINE,
    CT_LIST,

    CT_OBJECT,
    CT_RECORD,
    # CT_FILE,
    CT_KEY,
    CT_FIELD,
    # CT_INDEX,
    # CT_INDEXKEY,
    # CT_LONGLOCK,
)

class IncludeFileLoader(FileLoader):
    """
    Parent class for CompletionLoaders that load completions from an Include
    file.
    """

    LoadAsync = True

    @classmethod
    def view_scope(cls):
        """
        Return a scope to determine if the CompletionLoader will be enabled
        for a view.

        """
        return 'source.focus'

    @classmethod
    def view_check(cls, view):
        n = view.file_name()
        if (n is None) or (n == ''):
            return False
        return (get_ring_file(n) is not None)

    @classmethod
    def instances_for_view(cls, view):
        """
        Returns a list of instances of the given class to be used for the
        given view.

        """
        ring_file = get_ring_file(view.file_name())
        if ring_file is None:
            return []

        include_files = ring_file.get_include_files()
        if not include_files:
            return []

        instances = set()
        for f in include_files:
            logger.debug('%s;  f = %s', cls, f)
            try:
                instances.add(cls.Instances[f])
            except KeyError:
                instances.add(cls(file_path=f))
            except AttributeError:
                instances.add(cls(file_path=f))
        return instances

class AliasIncludeLoader(IncludeFileLoader):
    """
    Loads aliases defined in an Include File.
    """

    EmptyReturn = ([], sublime.INHIBIT_WORD_COMPLETIONS |
                   sublime.INHIBIT_EXPLICIT_COMPLETIONS)

    AliasMatcher = re.compile(r"^\s*:Alias\s+([^\n()\t]+?) *$", re.MULTILINE)

    @classmethod
    def completion_types(cls):
        """
        Return a set of completion types that this CompletionLoader can return.

        """
        return [CT_ALIAS]

    @classmethod
    def view_check(cls, view):
        if super().view_check(view):
            return get_completion_source_enabled_setting('Alias', 'Include')

    def load_completions(self, **kwargs):
        """
        Populate self.completions with Aliases from an Include file.

        """
        self.completions = set()
        ring_file = get_ring_file(self.file_path)
        for alias in ring_file.get_defined_aliases():
            alias = '@@' + alias + '()'
            self.completions.add((alias + '\tInclude', alias[2:]))

class LocalIncludeLoader(IncludeFileLoader):
    """
    Loads any locals used in an Include File.
    """

    EmptyReturn = ([], sublime.INHIBIT_WORD_COMPLETIONS |
                   sublime.INHIBIT_EXPLICIT_COMPLETIONS)

    @classmethod
    def completion_types(cls):
        """
        Return a list of completion types that this CompletionLoader can
        return.

        """
        return [CT_FOCUS_LOCAL]

    @classmethod
    def view_check(cls, view):
        if super().view_check(view):
            return get_completion_source_enabled_setting('Local', 'Include')

    def load_completions(self, **kwargs):
        """
        Populate self.completions with Locals from an Include file.

        """
        self.completions = set()
        ring_file = get_ring_file(self.file_path)
        for local in (ring_file.get_used_locals() |
                      ring_file.get_defined_locals()):
            self.completions.add((local + '\tInclude', local))

class ObjectIncludeLoader(IncludeFileLoader):
    """
    Loads DataDef completions from an Include File.
    """

    EmptyReturn = ([], sublime.INHIBIT_EXPLICIT_COMPLETIONS)

    @classmethod
    def completion_types(cls):
        """
        Return a list of completion types that this CompletionLoader can
        return.

        """
        return [CT_OBJECT, CT_RECORD, CT_KEY, CT_FIELD]

    @classmethod
    def view_check(cls, view):
        if super().view_check(view):
            return get_completion_source_enabled_setting('Object', 'Include')

    def load_completions(self, **kwargs):
        """
        Populate self.completions with objects from an Include file.

        """
        self.completions = dict()
        ring_file = get_ring_file(self.file_path)
        object_dict = ring_file.get_defined_objects()

        for key, object_set in object_dict.items():
            self.completions[key] = set(
                [(x + '\tInclude', x) for x in object_set])

class SubroutineIncludeLoader(IncludeFileLoader):
    """
    Loads subroutine completions from an Include File.
    """

    EmptyReturn = ([], sublime.INHIBIT_WORD_COMPLETIONS |
                   sublime.INHIBIT_EXPLICIT_COMPLETIONS)

    @classmethod
    def completion_types(cls):
        """
        Return a list of completion types that this CompletionLoader can
        return.

        """
        return [CT_SUBROUTINE]

    @classmethod
    def view_check(cls, view):
        if super().view_check(view):
            return get_completion_source_enabled_setting('Subroutine',
                                                         'Include')

    def load_completions(self, **kwargs):
        """
        Populate self.completions with subroutines from an Include file.

        """
        ring_file = get_ring_file(self.file_path)
        self.completions = set(
            [(x + '\tInclude', x) for x in
             ring_file.get_defined_subroutines()])

class ListIncludeLoader(IncludeFileLoader):
    """
    Loads subroutine completions from an Include File.
    """

    EmptyReturn = ([], sublime.INHIBIT_WORD_COMPLETIONS |
                   sublime.INHIBIT_EXPLICIT_COMPLETIONS)

    @classmethod
    def completion_types(cls):
        """
        Return a list of completion types that this CompletionLoader can
        return.

        """
        return [CT_LIST]

    @classmethod
    def view_check(cls, view):
        if super().view_check(view):
            return get_completion_source_enabled_setting('List',
                                                         'Include')

    def load_completions(self, **kwargs):
        """
        Populate self.completions with Lists from an Include file.

        """
        ring_file = get_ring_file(self.file_path)
        self.completions = set(
            [(x + '\tInclude', x) for x in ring_file.get_defined_lists()])


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

from __future__ import with_statement

import conf
import logging
import os.path
import sys
import ConfigParser

class Singleton(type):
    """Singleton Class implementation from
    http://code.activestate.com/recipes/412551/
    """

    def __init__(self, *args):
        type.__init__(self, *args)
        self._instance = None

    def __call__(self, *args):
        if self._instance is None :
            self._instance = type.__call__(self, *args)
        return self._instance

class MogamiLog(object):
    """Mogami Logger Class.
    """
    __metaclass__ = Singleton

    # Type of Component
    TYPE_FS = 0
    TYPE_META = 1
    TYPE_DATA = 2
    TYPE_SCHEDULER = 3

    DEBUG = logging.DEBUG
    INFO = logging.INFO
    WARNING = logging.WARNING
    ERROR = logging.ERROR
    CRITICAL = logging.CRITICAL

    def __init__(self, *args):
        """
        >>> i1 = MogamiLog()
        >>> i2 = MogamiLog()
        >>> assert(i1 == i2)
        """
        pass

    @staticmethod
    def init(log_type, output_level):
        """Initialize logger.

        @param log_type
        @param output_level
        >>> MogamiLog.init(MogamiLog.TYPE_META, MogamiLog.DEBUG)
        """
        instance = MogamiLog()

        logdir = conf.log_dir
        if log_type == MogamiLog.TYPE_FS:
            instance.logfile = os.path.join(logdir, "mogami.log")
        elif log_type == MogamiLog.TYPE_META:
            instance.logfile = os.path.join(logdir, "meta.log")
        elif log_type == MogamiLog.TYPE_DATA:
            instance.logfile = os.path.join(logdir, "data.log")
        elif log_type == MogamiLog.TYPE_SCHEDULER:
            instance.logfile = os.path.join(logdir, "scheduler.log")
        else:
            raise
        if os.access(logdir, os.W_OK) == False:
            sys.exit("""** Directory for log is permitted to write. **
Please confirm the directory "%s".""" % (logdir))

        logging.basicConfig(filename=instance.logfile,
                            level=output_level,
                            format='[%(asctime)s] %(message)s',
                            datefmt='%m/%d/%Y %I:%M:%S')
        logging.info("Logging Start")

    @staticmethod
    def debug(msg):
        logging.debug(msg)

    @staticmethod
    def info(msg):
        logging.info(msg)

    @staticmethod
    def warning(msg):
        logging.warning(msg)

    @staticmethod
    def error(msg):
        logging.error(msg)

    @staticmethod
    def critical(msg):
        logging.critical(msg)

class MogamiError(Exception):
    def __init__(self, typeno, ):
        pass

    def __str__(self, ):
        pass

class MogamiConfigParser(object):
    def __init__(self, config_path):
        """
        """
        self.config = ConfigParser.ConfigParser()
        self.config.read(config_path)

    def __getattr__(self, attr):
        return eval(self.config.get('default', attr))

if __name__ == "__main__":
    import doctest
    doctest.testmod()


#encoding
import xml.etree.ElementTree as ET
employees = ET.Element('Employees')
emp1 = ET.SubElement(employees,'Employee')
id1 = ET.SubElement(emp1,'id')
id1.text = '1'
name1 = ET.SubElement(emp1,'name')
name1.text = 'Mary'
# id2 = ET.SubElement(emp2,'id')
# id2.text = '2'
# name2 = ET.SubElement(emp2,'name')
# name2.text = 'John'
print(ET.tostring(employees))
et = ET.ElementTree(employees)
with open(r'c:\Users\user\PycharmProjects\pythonProject\class7\aa.xml',mode = 'wb') as f:
    et.write(f,encoding = 'UTF-8')


class Solution:
    def subsetsWithDup(self, nums: List[int]) -> List[List[int]]:

        answer, index, n = set(), 0, len(nums)
        while index < (1<<n):
            subset = []
            for i in range(32):
                if index & (1<<i): subset.append(nums[i])
            subset.sort()
            answer.add(tuple(subset))
            index += 1
        return list(answer)


from Tkinter import *
from Tkinter import Tk
from PIL import Image, ImageTk

fram = Frame()

app = Tk()
app.title("Bienvenido al Visor de Imagenes")
img = Image.open("cielo.jpg")
rimg = img.resize((150,150))
head = Label(app,text="Visor de Imagenes")

imagen = ImageTk.PhotoImage(rimg)
imagen1 = Label(app,image=imagen,anchor="center")

imagen1.grid(row=1,column=0)
head.grid(row=0,column=1)
app.geometry("800x600")
app.mainloop()


import csv
import torch
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
import random
import math
import pickle
from collections import namedtuple, deque
import JSBSim
import time
import subprocess
import os
import glob
import numpy as np
import statistics

Transition = namedtuple('Transition', ('state', 'action', 'next_state', 'reward'))

# DQN Network
class DQN(nn.Module):

    def __init__(self, n_observations, n_actions):
        super(DQN, self).__init__()
        self.layer1 = nn.Linear(n_observations, 128)
        self.layer2 = nn.Linear(128, 128)
        self.layer3 = nn.Linear(128, n_actions)

    def forward(self, x):
        x = F.relu(self.layer1(x))
        x = F.relu(self.layer2(x))
        return self.layer3(x)

class ReplayMemory:
    def __init__(self, capacity):
        self.memory = deque(maxlen=capacity)

    def push(self, *args):
        self.memory.append(Transition(*args))

    def sample(self, batch_size):
        return random.sample(self.memory, batch_size)

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

def save_replay_memory(memory, file_name):
    with open(file_name, 'wb') as file:
        pickle.dump(memory, file)

def load_replay_memory(file_name):
    with open(file_name, 'rb') as file:
        return pickle.load(file)

# Function to save model weights
def save_model_weights(model, filename):
    torch.save(model.state_dict(), filename)

# Function to load model weights
def load_model_weights(model, filename):
    if os.path.exists(filename):
        model.load_state_dict(torch.load(filename))
        model.train()  # Set the model to training mode
    else:
        print(f"No weights found at {filename}, initializing model with default weights.")
        torch.save(model.state_dict(), filename)
        model.train()

# Global Variables
BATCH_SIZE = 128
GAMMA = 0.99
EPS_START = 1.0
EPS_END = 0.01
EPS_DECAY = 2000
TAU = 0.005
LR = 1e-4

# action space with 0.1 intervals
action_space = [
    (elevator, aileron, rudder)
    for elevator in [i/10 for i in range(-10, 11)]
    for aileron in [i/10 for i in range(-10, 11)]
    for rudder in [i/10 for i in range(-10, 11)]
]

n_actions = len(action_space)
n_observations = 4  # altitude, xaccel, yaccel, zaccel

policy_net = DQN(n_observations, n_actions)
target_net = DQN(n_observations, n_actions)
load_model_weights(policy_net, "policy_net_weights.pth")
load_model_weights(target_net, "target_net_weights.pth")
target_net.load_state_dict(policy_net.state_dict())
optimizer = optim.AdamW(policy_net.parameters(), lr=LR, amsgrad=True)
memory = ReplayMemory(1000000)
steps_done = 0

# Function to dynamically adjust epsilon
def dynamic_eps(run_number, steps_done, total_runs=10, min_eps=0.01, max_eps=1.0):
    return min_eps + (max_eps - min_eps) * math.exp(-1. * steps_done / EPS_DECAY)

# Select Action Function with Dynamic Epsilon
def select_action(state, run_number, steps_done):
    eps_threshold = dynamic_eps(run_number, steps_done)
    if random.random() > eps_threshold:
        with torch.no_grad():
            return policy_net(state).max(1)[1].view(1, 1)
    else:
        return torch.tensor([[random.randrange(n_actions)]], dtype=torch.long)

def get_state_reward(current_state, altitude_change):
    current_altitude = current_state[0]

    steep_decline_rate = -10  # Example rate in feet per 0.5 second

    reward = 0

    # Penalty for steep decline
    if altitude_change < steep_decline_rate * 0.5:  # Assuming a 0.5 second interval
        reward -= 5

    # Penalty for dropping altitude to zero or below
    if current_altitude <= 0:
        reward -= 10

    return reward

def calculate_stability_reward(altitudes, threshold=5, stable_range=10):
    """
    Calculate stability reward based on altitude variations over the last 'threshold' seconds.
    'stable_range' defines the acceptable range of altitude variation for stability.
    """
    if len(altitudes) < threshold:
        return 0  # Not enough data to calculate stability

    recent_altitudes = altitudes[-threshold:]
    altitude_variance = np.var(recent_altitudes)

    if altitude_variance <= stable_range**2:
        return 2  # Reward for maintaining stable altitude
    else:
        return 0  # No reward if altitude varies too much

def get_episodic_reward(flight_duration, episodes_for_average, directory):
    # Reward based on flight duration
    # Episodic reward is equal to deviation from average flight time of previous series of episodes

    all_files = [os.path.join(directory, file) for file in os.listdir(directory) if os.path.isfile(os.path.join(directory, file))]
    sorted_files = sorted(all_files, key=os.path.getmtime, reverse=True)

    # Get the last n files
    last_n_files = sorted_files[:episodes_for_average]

    # Read the last line of each file
    last_lines = []
    for file in last_n_files:
        with open(file, 'r') as f:
            lines = f.readlines()
            if lines:
                last_line = lines[-1].strip()
                last_line = last_line.split(",,,,")
                last_line = last_line[-1]
                last_line = float(last_line)
                last_lines.append(last_line)

    return flight_duration - statistics.mean(last_lines)

# Optimize Model Function
def optimize_model():
    if len(memory) < BATCH_SIZE:
        return
    transitions = memory.sample(BATCH_SIZE)
    batch = Transition(*zip(*transitions))

    non_final_mask = torch.tensor(tuple(map(lambda s: s is not None, batch.next_state)), dtype=torch.bool)
    non_final_next_states = torch.cat([s for s in batch.next_state if s is not None]) if any(non_final_mask) else None
    state_batch = torch.cat(batch.state)
    action_batch = torch.cat(batch.action)
    reward_batch = torch.cat(batch.reward)

    state_action_values = policy_net(state_batch).gather(1, action_batch)

    next_state_values = torch.zeros(BATCH_SIZE)
    if non_final_next_states is not None:
        with torch.no_grad():
            next_state_values[non_final_mask] = target_net(non_final_next_states).max(1)[0]
    expected_state_action_values = (next_state_values * GAMMA) + reward_batch

    criterion = nn.SmoothL1Loss()
    loss = criterion(state_action_values, expected_state_action_values.unsqueeze(1))

    optimizer.zero_grad()
    loss.backward()
    for param in policy_net.parameters():
        param.grad.data.clamp_(-1, 1)
    optimizer.step()

def load_simulator_data(file_path):
    with open(file_path, 'r') as f:
        reader = csv.reader(f)
        next(reader)
        data = [line for line in reader]
    return data

def log_run_data(run_number, episode_states, episode_actions, flight_duration, reward):
    """Logs the data for a single run to a CSV file."""
    run_log_file = f'runlogs/run{run_number}.csv'
    with open(run_log_file, 'w', newline='') as f:
        writer = csv.writer(f)
        writer.writerow(["altitude", "xaccel", "yaccel", "zaccel", "elevator", "aileron", "rudder"])
        for state, action in zip(episode_states, episode_actions):
            writer.writerow(state + list(action))
        writer.writerow(["Reward", "", "", "", reward])
        writer.writerow(["Flight Duration", "", "", "", flight_duration])

def initialize_runlogs():
    """Initializes the runlogs directory and finds the last run number."""
    if not os.path.exists('runlogs'):
        os.makedirs('runlogs')

    run_files = glob.glob('runlogs/run*.csv')
    run_numbers = [int(os.path.splitext(os.path.basename(f))[0][3:]) for f in run_files]
    return max(run_numbers) if run_numbers else 0

def process_state(altitude, xaccel, yaccel, zaccel):
    """Process a single state and return the selected action."""
    state = torch.tensor([altitude, xaccel, yaccel, zaccel], dtype=torch.float32).unsqueeze(0)
    action = select_action(state)
    elevator, aileron, rudder = action_space[int(action.item())]
    return (elevator, aileron, rudder)

def update_memory(state, action, next_state, reward):
    """Store the transition in replay memory"""
    memory.push(state, action, next_state, torch.tensor([reward], dtype=torch.float32))

def run_fgfs(filename):
    with open(filename, 'r') as file:
        fg_command = file.read().strip()  # Read and strip any trailing whitespace
    return subprocess.Popen(fg_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

def kill_fgfs():
    subprocess.run(["bash", "kill.sh"])

def main():
    last_run_number = initialize_runlogs()
    current_run_log = last_run_number + 1
    run_number = 0

    while run_number < 11:
        jsbsim_client = JSBSim.JsbsimInterface()
        steps_done = 0  # Reset steps_done for each run
        altitudes = []  # List to store altitudes for stability calculation
        stability_reward_interval = 100  # Assuming simulation step is 0.01s, calculate every second
        stability_reward = 0

        try:
            print(f"Starting JSBSim for Run No {run_number}!")
            jsbsim_client.start()

            episode_actions = []
            episode_states = []
            episode_actions_log = []
            last_altitude = None

            while True:
                jsbsim_client.run()

                current_state = jsbsim_client.get_state()
                altitude, xaccel, yaccel, zaccel = current_state
                episode_states.append(current_state)

                # Calculate altitude change
                altitude_change = 0
                if last_altitude is not None:
                    altitude_change = altitude - last_altitude
                last_altitude = altitude

                altitudes.append(altitude)

                if len(altitudes) % stability_reward_interval == 0:
                    stability_reward = calculate_stability_reward(altitudes, threshold=100, stable_range=10)

                if jsbsim_client.gear_contact():
                    print("Landing gear contact. Ending simulation.")
                    next_state = None  # Set next state to None if simulation ends
                    break

                if altitude <= 0:  # Check for simulation end condition
                    next_state = None
                    break

                # Process state to get actions
                torch_current_state = torch.tensor(current_state, dtype=torch.float32).unsqueeze(0)
                action_index = select_action(torch_current_state, run_number, steps_done)
                elevator, aileron, rudder = action_space[int(action_index.item())]
                actions = [elevator, aileron, rudder]
                episode_actions_log.append(actions)

                # Apply actions to JSBSim
                jsbsim_client.set_controls(elevator, aileron, rudder)

                # Get the next state
                jsbsim_client.run()
                next_state = jsbsim_client.get_state()

                # Store the state and action
                torch_next_state = torch.tensor(next_state, dtype=torch.float32).unsqueeze(0) if next_state is not None else None
                episode_actions.append((torch_current_state, action_index))

                # Calculate and update memory with state reward
                state_reward = get_state_reward(current_state, altitude_change)
                # Update the total reward including stability_reward
                total_reward = state_reward + stability_reward
                # print(total_reward) uncomment this to see the total_reward of each state
                action_tensor = torch.tensor([[action_index]], dtype=torch.long)
                update_memory(torch_current_state, action_tensor, torch_next_state, total_reward)

            # Use JSBSim's internal simulation time as flight duration
            flight_duration = jsbsim_client.get_sim_time()
            print(f"Flight duration for Run No {run_number}: {flight_duration} seconds")

            # Calculate episodic reward and update memory
            episodic_reward = get_episodic_reward(flight_duration, 100, "runlogs")
            for state, action in episode_actions:
                update_memory(state, action, None, episodic_reward)

            # Log run data
            log_run_data(current_run_log, episode_states, episode_actions_log, flight_duration, episodic_reward)

            run_number += 1
            current_run_log += 1
            if run_number % 5 == 0:
                optimize_model()

        finally:
            jsbsim_client.stop()

    save_model_weights(policy_net, "policy_net_weights.pth")
    save_model_weights(target_net, "target_net_weights.pth")
    save_replay_memory(memory, "replay_memory.pkl")

if __name__ == "__main__":
    main()


"""
Design Hit Counter
Things to consider:
1. If a lot of hits within given time window / per sec
2. Multi-threading, if multiple threads report hit #Example: if a webpage, multiple clients click hit
"""

from collections import deque

"""
1. 简单版本，不考虑多线程
"""
class HitCounter:

    def __init__(self):
        """
        Initialize your data structure here.
        """
        self._counter = deque()
        self.th = 300

    def hit(self, timestamp: int) -> None:
        """
        Record a hit.
        @param timestamp - The current timestamp (in seconds granularity).
        """
        self._counter.append(timestamp)

    def getHits(self, timestamp: int) -> int:
        """
        Return the number of hits in the past 5 minutes.
        @param timestamp - The current timestamp (in seconds granularity).
        """
        cutoff = timestamp - self.th
        if self._counter and self._counter[-1] <= cutoff:
            return 0

        while self._counter:
            if self._counter[0] <= cutoff:
                self._counter.popleft()
            else:
                break

        return len(self._counter)

# python solution: O(1) Space, O(1) hit, O(S) gethits()
"""
using a tuple and referencing the variable at the same time so even if the context switch
happens in a multithreaded environment, both hits and times will be in sync

can achieve synchronized modification and reading
or using blocking queue

it can handle multiple hit at the same time, because this approach does not involve dynamic allocating the space
"""

class HitCounter2:

    def __init__(self):
        """
        Initialize your data structure here.
        """
        self.th = 300
        self.q = [(0, 0)] * self.th

    def hit(self, timestamp: int) -> None:
        """
        Record a hit.
        @param timestamp - The current timestamp (in seconds granularity).
        """
        idx = timestamp % self.th
        time, hit = self.q[idx]
        if time != timestamp:
            # previous timestamp is outdated, safe to override
            self.q[idx] = timestamp, 1
        else:
            self.q[idx] = time, hit + 1

    def getHits(self, timestamp: int) -> int:
        """
        Return the number of hits in the past 5 minutes.
        @param timestamp - The current timestamp (in seconds granularity).
        """
        cnt = 0
        cutoff = timestamp - self.th
        for time, hit in self.q:
            if time > cutoff:
                cnt += hit
        return cnt


import os
import shutil
import xml.etree.ElementTree as et
import zipfile

class ModificaDocx(object):

    scheme = '{http://schemas.openxmlformats.org/wordprocessingml/2006/main}'

    def __init__(self, path):
        self.path = path
        self.filename = os.path.basename(path)

    def get_docx_xml(self):
        myzip = zipfile.ZipFile(self.path, 'r')
        xml_content = myzip.read('word/document.xml')
        xml_tree = et.fromstring(xml_content)
        return xml_tree

    def find_text_nodes(self, xml_tree):
        'Iteratore per trovare i nodi testo xml'
        for nodo in xml_tree.iter():
            if nodo.tag == self.scheme + 't':
                yield nodo

    def write_docx(self, xml_tree, filename=''):
        if filename == '':
            filename = self.filename
        else:
            filename = filename + '.docx'

        root_dir = os.getcwd()
        os.makedirs('tmp')
        tmp_dir = os.path.join(root_dir, 'tmp')
        os.chdir(tmp_dir)

        with zipfile.ZipFile(self.path, 'r') as myzip:
            myzip.extractall(tmp_dir)
            myzip.close()

        with open(os.path.join(tmp_dir, 'word/document.xml'), 'w') as f:
            f.write(et.tostring(xml_tree, encoding='unicode'))
            f.close()

        with zipfile.ZipFile(filename, 'w') as f:
            for item in zipfile.ZipFile(self.path, 'r').namelist():
                f.write(os.path.join(tmp_dir, item), item)
            f.close()

        os.rename(os.path.join(tmp_dir, filename), os.path.join(root_dir, filename))
        shutil.rmtree(tmp_dir)

class ModificaDisegni(object):
    'Toolkit per aggiornare il documento per la modifica disegni'

    template = '/home/io/Documents/codes/python/template.docx'

    def __init__(self, author, date, modification_description):
        self.author = author
        self.date = date
        self.modification_description = modification_description

    def new_autohr(self, author):
        self.author = author

    def new_date(self, date):
        self.author = date

    def modification_description(self, modification_description):
        self.author = modification_description

    def fill_template(self, filename):
        template = ModificaDocx(self.template)
        template_xml_tree = template.get_docx_xml()
        for node in template.find_text_nodes(template_xml_tree):
            new_text = 'ciao mamma!!!!'
            node.text = new_text
        template.write_docx(template_xml_tree, filename)

def main():

    mod_1 = ModificaDisegni('io', '18-3-84', 'muhauhuahu')
    mod_1.fill_template('daje')

#    author = input("Mittente :")
#    date = input("Data :")
#    file_name = input("Nome File :")
#
#    mod_1 = ModificaDisegni(file_name, author, date)
#    print(mod_1.file_name)
#
#    mod_1 = ModificaDisegni('daje', 'Pierpaolo', '18/03/1984')
#
#    my_xml_tree = mod_1.get_docx_xml()
#
#    for node in mod_1.find_text_nodes(my_xml_tree):
#        new_text = 'DAJE de PIUUUUU!!!!'
#        node.text = new_text
#
#    mod_1.write_docx(my_xml_tree, 'daje')

if __name__ == '__main__':
    main()


#!/usr/bin/env python
from pathlib import Path
from distutils.core import setup

README = Path(__file__).parent / "README.md"
with open(README) as fp:
    long_description = fp.read()

setup(
    name="PyAutoBlockchain",
    version="0.5",
    description="PAB is a framework that helps with development and automation of periodic tasks on blockchains.",
    long_description=long_description,
    long_description_content_type="text/markdown",
    author="Manuel Pepe",
    author_email="manuelpepe-dev@outlook.com.ar",
    url="https://github.com/manuelpepe/PyAutoBlockchain",
    include_package_data=True,
    package_data={"pab": ["resources/config.schema.json"]},
    entry_points={
        "console_scripts": [
            "pab = pab.cli:ep",
        ],
    },
    packages=[
        "pab",
        "pab.resources",
    ],
    install_requires=["web3", "hexbytes", "python-dotenv", "projectutils"],
    extras_require={"ui": ["pabui"]},
)


# Based on: https://machinelearningmastery.com/understanding-stateful-lstm-recurrent-neural-networks-python-keras/
#       and https://www.idiap.ch/~katharas/importance-sampling/ --> Not working for TF 2.2
import numpy as np
import random
import datetime
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, LSTM, GRU, Masking
from tensorflow.keras import utils
from tensorflow.keras.preprocessing.sequence import pad_sequences
from tensorflow.keras.callbacks import Callback

##### Parameters

n_iterations = 30
n_epochs = 50

eval_method = "loss"
#eval_method = "accuracy"

mask_value = np.finfo(np.float32).min

#####

np.set_printoptions(formatter={'float': '{: 0.3f}'.format}, suppress=True, linewidth=208)
np.random.seed(7)

alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"

char_to_int = dict((c, i) for i, c in enumerate(alphabet))
int_to_char = dict((i, c) for i, c in enumerate(alphabet))

dataX = []
dataY = []
for i in range(0, len(alphabet), 1):
    seq_in = alphabet[i:i + 1]
    seq_out = alphabet[(i + 1) % len(alphabet)]
    dataX.append([char_to_int[char] for char in seq_in])
    dataY.append(char_to_int[seq_out])

data = dict()
data["X"] = []
data["y"] = []
for seq_len in range(1, len(alphabet)+1):
    for shift in range(len(alphabet)):
        roll = np.roll(dataX, shift, axis=0)
        X = roll[:seq_len].reshape(seq_len) / float(len(alphabet))
        y = utils.to_categorical(roll[seq_len % len(alphabet)], len(alphabet))
        data["X"].append(X)
        data["y"].append(y)

X = pad_sequences(data["X"], maxlen=len(alphabet), value=mask_value, dtype=np.float32)
X = np.reshape(X, (X.shape[0], X.shape[1], 1))
y = np.array(data["y"])
y = np.reshape(y, (y.shape[0], y.shape[2]))

model = Sequential()
model.add(Masking(mask_value=mask_value, input_shape=(len(alphabet), 1)))
model.add(GRU(32))
model.add(Dense(len(alphabet), activation="softmax"))
model.compile(loss="categorical_crossentropy", optimizer="nadam", metrics=["accuracy"])
print(model.summary())

class EvaluationCallback(Callback):
    def __init__(self, metric):
        if metric=="loss":
            self.metric = "loss"
        else:
            self.metric = "accuracy"
        print("===> Metric is", metric)

    def on_test_begin(self, logs=None):
        self.score = []

    def on_test_batch_end(self, batch, logs=None):
        if self.metric=="loss":
            self.score.append(logs["loss"])
        else:
            self.score.append(max(1 - logs["accuracy"], 0.01))

X_importance = np.array([1 for x in X])

def sample():
    X_tmp = []
    y_tmp = []
    for i in range(len(X_importance)):
        for _ in range(X_importance[i]):
            X_tmp.append(X[i])
            y_tmp.append(y[i])
    return np.array(X_tmp), np.array(y_tmp)

evalCallback = EvaluationCallback(eval_method)

def calc_importance():
    _, a = model.evaluate(X, y, batch_size=1, callbacks=[evalCallback], verbose=1)
    if a == 1:
        return None
    importance = np.round(evalCallback.score / np.min(evalCallback.score)).astype(int)
    print("Min:", np.min(importance), " Max:", np.max(importance), " Mean:", np.mean(importance), " Median:", np.median(importance), " Percentiles [25, 33, 50, 66, 75, 85, 90, 95]:", np.percentile(importance, [25, 33, 50, 66, 75, 85, 90, 95]))
    print("Score Min:", np.min(evalCallback.score), " Score Max:", np.max(evalCallback.score))
    return importance

start = datetime.datetime.now()
for i in range(n_iterations):
    X_sampled, y_sampled = sample()
    print("Iteration", (i+1), "is training on", X_sampled.shape[0], "samples")
    stat = model.fit(X_sampled, y_sampled, batch_size=64, epochs=n_epochs, shuffle=True, verbose=1)
    X_importance = calc_importance()
    if X_importance is None:
        break
end = datetime.datetime.now()

X = np.unique(X, axis=0)
y_hat = model.predict(X)
for sample in range(X.shape[0]):
    x = [int(round(xx * len(alphabet))) for xx in X[sample].reshape(len(alphabet)) if xx >= 0]
    chars = [int_to_char[round(v)] for v in x]
    index = np.argmax(y_hat[sample])
    print(chars, "=>", int_to_char[index])

print("===> Iterations:", (i+1), "Total epochs:", ((i+1) * n_epochs))
print("===> Total training time:", (end-start))


# dictionaries
# pasangan key dan value

# cara bikin dictionary
monthConversion = {
    "Jan": "January",
    "Feb": "February",
    "Mar": "March",
    "Apr": "April",
    "May": "May",
    "Jun": "June",
    "Jul": "July",
    "Aug": "August",
    "Sep": "September",
    "Oct": "October",
    "Nov": "November",
    "Dec": "December",
}

# akses dictionary, bukan menggunakan index tapi "key"
#print(monthConversion["Jan"])

print(monthConversion.get("Luv", "Not a valid key"))
# Kalau pakei .get() itu akan membantu ketika key yang dimasukkan itu tidak ada
# parameter ke 2 akan menjadi default value ketika key nya tidak ada


import rhinoscriptsyntax as rs

def mapValue(val, inMin, inMax, outMin, outMax):
    outR = outMax - outMin
    inR = inMax - inMin
    inVal = val - inMin
    newVal = (inVal/inR) * outR
    return outMin + newVal

def lerp(startPt, endPt, T):
    len = rs.VectorSubtract(endPt, startPt)
    nVec = rs.VectorScale(len, T)
    return rs.VectorAdd(startPt, nVec)

def calcBiLinear(pt, bbMin, bbMax):
    bX = mapValue(pt.X,bbMin[0],bbMax[0],0.0,1.0)
    bY = mapValue(pt.Y,bbMin[1],bbMax[1],0.0,1.0)
    return[bX,bY]

def calcTriLinear(pt, bbMin, bbMax):
    bX = mapValue(pt.X,bbMin[0],bbMax[0],0.0,1.0)
    bY = mapValue(pt.Y,bbMin[1],bbMax[1],0.0,1.0)
    bZ = mapValue(pt.Z,bbMin[2],bbMax[2],0.0,1.0)
    return[bX,bY,bZ]

def main():
    #box = rs.GetBox()

    unitCubeMin = box[0]
    unitCubeMax = box[6]

    #units = rs.GetObjects("select polylines", 4)
    #meshes = rs.GetObjects("select meshes",32)

    for unit in units:
        unitPts = []
        unitCoords =[]

        polylinePts = rs.PolylineVertices(unit)

        print(str(polylinePts[0]))
        for pt in polylinePts:
            tc = calcTriLinear(pt,unitCubeMin,unitCubeMax)
            unitCoords.append(tc)
            unitPts.append(pt)

        for mesh in meshes:
            v = rs.MeshVertices(mesh)
            count = 0

            newPts = []
            for i in range(0, len(unitPts)):
                bLC = unitCoords[i]
                lX1 = lerp(v[4],v[5],bLC[0])
                lX2 = lerp(v[3],v[0] ,bLC[0])

                uX1 = lerp(v[6],v[7],bLC[0])
                uX2 = lerp(v[1],v[2],bLC[0])

                y1 = lerp(lX1,lX2,bLC[1])
                y2 = lerp(uX1,uX2,bLC[1])

                pt = lerp(y1,y2,bLC[2])
                rs.AddPoint(pt)
                newPts.append(pt)

            rs.AddPolyline(newPts)

if __name__ == "__main__":
    main()


months = ("Enero","Febrero","Marzo","Abril","Mayo","Junio",
    "Julio","Agosto","Septiembre","Octubre","Noviembre","Diciembre")
while True:
    numero = int(input("Numero del mes: "))
    if numero <= 0:
        # El prigrama debe terminar
        # Break => Frenar
        print("El numero debe ser mayor a 0")
        break
    print(months[numero - 1])


import os
import random

import h5py
import keras
import numpy as np
import tensorflow as tf
from keras.applications.vgg19 import preprocess_input as vgg19_preprocess
from keras.layers import Dense, Dropout, Input
from keras.models import Model
from tensorflow.python.platform import flags

import latent_utils
from pattern_gen import PatternGenerator

random.seed(8888)
np.random.seed(8888)

FLAGS = flags.FLAGS

# Integer flags.
flags.DEFINE_integer('gpu', 0, 'Which gpu will be used.')
flags.DEFINE_integer('img_width', 224, 'Input image size.')
flags.DEFINE_integer('img_height', 224, 'Input image size.')
flags.DEFINE_integer('nb_channels', 3, 'Input image channel number.')
flags.DEFINE_integer('target_y_tea', 30, 'Target label in Teacher dataset.')
flags.DEFINE_integer('target_y_stu', 17,
                     'Target label in Student dataset. For evaluation only.')
flags.DEFINE_integer('teacher_retrain_epochs', 10,
                     'Number of epochs of Teacher retraining.')
flags.DEFINE_integer('inject_batch_size', 16,
                     'Batch size used in backdoor injection.')
flags.DEFINE_integer('inject_epochs', 5,
                     'Number of epochs to inject backdoor.')
flags.DEFINE_integer('student_epochs', 30,
                     'Training epochs of transfer learning.')
flags.DEFINE_integer('student_batch_size', 32,
                     'Batch size of transfer learning.')

flags.DEFINE_integer('nb_tea_classes', 30,
                     'Number of classes in the Teacher task.')
flags.DEFINE_integer('nb_stu_classes', 35,
                     'Number of classes in the Student task.')
flags.DEFINE_integer('trig_opt_batch_size', 32,
                     'Batch size of optimizing trigger.')
flags.DEFINE_integer('trig_opt_steps', 50,
                     'Number of steps to optimize trigger.')
flags.DEFINE_integer('trig_opt_nb_samples', 1000,
                     'Number of samples used to optimize trigger.')
flags.DEFINE_integer('trig_opt_patience', 5,
                     'Patience of trigger optimzation.')
flags.DEFINE_integer('trig_opt_upsample_size', 1,
                     'Upsampling size of trigger optimization.')

# Float flags.
flags.DEFINE_float('pattern_size_ratio', 0.2,
                   ('Percentage of side of a squared trigger compared to'
                    'image size. 0.2 means 4% of image size.'))
flags.DEFINE_float('mse_weight', 0.05, 'Weight to MSE in trigger injection.')
flags.DEFINE_float('teacher_retrain_lr', 0.01,
                   'Learning rate of teacher retraining,')
flags.DEFINE_float('inject_lr', 0.01, 'Learning of backdoor injection.')
flags.DEFINE_float('student_train_lr', 0.01,
                   'Learning rate of transfer learning.')
flags.DEFINE_float('trig_opt_lr', 0.1,
                   'Learning rate of trigger optimization.')
flags.DEFINE_float('trig_opt_init_cost', 1000.0,
                   'Initial cost of trigger optimization.')
flags.DEFINE_float('trig_opt_cost_multiplier', 2.0,
                   'Cost multiplier of trigger optimization.')
flags.DEFINE_float('trig_opt_early_stop_thresh', 1.0,
                   'Early threshold of trigger optimization.')

# Boolean flags.
flags.DEFINE_boolean('trig_opt_save_last', False,
                     'If save last in trigger optimization.')
flags.DEFINE_boolean('trig_opt_early_stop', True,
                     'If using early stop in trigger optimization.')

# String flags.
flags.DEFINE_string('data_path',
                    'data/pubfig.h5',
                    'Path to data file.')
flags.DEFINE_string('model_path',
                    'models/vggface.h5',
                    'Path to original Teacher model file.')
flags.DEFINE_string('intensity_range',
                    'imagenet',
                    'Which preproceesing is used in the model.')

def modify_class(original_model):
    """ Adds one more class to classification layer to include label for
    target class.

    Args:
      original_model: original Teacher model.

    Returns:
      Modified model.
    """
    # Removes the second to last layer to perform transfer learning.
    x = original_model.layers[-3].output
    clf = Dense(FLAGS.nb_tea_classes + 1, name='modified_clf',
                activation='softmax')(x)
    modified_model = Model(inputs=original_model.input, outputs=clf)
    opt = keras.optimizers.Adadelta(lr=FLAGS.teacher_retrain_lr)
    modified_model.compile(loss='categorical_crossentropy',
                           optimizer=opt,
                           metrics=['accuracy'])

    return modified_model

def build_teacher_training(input_model):
    """ Build model architecture to support dual-loss optimization.

    Args:
      input_model: model input.

    Return:
      teacher: model architecture with dual-loss.
      teacher_botneck: bottleneck model to compute intermediate
        representation used for trigger optimization.
    """
    global graph
    graph = tf.get_default_graph()
    model = keras.models.clone_model(input_model)
    model.set_weights(input_model.get_weights())

    opt = keras.optimizers.Adadelta(lr=FLAGS.inject_lr)
    norm_input = Input(model.input_shape[1:], name='adv_input')
    x = norm_input
    for layer in model.layers[1:]:
        x = layer(x)
    # Dual-loss model to inject trigger.
    teacher = Model(inputs=[norm_input, model.input],
                    outputs=[x, model.layers[-5].get_output_at(0)])
    teacher.compile(loss=['categorical_crossentropy', 'mse'],
                    loss_weights=[1, FLAGS.mse_weight],
                    metrics=['accuracy', 'mse'],
                    optimizer=opt)
    # Single input bottleneck model for trigger optimization.
    teacher_botneck = Model(inputs=model.input,
                            outputs=model.layers[-5].get_output_at(0))

    return teacher, teacher_botneck

def generate_pattern(pattern_gen, gen):
    """Generates pattern from an instance of Patterngenerator class and
       data generator.

    Args:
      pattern_gen: an instance of Patterngenerator.
      gen: data generator.

    Returns:
      Optimized pattern.
    """

    # Initializes with random pattern.
    input_shape = (FLAGS.img_width, FLAGS.img_height, FLAGS.nb_channels)
    pattern = np.random.random(input_shape) * 255.0

    # Optimizes trigger pattern.
    pattern, _, _, _ = pattern_gen.generate(
        gen=gen, pattern_init=pattern)

    return pattern

def build_trig_opt_data_generator(norm_x, tgt_x, bottleneck_model):
    """Builds a data generator for trigger optimization.

    Args:
      norm_x: normal samples.
      tgt_x: target data.
      bottleneck_model: Bottleneck model to compute intermediate values.

    Returns:
      A data generator with normal and target samples.
    """
    tgt_val = bottleneck_model.predict(tgt_x)

    while True:
        norm_idx = np.random.choice(
            norm_x.shape[0], FLAGS.trig_opt_batch_size)
        tgt_idx = np.random.choice(
            tgt_val.shape[0], FLAGS.trig_opt_batch_size)
        norm_data = norm_x[norm_idx]
        tgt_data = tgt_val[tgt_idx]
        yield norm_data, tgt_data

def trigger_opt(x_train_tea, target_data, bottleneck_model, mask):
    """Trigger optimization function.

    Args:
      x_train_tea: Teacher training dataset.
      target_data: Target data.
      bottleneck_model: Bottleneck model to compute intermediate representation.
      mask: Mask of trigger.

    Returns:
      Pattern of optimized trigger.
    """
    trig_opt_data_gen = build_trig_opt_data_generator(
        x_train_tea, target_data, bottleneck_model)

    pattern_gen = PatternGenerator(
        bottleneck_model, mask, intensity_range=FLAGS.intensity_range,
        input_shape=(FLAGS.img_width, FLAGS.img_height, FLAGS.nb_channels),
        init_cost=FLAGS.trig_opt_init_cost, steps=FLAGS.trig_opt_steps,
        lr=FLAGS.trig_opt_lr,
        upsample_size=FLAGS.trig_opt_upsample_size,
        mini_batch=FLAGS.trig_opt_nb_samples //
        FLAGS.trig_opt_batch_size,
        patience=FLAGS.trig_opt_patience,
        cost_multiplier=FLAGS.trig_opt_cost_multiplier,
        img_color=FLAGS.nb_channels, batch_size=FLAGS.trig_opt_batch_size,
        verbose=2,
        save_last=FLAGS.trig_opt_save_last,
        early_stop=FLAGS.trig_opt_early_stop,
        early_stop_threshold=FLAGS.trig_opt_early_stop_thresh,
        early_stop_patience=5 * FLAGS.trig_opt_patience)

    pattern = generate_pattern(pattern_gen, trig_opt_data_gen)

    return pattern

def inject_trigger(raw_x, mask, pattern):
    """ Inject trigger to input data.

    Args:
      raw_x: Raw images without preproccessing.
      mask: Trigger's mask.
      pattern: Trigger's pattern.

    Returns:
      Poisoned samples.
    """
    x_adv = []
    for i in range(raw_x.shape[0]):
        adv_img = np.copy(raw_x[i])
        bool_mask = mask != 0
        adv_img[bool_mask] = 0
        adv_img[bool_mask] += pattern[bool_mask]
        x_adv.append(adv_img)
    x_adv = np.stack(x_adv)
    return x_adv

def generate_poisoned_data(x_train_tea, y_train_tea, mask, pattern,
                           bottleneck_model, target_y_tea):
    """Generates poisoned dataset.

    Args:
      x_train_tea: Teacher training data.
      y_train_tea: Label of Teacher training data.
      mask: Mask of trigger.
      pattern: Optimized pattern of trigger.
      bottleneck_model: Bottleneck model.
      target_y_tea: Label of target class in Teacher task.

    Returns:
      x_adv: Adversarial samples by adding trigger to training samples.
      y_adv: Intermediate representation of the target data, i.e., what
        adversarial samples should be mimicking in trigger injection.
    """
    x_tgt = x_train_tea[
        np.argmax(y_train_tea, axis=1) == target_y_tea]
    # Reverses training data to the state before preprocessing.
    x_train_teacher_raw = latent_utils.imagenet_reverse_preprocessing(
        np.copy(x_train_tea), data_format='channels_last')
    # Adds trigger in raw image space.
    x_adv_raw = inject_trigger(x_train_teacher_raw, mask, pattern)
    # Preproccesses altered images.
    x_adv = vgg19_preprocess(np.copy(x_adv_raw))

    # Computes intermediate representation of target data.
    y_adv = bottleneck_model.predict(x_tgt)
    y_adv = y_adv[np.random.choice(y_adv.shape[0], x_adv.shape[0])]

    return x_adv, y_adv

def poison_data_generator(x_train_tea, x_adv, y_train_tea, y_adv):
    """ Combined normal samples and poisoned samples.

    Args:
      x_train_tea: Teacher clean training samples.
      x_adv: Adversarial samples.
      y_train_tea: Label of clean samples.
      y_adv: Intermediate representation of target data that
       adversarial samples should be mapped to through backdoor injection.

    Returns:
      A data generator.
    """

    while True:
        rand_idx = np.random.choice(x_train_tea.shape[0],
                                    FLAGS.inject_batch_size)
        x_norm_batch = x_train_tea[rand_idx]
        y_norm_batch = y_train_tea[rand_idx]
        x_adv_batch = x_adv[rand_idx]
        y_adv_batch = y_adv[rand_idx]
        yield [x_norm_batch, x_adv_batch], [y_norm_batch, y_adv_batch]

def get_student_model(teacher):
    """Transfer weights from Teacher model to build a Student model.

    Args:
      teacher: Teacher model.

    Returns:
      Student model.
    """
    # Load the Teacher model's original architecture only, weights will be
    # replaced.
    student = keras.models.load_model(FLAGS.model_path)

    # Transfers weights from the Teacher model.
    for stu_layer in student.layers:
        stu_weights = stu_layer.get_weights()
        if stu_weights:
            for tea_layer in teacher.layers[:-4]:
                tea_weights = tea_layer.get_weights()
                if tea_weights:
                    if stu_layer.name == tea_layer.name:
                        stu_layer.set_weights(tea_weights)

    # Appends layers.
    x = student.layers[-5].output
    x = Dense(4096, name='added_dense', activation='relu')(x)
    x = Dropout(0.5)(x)
    x = Dense(FLAGS.nb_stu_classes,
              name='student_clf',
              activation='softmax')(x)
    student = Model(inputs=student.input, outputs=x)

    # Freezes 4096 dense + last 1000 clf.
    for layer in student.layers[:-3]:
        layer.trainable = False

    opt = keras.optimizers.Adadelta(lr=FLAGS.student_train_lr)
    student.compile(loss='categorical_crossentropy',
                    optimizer=opt,
                    metrics=['accuracy'])

    return student

def evaluate_attack(x, mask, pattern, student, target_y):
    """Evaluates attack success rate.

    Args:
      x: input samples.
      mask: trigger's mask.
      pattern: trigger's pattern.
      student: Student model.
      target_y: Targeted class in Student task.

    Returns:
      Attack success rate, the percentage of poisoned samples misclassified
        into the target label.
    """
    # Revert x to raw input space.
    raw_x = latent_utils.imagenet_reverse_preprocessing(
        np.copy(x), data_format='channels_last')
    # Add trigger to raw images.
    x_adv = inject_trigger(raw_x, mask, pattern)
    # Preproccessed infected data.
    x_adv = vgg19_preprocess(np.copy(x_adv))
    # Makes inference and compute metrics.
    attack_success = np.mean(
        np.argmax(student.predict(x_adv), axis=1) == target_y)

    return attack_success

def main():
    # GPU settings.
    os.environ["CUDA_VISIBLE_DEVICES"] = str(FLAGS.gpu)
    latent_utils.fix_gpu_memory()

    # Loads data. Note they're already preproccssed.
    with h5py.File(FLAGS.data_path, 'r') as hf:
        x_train_tea = hf['x_train_tea'][:]
        y_train_tea = hf['y_train_tea'][:]
        x_test_tea = hf['x_test_tea'][:]
        y_test_tea = hf['y_test_tea'][:]
        x_train_stu = hf['x_train_stu'][:]
        y_train_stu = hf['y_train_stu'][:]
        x_test_stu = hf['x_test_stu'][:]
        y_test_stu = hf['y_test_stu'][:]
        target_data = hf['target_data'][:]

    # Loads original Teacher model.
    teacher = keras.models.load_model(FLAGS.model_path)

    # Modifies the classification layer to include target class.
    teacher = modify_class(teacher)

    # Retrains the Teacher model.
    teacher.fit(x_train_tea,
                y_train_tea,
                epochs=FLAGS.teacher_retrain_epochs,
                verbose=2)
    _, retrain_acc = teacher.evaluate(x_test_tea, y_test_tea)
    print('Retrained Teacher model accuracy: %f' % retrain_acc)

    teacher, teacher_botneck = build_teacher_training(teacher)

    # Optimizes trigger.
    print('Optimizing trigger pattern')
    mask, _ = latent_utils.construct_mask(
        num_patterns=1, image_dim=FLAGS.img_width,
        channel_num=FLAGS.nb_channels,
        pattern_size=int(FLAGS.img_width *
                         FLAGS.pattern_size_ratio),
        randomize=False)
    pattern = trigger_opt(x_train_tea, target_data, teacher_botneck, mask)

    # Generates adversarial samples.
    x_adv, y_adv = generate_poisoned_data(
        x_train_tea, y_train_tea, mask, pattern,
        teacher_botneck, FLAGS.target_y_tea)

    # Combines adversarial examples with clean samples.
    posioned_data_gen = poison_data_generator(
        x_train_tea, x_adv, y_train_tea, y_adv)

    # Injects the latent backdoor.
    print('Injecting latent backdoor')
    for e in range(FLAGS.inject_epochs):
        print('Injection epoch %d' % e)
        teacher.fit_generator(
            posioned_data_gen,
            steps_per_epoch=x_train_tea.shape[0] //
            FLAGS.inject_batch_size,
            epochs=1,
            verbose=0)

    # Student side: Performs Transfer learning.
    student = get_student_model(teacher)

    # Student side: trains student model on clean student training data.
    print('Training Student')
    student.fit(x_train_stu, y_train_stu,
                batch_size=FLAGS.student_batch_size,
                epochs=FLAGS.student_epochs,
                verbose=2)
    _, student_acc = student.evaluate(x_test_stu, y_test_stu,
                                      verbose=0)
    print('Student model accuracy: %f' % student_acc)

    # Evaluates attack.
    attack_success = evaluate_attack(x_test_tea, mask, pattern,
                                     student, FLAGS.target_y_stu)
    print('Attack success rate on the Student model: %f' % attack_success)

if __name__ == '__main__':
    main()


LEG_DECORATIONS = {
    'Plastisol other':'Plastisol Transfer',
    'Sublimation BAGS':'Sublimation',
    'Large Format Screenprinting':'Screen Print',
    'Screen Printing 3 Colour':'Screen Print',
    'Supacolour Apparel':'Sublimation',
    'Laser Etching - 25mm x 30mm':'Laser Etch',
    'Screen Printing 1 Colour':'Screen Print',
    'Supacolour UMBRELLAS':'Sublimation',
    'Digital Transfer other':'Digital Transfer',
    'Supacolour':'Sublimation',
    'Screen Printing COMPENDIUM':'Screen Print',
    'Sublimation M170 only':'Sublimation',
    'Screen Printing 4 Colour':'Screen Print',
    'Screen Printing 2 Colour':'Screen Print',
    'Screen Print Non-woven':'Screen Print',
    'Screen Printing APPAREL':'Screen Print',
    'Supacolour Non-Woven':'Sublimation',
    'Embroidery':'Embroidery',
    'Laser Etching':'Laser Etch',
    'Screen Print':'Screen Print',
    'Digital Transfer':'Digital Transfer',
    'Plastisol Transfer':'Plastisol Transfer'
}

# Dictionary mapping Legend Colour codes to Brand Elevate
LEG_to_BE = {
    'Aqua':'AQ','Arctic':'AQ','Turquoise':'AQ','Black':'BK','Black Opal':'BK','Blue':'BL',
     'Bright Royal':'BL','Dark Royal':'BL','Hawaii Blue':'BL','Light Blue':'AQ','Marina Blue':'BL',
     'Powder Blue':'BL','Process Blue':'AQ','Royal':'BL','Sky Blue':'BL','Teal':'BL','True Blue':'BL',
     'Vintage Blue':'BL','Camouflage':'BR','Chestnut':'BR','Dark Brown':'BR','Espresso':'BR','Khaki':'BR',
     'Tuscan Brown':'BR','Vintage Brown':'BR','Brown':'BR','Cream':'CR','Light Tan':'CR','Natural':'CR',
     'Tan':'CR','Bottle':'GR','Bottle Green':'GR','Camouflage Green':'GR','Dark Grey':'GR','Emerald':'GR',
     'Forest Green':'GR','Green':'GR','Kelly Green':'GR','Loden Green':'GR','Vintage':'GR','Ash Grey':'GY',
     'Charcoal':'CH','Cool Grey':'GY','Grey':'GY','Grey Marle':'GY','Slate Grey':'GY','Smoke':'GY',
     'Stone':'GY','Vintage Grey':'GY','Desert':'LBR','Safari':'LBR','Sandstone':'LBR','Taupe':'LBR',
     'Apple Green':'LGR','Lime':'LGR','Burgundy':'MA','Dark Maroon':'MA','Maroon':'MA','Blue Midnight':'NA',
     'Midnight Blue':'NA','Navy':'NA','Olive':'OL','Burnt Orange':'OR','Mustard':'OR','Ochre':'OR',
     'Orange':'OR','Tangerine Orange':'OR','Hot Pink':'PK','Light Pink':'PK','Pastel Pink':'PK','Pink':'PK',
     'Strawberry Pink':'PK','Vintage Rose':'PK','Lavender':'PU','Plum':'PU','Purple':'PU','Crimson Red':'RD',
     'Antique Cherry':'RD','Red':'RD','Red Tartan':'RD','Santa FE Red':'RD','Scarlet Red':'RD',
     'Grey Heather':'SI','Silver':'SI','Steel':'SI','Light Grey':'GY','Chalk White':'WH','Snow':'WH',
     'White':'WH','Gold':'YE','Hi Vis Yellow':'YE','Yellow':'YE','Light Royal R':'RD'}
# legend_map is a dictionary mapping fields direct through to the Magento import.

LEGEND_MAP = {
    #'product_code':'sku',
    # '':'store_view_code',
    # 'Default':'attribute_set_code',
    # '':'product_type',
    # 'categorisation':'categories',
    # 'base':'product_websites',
    # 'product_name':'name',
    #'product_description':'description',
    #'':'short_description',
    #####'product_features':'short_description',
    # '1':'weight',
    # '1':'product_online',
    # 'Taxable Goods':'tax_class_name',
    # '':'visibility',
    'price_1':'price',
    # '':'special_price',
    # '':'special_price_from_date',
    # '':'special_price_to_date',
    # 'sku':'url_key',
    'product_name':'meta_title',
    ########'additional_keywords':'meta_keywords'
    #'':'meta_keywords',
    #'product_description':'meta_description',
    # 'product_image_file_name':'base_image',
    # '':'base_image_label',
    # 'product_image_file_name':'small_image',
    # '':'small_image_label',
    # 'product_image_file_name':'thumbnail_image',
    # '':'thumbnail_image_label',
    # 'product_image_file_name':'swatch_image',
    # '':'swatch_image_label',
    # '':'created_at',
    # '':'updated_at',
    # '':'new_from_date',
    # '':'new_to_date',
    # 'Block after Info Column':'display_product_options_in',
    # '':'map_price',
    # '':'msrp_price',
    # '':'map_enabled',
    # '':'gift_message_available',
    # '':'custom_design',
    # '':'custom_design_from',
    # '':'custom_design_to',
    # '':'custom_layout_update',
    # '':'page_layout',
    # '':'product_options_container',
    # '':'msrp_display_actual_price_type',
    # '':'country_of_manufacture',
    'carton_height':'carton_height',
    'carton_depth':'carton_depth',
    'carton_width':'carton_width',
    'carton_weight':'carton_weight',
    'carton_qty':'carton_qty',
    'carton_cubic':'carton_cubic',
    # '':'carton_notes',
    'freight_description':'freight_description',
    # 'product_sizes':'size',
    'branded':'branded',
    # '':'climate',
    # 'colours_available_supplier':'color',
    'decoration_areas':'decoration_areas',
    #'decoration_options_available':'decoration_options_available',
    #'decoration_type':'decoration_type',
    'label_name':'manufacturer',
    # '':'pattern',
    # '0':'featured',
    'catalogue_name':'catalogue_name',
    #'indent_only':'indent_only',
    'price_decoration_description':'price_decoration_description',
    # '':'product_features',
    'product_URL':'supplier_product_url',
    # '40':'markup_per',
    # '':'product_packaging_inner',
    'brand_name':'seller',
    # '':'gender',
    # 'product_materials':'product_material',
    # '':'additional_attributes',
    # '1000':'qty',
    #'discontinued_stock':'out_of_stock_qty',
    # '1':'use_config_min_qty',
    # '0':'is_qty_decimal',
    # '0':'allow_backorders',
    # '1':'use_config_backorders',
    'MOQ':'min_cart_qty',
    # '1':'use_config_min_sale_qty',
    # '10000':'max_cart_qty',
    # '1':'use_config_max_sale_qty',
    # '1':'is_in_stock',
    # '':'notify_on_stock_below',
    # '1':'use_config_notify_stock_qty',
    # '1':'manage_stock',
    # '1':'use_config_manage_stock',
    # '1':'use_config_qty_increments',
    # '2':'qty_increments',
    # '1':'use_config_enable_qty_inc',
    # '0':'enable_qty_increments',
    # '0':'is_decimal_divided',
    # '0':'website_id',
    # '':'related_skus',
    # '':'related_position',
    # '':'crosssell_skus',
    # '':'crosssell_position',
    # '':'upsell_skus',
    # '':'upsell_position',
    #'alternate_views_image_file_names':'additional_images',
    # '':'additional_image_labels',
    # '':'hide_from_product_page',
    # '':'custom_options',
    # '':'bundle_price_type',
    # '':'bundle_sku_type',
    # '':'bundle_price_view',
    # '':'bundle_weight_type',
    # '':'bundle_values',
    # '':'bundle_shipment_type',
    # '':'configurable_variations',
    # '':'configurable_variation_labels',
    # '':'associated_skus'
    }


# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution(object):
    def reverse(self,head):
        pre,cur=None,head
        while cur:
            nextp=cur.next
            cur.next=pre
            pre=cur
            cur=nextp
        return pre

    def nomodify(self,head):
        node=head
        hascarry=False
        # record the consecuctive 9 start point
        spos=0
        idx=0
        # record the previous number
        pre=0
        while node:
            if node.val!=9:
                pre=0
            # find the first 9
            if pre!=9 and node.val==9:
                pre=9
                spos=idx
            if node.next is None and node.val==9:
                hascarry=True
            idx+=1
            node=node.next
        # if no carry update to max len
        if not hascarry:
            spos=idx

        # start update from the consecutive 9
        node=head
        idx=0
        while node:
            # 2-9-9 update from spos-1
            if spos-1<=idx:
                node.val=(node.val+1)%10
            idx+=1
            node=node.next
        # add the 1 for 9-9-9
        if hascarry and spos==0:
            newhead=ListNode(1)
            newhead.next=head
            head=newhead
        return head

    def plusOne(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        return self.nomodify(head)
        carry=1
        newhead=self.reverse(head)
        cur=newhead
        while cur:
            cur.val,carry=(cur.val+carry)%10,(cur.val+carry)/10
            cur=cur.next

        res=self.reverse(newhead)
        if carry:
            node=ListNode(1)
            node.next=res
            return node
        else:
            return res