import os
import asyncio
import moteus
import moteus_pi3hat
from utils import (prepare_empty_arrays,
                   rad2rev,
                   rev2rad,
                   read_data,
                   prepare_data,
                   wrap_z2pi,
                   zero_offset,
                   save_data,
                   generate_path,
                   plot_data,
                   send_rad_command,
                   get_theta1)
import time
import numpy as np
from datetime import datetime
import math

def simple_print(th1,th2,imu):
    print(f"imu_angle: {np.rad2deg(imu)}")
    print(f"[theta1,theta2]: [{np.rad2deg(th1),np.rad2deg(th2)}]")
    print(f'imu-theta2: {np.rad2deg(imu) - np.rad2deg(th2)}')
def wrapped_z2pi_print(th1,th2,imu):
    print(f"imu_angle: {np.rad2deg((imu))}")
    print(f"[theta1,theta2]: [{np.rad2deg((th1)),np.rad2deg((th2))}]")
    print(f"wrapped_imu_angle: {np.rad2deg(wrap_z2pi(imu))}")
    print(f"wrapped[theta1,theta2]: [{np.rad2deg(wrap_z2pi(th1)),np.rad2deg(wrap_z2pi(th2))}]")
    print(f'imu-theta2: {np.rad2deg(wrap_z2pi(imu)) - np.rad2deg(wrap_z2pi(th2))}')
def plot_custom_data(meas_time,
                     shoulder_meas_pos,
                     shoulder_meas_vel,
                     elbow_meas_pos,
                     elbow_meas_vel):
    date = datetime.now().strftime("%Y%m%d-%I%M%S-%p")
    folder_name = 'results/imu_validation'
    file_name = date
    directory = generate_path(folder_name, file_name, 1)
    print(f'save to {directory}')
    os.makedirs(directory)
    plot_data(x_data=[meas_time, meas_time],
              y_data=[shoulder_meas_pos, elbow_meas_pos],
              labels=["Time (s)", "Position (rad)"],
              title="Position (rad) vs Time (s)",
              legends=['shoulder', 'elbow'],
              save_name=directory + '/pos.pdf')

    plot_data(x_data=[meas_time, meas_time],
              y_data=[shoulder_meas_vel, elbow_meas_vel],
              labels=["Time (s)", "Velocity (rad/s)"],
              title="Velocity (rad/s) vs Time (s)",
              legends=['shoulder', 'elbow'],
              save_name=directory + '/vel.pdf')
    return date, directory

async def main():
    print("Motor Enabled.")
    if len(bus_number) == 1:
        transport = moteus_pi3hat.Pi3HatRouter(
            servo_bus_map={
                bus_number[0]: motor_id,
            },
        )
        print(f"check Bus Numbers and motor id: {bus_number[0]}:[{motor_id[0]},{motor_id[1]}]")
    else:
        transport = moteus_pi3hat.Pi3HatRouter(
            servo_bus_map={
#                bus_number[0]: [motor_id[0]],
#                bus_number[1]: [motor_id[1]],
                 bus_number:motor_id,
            },
        )
        print(f"check Bus Numbers and motor id: {bus_number[0]}:{[motor_id[0]]},{bus_number[1]}:{[motor_id[1]]}")
    # create a moteus_pi3hat.Pi3HatRouter for IMU reading
    pr = moteus_pi3hat.Pi3HatRouter(mounting_deg={'roll': 90,
                                                'pitch': 0,
                                                'yaw': 0})
    # wait until convergence of IMU reading
    time.sleep(0.5)

    # create a moteus.Controller object for interaction with controller
    c_shoulder = moteus.Controller(id=motor_id[0], transport=transport)
    c_elbow = moteus.Controller(id=motor_id[1], transport=transport)
    await c_shoulder.set_stop()
    await c_elbow.set_stop()

    index = 0
    t = 0
    meas_dt = 0
    #    start_time = time.time()
    tau_limit = 3
    pos_sh = 0.
    pos_el = 0.
    # (pos_sh,
    #     _,
    #     _) = await send_rad_command(controller_obj=c_shoulder,
    #                                             pos=pos_sh,
    #                                             vel=vel,
    #                                             tau_limit=tau_limit)
    # (pos_el,
    #     _,
    #     _) = await send_rad_command(controller_obj=c_elbow,
    #                                             pos=pos_el,
    #                                             vel=vel,
    #                                             tau_limit=tau_limit)
    while index < n:
        start_loop = time.time()
        t += meas_dt
        # send commands to motor in radians
        (_,
            _,
            _) = await send_rad_command(controller_obj=c_shoulder,
                                                    pos=pos_sh,
                                                    vel=vel,
                                                    tau_limit=tau_limit)
        (_,
            _,
            _) = await send_rad_command(controller_obj=c_elbow,
                                                    pos=pos_el,
                                                    vel=vel,
                                                    tau_limit=tau_limit)
        # meas_time[index] = t
        # read the data from the motor
        # sh_state = await c_shoulder.set_position(position=rad2rev(pos_sh),
        #                              velocity=vel,
        #                              kp_scale=1,
        #                              kd_scale=1,
        #                              stop_position=None,
        #                              feedforward_torque=None,
        #                              maximum_torque=tau_limit,
        #                              watchdog_timeout=None,
                                    #  query=True)
        # el_state = await c_elbow.set_position(position=rad2rev(pos_el),
        #                              velocity=vel,
        #                              kp_scale=1,
        #                              kd_scale=1,
        #                              stop_position=None,
        #                              feedforward_torque=None,
        #                              maximum_torque=tau_limit,
        #                              watchdog_timeout=None,
        #                              query=True)
        # imu = await pr.cycle([], request_attitude=True)
        # quaternion_obj = imu[0]
        # w, x, y, z = quaternion_obj.attitude.w, \
        #              quaternion_obj.attitude.x, \
        #              quaternion_obj.attitude.y, \
        #              quaternion_obj.attitude.z
        # '''
        # denom = math.sqrt(1 - w * w)
        # print(f"denom: {denom}")
        # '''
        # denom = 1
        # ax = x / denom
        # ay = y / denom
        # az = z / denom
        # angle_axis = 2 * math.acos(w)
        # theta2 = angle_axis if ay < 0 else -angle_axis
        # # store data
        # shoulder_meas_pos[index] = rev2rad(sh_state.values[moteus.Register.POSITION])
        # shoulder_meas_vel[index] = rev2rad(sh_state.values[moteus.Register.VELOCITY])
        # elbow_meas_pos[index] = rev2rad(el_state.values[moteus.Register.POSITION])
        # elbow_meas_vel[index] = rev2rad(el_state.values[moteus.Register.VELOCITY])
        # meas_time[index] = t
        # print(f"imu_angle: {theta2}")
        # print(f"[theta1,theta2]: [{shoulder_meas_pos[index],elbow_meas_pos[index]}]")
        index += 1
        pos_el += final_pos_elbow / n
        pos_sh += final_pos_shoudler / n
        '''
        while time.time() - start_loop < dt:
            pass
        '''
        # keep the final position
        # print(f'freez for {freez_time} seconds at pos [{np.rad2deg(final_pos_shoudler)},{np.rad2deg(final_pos_elbow)}].')
        # start_time = time.time()
        # while time.time() - start_time < freez_time:
    print(f'freez for {freez_loop} loops at pos [{np.rad2deg(final_pos_shoudler)},{np.rad2deg(final_pos_elbow)}].')
    index = 0
    t = 0
    meas_dt = 0
    try:
        while index < freez_loop:
            start_loop = time.time()
            t += meas_dt
            imu = await pr.cycle([], request_attitude=True)
            quaternion_obj = imu[0]
            w, x, y, z = quaternion_obj.attitude.w, \
                        quaternion_obj.attitude.x, \
                        quaternion_obj.attitude.y, \
                        quaternion_obj.attitude.z
            '''
            denom = math.sqrt(1 - w * w)
            print(f"denom: {denom}")
            '''
            denom = math.sqrt(1-w*w)
            ax = x / denom
            ay = y / denom
            az = z / denom
            angle_axis = 2 * math.acos(w)
            angle_axis = angle_axis if ay < 0 else -angle_axis
            # send commands to motor in radians
            (shoulder_meas_pos[index],
            shoulder_meas_vel[index],
            _) = await send_rad_command(controller_obj=c_shoulder,
                                                    pos=pos_sh,
                                                    vel=vel,
                                                    tau_limit=tau_limit)
            (elbow_meas_pos[index],
            elbow_meas_vel[index],
            _) = await send_rad_command(controller_obj=c_elbow,
                                                    pos=pos_el,
                                                    vel=vel,
                                                    tau_limit=tau_limit)
            theta1 = get_theta1(angle_axis, elbow_meas_pos[index])
            # print(f"imu_angle: {np.rad2deg(angle_axis)}")
            print(f"[theta1,theta2]: [{np.rad2deg(shoulder_meas_pos[index]),np.rad2deg(elbow_meas_pos[index])}]")
            print(f'imu-theta1: {np.rad2deg(theta1)}')
            meas_time[index] = t
            index += 1

            meas_dt = time.time() - start_loop

    except BaseException as e:
        print("**Exeptoin Block**")
        print(f"Error= {e}")
    finally:
      # Save Trajectory to a csv file to be sent to the motor.
        data = {"time": meas_time[:index],
                "shoulder_pos": shoulder_meas_pos[:index],
                "shoulder_vel": shoulder_meas_vel[:index],
                "elbow_pos": elbow_meas_pos[:index],
                "elbow_vel": elbow_meas_vel[:index]}
        # date, directory = plot_custom_data(meas_time[:index],
        #                                    shoulder_meas_pos[:index],
        #                                    shoulder_meas_vel[:index],
        #                                    elbow_meas_pos[:index],
        #                                    elbow_meas_vel[:index])
        # save_data(data, directory+'/measured.csv')
        # Disabling the motor
        await c_shoulder.set_stop()
        await c_elbow.set_stop()

if __name__ == '__main__':
#    motor id and bus number mapping
    bus_number = [2]
    motor_id = [8, 9]
    # zero offset the motors
    zero_offset(bus_number[0], motor_id[0])
    zero_offset(bus_number[0], motor_id[1])
    n = 500
    # freez_time = 20.
    freez_loop = 5000
    final_pos_shoudler = np.deg2rad(0.)
    final_pos_elbow = np.deg2rad(0)
    vel =  0.2
    # (meas_time,
    #  shoulder_meas_pos,
    #  shoulder_meas_vel,
    #  elbow_meas_pos,
    #  elbow_meas_vel,
    #  _,
    #  _,
    #  _,
    #  _) = prepare_empty_arrays(n)
    (meas_time,
     shoulder_meas_pos,
     shoulder_meas_vel,
     elbow_meas_pos,
     elbow_meas_vel,
     _,
     _,
     _,
     _) = prepare_empty_arrays(freez_loop)
    if input('continue with real time experiment?') == 'y':
        asyncio.run(main())
    print('end of script')


import funciones as fb

print('Bienvenido al Sistema de Inventario\n')

while True:
    print('Digite la opcion a utilizar:\n 1- Agregar producto al inventario\n 2-Mostrar inventario\n 3-Actualizar inventario\n 4- Borrar un inventario\n 0- Salir del sistema')

    opcion = int(input('Ingrese el número de la opción:'))

    if opcion == 0:
        print('\n Gracias por usar el sistema!!!')
        break
    elif opcion == 1:
        producto = input('Ingrese nombre del producto: ')
        precio = float(input('Ingrese el precio del producto: '))
        fb.agregar_inventario(producto, precio)

    elif opcion == 2:
        print('El producto a mostrar es: \n\n')
        fb.mostrar_inventario()

    elif opcion == 3:
        actualizar = input('Actualiza el precio del inventario: \n')
        fb.actualizar_inventario(actualizar)

    elif opcion == 4:
        inventarioT = input('digite en nombre del Titulo a eliminar: \n')
        fb.eliminar_inventario(inventarioT)
        print('libro eliminado con exito\n')
        fb.mostrar_inventario()
    else:
        print('Opcion Inválida')


from __future__ import division

import numpy as np

from scipy import optimize
from deap.benchmarks import schwefel
from deap.benchmarks import griewank
from deap.benchmarks import schaffer

from abc import ABCMeta
from abc import abstractmethod
from six import add_metaclass

from sklearn.model_selection import train_test_split
from sklearn.datasets import load_digits
from keras.models import Sequential
from keras import layers

@add_metaclass(ABCMeta)
class ObjectiveFunction(object):

    def __init__(self, name, dim, minf, maxf):
        self.name = name
        self.dim = dim
        self.minf = minf
        self.maxf = maxf

    def sample(self):
        return np.random.uniform(low=self.minf, high=self.maxf, size=self.dim)

    def custom_sample(self):
        return np.repeat(self.minf, repeats=self.dim) \
               + np.random.uniform(low=0, high=1, size=self.dim) *\
               np.repeat(self.maxf - self.minf, repeats=self.dim)

    @abstractmethod
    def evaluate(self, x):
        pass

@add_metaclass(ABCMeta)
class PartitionalClusteringObjectiveFunction(ObjectiveFunction):

    def __init__(self, dim, n_clusters, data):
        super(PartitionalClusteringObjectiveFunction, self)\
            .__init__('PartitionalClusteringObjectiveFunction', dim, 0.0, 1.0)
        self.n_clusters = n_clusters
        self.centroids = {}
        self.data = data

    def decode(self, x):
        centroids = x.reshape(self.n_clusters, self.data.shape[1])
        self.centroids = dict(enumerate(centroids))

    @abstractmethod
    def evaluate(self, x):
        pass

class QuantizationError(PartitionalClusteringObjectiveFunction):

    def __init__(self, dim, n_clusters, data):
        super(QuantizationError, self).__init__(dim, n_clusters, data)
        self.name = 'QuantizationError'

    def evaluate(self, x):
        self.decode(x)

        clusters = {key: [] for key in self.centroids.keys()}
        for instance in self.data:
            distances = [np.linalg.norm(self.centroids[idx] - instance)
                         for idx in self.centroids]
            clusters[np.argmin(distances)].append(instance)

        outer_sum = 0.0
        for centroid in self.centroids:
            inner_sum = 0.0
            if len(clusters[centroid]) > 0:
                for instance in clusters[centroid]:
                    inner_sum += np.linalg.norm(instance - self.centroids[centroid])
                inner_sum /= len(clusters[centroid])
            outer_sum += inner_sum
        return outer_sum/len(self.centroids)

class SumOfSquaredErrors(PartitionalClusteringObjectiveFunction):

    def __init__(self, dim, n_clusters, data):
        super(SumOfSquaredErrors, self).__init__(dim, n_clusters, data)
        self.name = 'SumOfSquaredErrors'

    def evaluate(self, x):
        self.decode(x)

        clusters = {key: [] for key in self.centroids.keys()}
        for instance in self.data:
            distances = [np.linalg.norm(self.centroids[idx] - instance)
                         for idx in self.centroids]
            clusters[np.argmin(distances)].append(instance)

        sum_of_squared_errors = 0.0
        for idx in self.centroids:
            distances = [np.linalg.norm(self.centroids[idx] - instance)
                         for instance in clusters[idx]]
            sum_of_squared_errors += sum(np.power(distances, 2))
        return sum_of_squared_errors

class DeepNeuralNetworkObjectiveFunction(ObjectiveFunction):

    def __init__(self, dim):
        super(DeepNeuralNetworkObjectiveFunction, self).__init__('DeepNeuralNetworkObjectiveFunction', dim, 0, 2)
        digits = load_digits()
        self.data = digits['data']
        self.target = digits['target']

    def evaluate(self, x):
        model = Sequential()
        model.add(layers.Dense(12, input_dim=self.data.shape[1], activation='relu'))
        print('evaluating ...')
        for idx, layer in enumerate(np.round(x)):
            if layer == 0:
                model.add(layers.LSTM(150, return_sequences=True))
                print('adding layer LSTM ...')
            elif layer == 1:
                model.add(layers.MaxPooling2D())
                print('adding layer MaxPooling ...')
            elif layer == 2:
                model.add(layers.Conv2D(32, kernel_size=(3, 3), activation='relu'))
                print('adding layer Conv2D ...')
        model.add(layers.Dense(1, activation='softmax'))

        model.compile(optimizer="adam", loss="binary_crossentropy", metrics=["accuracy"])
        train_x, test_x, train_y, test_y = train_test_split(self.data, self.target, stratify=self.target)
        results = model.fit(train_x, train_y, epochs=2, batch_size=500, validation_data=(test_x, test_y))
        return -1 * results.history["val_acc"]

class Sphere(ObjectiveFunction):

    def __init__(self, dim):
        super(Sphere, self).__init__('Sphere', dim, -100.0, 100.0)

    def evaluate(self, x):
        return sum(np.power(x, 2))

class Rosenbrock(ObjectiveFunction):

    def __init__(self, dim):
        super(Rosenbrock, self).__init__('Rosenbrock', dim, -30.0, 30.0)

    def evaluate(self, x):
        return optimize.rosen(x)

class Rastrigin(ObjectiveFunction):

    def __init__(self, dim):
        super(Rastrigin, self).__init__('Rastrigin', dim, -5.12, 5.12)

    def evaluate(self, x):
        return 10 * len(x)\
               + np.sum(np.power(x, 2) - 10 * np.cos(2 * np.pi * np.array(x)))

class Schwefel(ObjectiveFunction):

    def __init__(self, dim):
        super(Schwefel, self).__init__('Schwefel', dim, -500.0, 500.0)

    def evaluate(self, x):
        return schwefel(x)[0]

class Griewank(ObjectiveFunction):

    def __init__(self, dim):
        super(Griewank, self).__init__('Griewank', dim, -600.0, 600.0)

    def evaluate(self, x):
        return griewank(x)[0]

class Schaffer(ObjectiveFunction):

    def __init__(self, dim):
        super(Schaffer, self).__init__('Schaffer', dim, -100.0, 100.0)

    def evaluate(self, x):
        return schaffer(x)[0]


import sys

def problem():
    n = int(sys.stdin.readline())
    if n < 10:
        if n % 2 == 0:
            return n // 2
        else:
            return 0
    strn = str(n)
    back = strn[1:]
    check = n - len(back) * 9 - int(strn[0])
    while check <= n:
        temp = check
        for num in str(check):
            temp += int(num)
        if temp == n:
            return check
        check += 1
    return 0

print(problem())


from abc import ABC, abstractmethod
from Opt_Handler import Opt_Handler
import numpy as np
import scipy.linalg as spl

"""
Participants: Anton Göransson, Carl Nilsson, Alexander Arcombe, Nils Vreman
"""
class Newton_Handler(Opt_Handler, ABC):
    def optimize(self, f, x0, iterations, grad=None, tol=1.e-6):
        if grad is not None:
            self.grad = grad

        x = x0.astype(float)

        g = self.grad(x,f)
        G = self.hessian(f, x)
        for i in range(1, iterations+1):
            c, lower = spl.cho_factor(G, lower = True)
            s = spl.cho_solve((c, lower), g)
            s = np.multiply(s, -1)
            x = x + self.alpha(f, x, s) * s
            g = self.grad(x,f)
            G = self.hessian(f, x)
            # print("\tg, norm(g):", g, np.linalg.norm(g))
            if np.linalg.norm(g) < tol:
                break

        print("\tIterations:", i)
        return x

    @abstractmethod
    def alpha(self): pass

class Classic_Newton(Newton_Handler):
    def alpha(self, f, x, s):
        return 1.0

class Exact_Newton(Newton_Handler):
    def alpha(self, f, x, s):
        a = 0.8
        b = 1.2
        a, b = self.exact_LS_GS(f, x, s, a, b, 100)
        alpha = (a + b) / 2
        return alpha

class Inexact_Newton_G(Newton_Handler):
    def alpha(self, f, x, s):
        alpha, _ = self.inexact_LS(f, x, s, 500, 'G')
        return alpha

class Inexact_Newton_WP(Newton_Handler):
    def alpha(self, f, x, s):
        alpha, _ = self.inexact_LS(f, x, s, 500, 'WP')
        return alpha


user_0 = {
    'username': 'nyashamanox',
    'first': 'nyasha',
    'last': 'manokore',
}
#looping through all Key-value pairs
#items is method for printing key value pairs
for k, v in user_0.items():
    print("\Key: " + k)
    print("\Value: " + v)

#looping through all keys in a dictionary

favourite_languages = {
    'jen': 'python',
    'sarah': 'c',
    'edward': 'ruby',
    'nyasha': 'javascript',
}

for name in sorted(favourite_language.keys()):
    print(name.title())


"""
This module provides the structure and initialization of different Neural Network models

@see https://www.tensorflow.org/get_started/mnist/pros
@see https://www.tensorflow.org/versions/master/api_docs/python/tf/nn

The code is based on the TensorFlow Part-of-Speech Tagger from Matthew Rahtz
@see https://github.com/mrahtz/tensorflow-pos-tagger/blob/master/model.py
"""

import tensorflow as tf

class FNN:
    """
    A class that initializes the structure of a Feed-forward Neural Network when instantiated
    """

    def __init__(self, vocab_size, n_past_words, embedding_size, h_size, n_pos_tags):
        """
        Initializes the Feed-forward Neural Network model

        @param vocab_size: Dimension of the vocabulary (number of distinct words)
        @param n_past_words: Number of preceding words to take into account for the POS tag training of the current word
        @param embedding_size: Dimension of the word embeddings
        @param h_size: Dimension of the hidden layer
        @param n_pos_tags: Number of existing POS tags
        """

        # initialize input word vectors. None: "variable size"
        self.input_x = tf.placeholder(tf.int32, [None, n_past_words + 1], name="input_x")
        # initialize input lables (tags)
        self.input_y = tf.placeholder(tf.int64, [None], name="input_y")

        # initialize an embedding matrix with random truncated normal values
        self.embedding_matrix = tf.Variable(tf.truncated_normal([vocab_size, embedding_size], stddev=0.1))
        # build word matrix out of a lookup in the embedding matrix for the input words
        self.word_matrix = tf.nn.embedding_lookup(self.embedding_matrix, self.input_x)
        # stack the rows to create one vector. -1: "figure out the right size" (accounts for variable batch size)
        self.feature_vector = tf.reshape(self.word_matrix, [-1, (n_past_words + 1) * embedding_size])

        # initialize weights between input layer and hidden layer
        w1 = tf.Variable(tf.truncated_normal([(n_past_words + 1) * embedding_size, h_size], stddev=0.1))
        # compute rectified linear activation function on hidden layer
        self.h = tf.nn.relu(tf.matmul(self.feature_vector, w1))
        # initialize weights between hidden layer and output layer
        self.w2 = tf.Variable(tf.truncated_normal([h_size, n_pos_tags], stddev=0.1))
        # compute the logits for the output layer with shape [?, n_pos_tags]
        self.logits = tf.matmul(self.h, self.w2)
        # compute the loss
        self.loss = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(labels=self.input_y, logits=self.logits))

        # reduce the logits output with the largest value to the output layer size = predictions
        self.predictions = tf.argmax(self.logits, axis=1, name="predictions")
        # get the correct predictions by comparing to the given labels
        correct_prediction = tf.equal(self.predictions, self.input_y)
        # compute the overall accuracy
        self.accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

        # apply an optimizer
        self.optimizer = tf.train.AdamOptimizer()

class RNN:
    """
    A class that initializes the structure of a Recurrent Neural Network when instantiated
    """

    def __init__(self, vocab_size, n_timesteps, embedding_size, h_size, n_pos_tags):
        """
        Initializes the Recurrent Neural Network model

        @param vocab_size: Dimension of the vocabulary (number of distinct words)
        @param n_timesteps: Number of previous training steps to include
        @param embedding_size: Dimension of the word embeddings
        @param h_size: Dimension of the hidden layer
        @param n_pos_tags: Number of existing POS tags
        """

        # initialize input word vectors of shape [batch_size, n_timesteps, word_id]
        self.input_x = tf.placeholder(tf.int32, [None, n_timesteps], name="input_x")
        # initialize input labels of shape [batch_size, n_timesteps]
        self.input_y = tf.placeholder(tf.int64, [None], name="input_y")

        # initialize an embedding matrix with random truncated normal values
        self.embedding_matrix = tf.Variable(tf.truncated_normal([vocab_size, embedding_size], stddev=0.1))
        # build word matrix out of a lookup in the embedding matrix for the input words
        self.word_matrix = tf.nn.embedding_lookup(self.embedding_matrix, self.input_x)
        # stack the rows to create one vector. -1: "figure out the right size" (accounts for variable batch size)
        self.feature_vector = tf.reshape(self.word_matrix, [-1, n_timesteps, embedding_size])

        # initialize hidden layer with shape [h_size, n_pos_tags]
        self.w = tf.Variable(tf.truncated_normal([h_size, n_pos_tags], stddev=0.1))
        # create lstm cell
        cell = tf.nn.rnn_cell.LSTMCell(h_size, activation=tf.nn.relu)
        # calculate outputs with shape [batch_size*n_timesteps, h_size]
        outputs, states = tf.nn.dynamic_rnn(cell, self.feature_vector, dtype=tf.float32)
        # compute the logits for the output layer
        self.logits = tf.matmul(tf.reshape(outputs, [-1, h_size]), self.w)
        # reshape logits to make the first dimension fit the batch size/labels: [batch_size, n_timesteps*n_pos_tags]
        logits = tf.reshape(self.logits, [-1, n_timesteps*n_pos_tags])
        # compute the loss
        self.loss = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(logits=logits, labels=self.input_y))

        # reduce the logits output with the largest value to the output layer size = predictions
        self.predictions = tf.argmax(logits, axis=1, name="predictions")
        # get the correct predictions by comparing to the given labels
        correct_prediction = tf.equal(self.predictions, self.input_y)
        # compute the overall accuracy
        self.accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

        # apply an optimizer
        self.optimizer = tf.train.AdamOptimizer()


from .exceptions import ApiNoTokenError, ApiNoUrlError

class ApiAccess(object):
    """
    ApiAccess class holds the data required to access the Api
    """

    def __init__(self, token: str, url: str):
        self.token = token
        self.url = url

    @property
    def token(self) -> str:
        """
        Gets the Bearer Token
        :return:
        """
        return self._token

    @token.setter
    def token(self, value: str) -> None:
        """
        Sets the token.

        :param value: The token
        :return:
        """
        if not value:
            raise ApiNoTokenError

        assert isinstance(value, str), f'Token must be provided as a string. Input: {value}'

        if not str(value).startswith('Bearer '):
            value = f'Bearer {value}'

        self._token = value

    @property
    def url(self) -> str:
        """
        Gets the base url of the destination.
        :return:
        """
        return self._url

    @url.setter
    def url(self, value: str) -> None:
        """
        Sets the base url of the destination.
        :param value:
        :return:
        """
        if not value:
            raise ApiNoUrlError

        assert isinstance(value, str), f'Url must be provided as a string. Input: {value}'

        if not str(value).endswith('/'):
            value = f'{value}/'

        self._url = value


"""
Преобразовать MAC-адрес в строке mac в двоичную строку такого вида: „101010101010101010111011101110111100110011001100“

Полученную новую строку вывести на стандартный поток вывода (stdout) с помощью print.

Ограничение: Все задания надо выполнять используя только пройденные темы.
"""
"""
mac = "AAAA:BBBB:CCCC"

input_mac_list = mac.split(":")
out_mac_str = str(bin(int(input_mac_list[0],16)).lstrip('0b') + bin(int(input_mac_list[1],16)).lstrip('0b') \
+ bin(int(input_mac_list[2],16)).lstrip('0b'))

print(out_mac_str)

более элегантное решение
"""
mac = "AAAA:BBBB:CCCC"

bin_mac = "{:b}".format(int(mac.replace(":", ""), 16))
print(bin_mac)


import cv2
import numpy as np
import os

labels = {0: "angle-boot", 1: "bag", 2: "coat", 3: "dress", 4: "pullover",
          5: "sandal", 6: "shirt", 7: "sneaker", 8: "t-shirt", 9: "trouser"}

class FashionClassifier:

    def __init__(self, model_path, backend = 3, scalefactor=1.0, size=(), mean=(), swapRB=False, crop=False, ddepth=cv2.CV_32F):

        if os.path.isdir(model_path):
            self.net = cv2.dnn.readNetFromModelOptimizer(model_path+"/model.xml", model_path+"/model.bin")
        else:
            self.net = cv2.dnn.readNetFromONNX(model_path)

        self.net.setPreferableBackend(backend)
        self.net.setPreferableTarget(0)

        self.scalefactor = scalefactor
        self.size = size
        self.mean = mean
        self.swapRB = swapRB
        self.crop = crop
        self.ddepth = ddepth

    # Convert the raw result to the string labels
    def process_output(self, out):
        out = out.flatten()
        classId = np.argmax(out)
        return labels[classId]

    def predict(self, img):
        # Preprocess the image to the network needs
        blob = cv2.dnn.blobFromImage(
            img, self.scalefactor, self.size, self.mean, self.swapRB, self.crop, self.ddepth)
        self.net.setInput(blob)
        out = self.net.forward()
        return self.process_output(out)


def dfs(sy, sx):
    stack = [(sy, sx)]
    while stack:
        cy, cx = stack.pop()
        if not visited[cy][cx]:
            visited[cy][cx] = 1
            for dy, dx in dxy:
                ny = cy + dy
                nx = cx + dx
                if 0 <= ny < N and 0 <= nx < N and not visited[ny][nx]:
                    stack.append((ny, nx))

N = int(input())
array = [list(map(int, input().split())) for _ in range(N)]
dxy = [(1, 0), (0, 1), (0, -1), (-1, 0)]
mv = max([max(line) for line in array])
mc = 0

for k in range(mv):
    visited = [[0] * N for _ in range(N)]
    for i in range(N):
        for j in range(N):
            if array[i][j] <= k:
                visited[i][j] = 1
    count = 0
    for i in range(N):
        for j in range(N):
            if not visited[i][j]:
                dfs(i, j)
                count += 1
    mc = max(mc, count)

print(mc)


import os
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.preprocessing import MinMaxScaler
from scipy.interpolate import RBFInterpolator
import plotly.graph_objects as go
import plotly.express as px
from plotly.subplots import make_subplots
from matplotlib.colors import PowerNorm
# import functions  # imports the relevant functions used in processing and making the plots
#1: Functions that creates the cylindrical dataset in cartesian coordinate

# Creating a function that creates the X, Y coordinates from
# a given radius and the number of columns or traces

def create_CardPoints(rad, trace_num):
    """Create 1 2D array with with shape (trace_num x 2).

    parameters:
    ----------
    rad: radius from the center of the trunk in centimeters.

    Returns:
    ρ, θ, X, and Y
    """
    dist = trace_num * 0.02  # The distance of the horizontal profile

    arr = np.ones((trace_num, 4))
    arr[:, 0] = rad/100  # converting the radius to meters since the distance is in meters
    arr[:, 1] = np.linspace(0.02, dist, trace_num) / (arr[:, 0])
    # θ = distance / radius
    arr[:, 2] = arr[:, 0] * np.cos(arr[:, 1])
    arr[:, 3] = arr[:, 0] * np.sin(arr[:, 1])

    return arr

def createZ(sample_pts, depth = 'time'):
    """Convert the number of digitized points into depth profile.

    The vertical axis can be converted to depth in time or depth by
    spreading out the numbers of digitized points across the 45.45 ns
    the EM waves were collected.
    """

    if depth == 'time':
        calc_depth = np.linspace(0, 45.45, sample_pts)  # Depth in time
        return calc_depth

    # To convert to distance, distance = velocity * time/2
    # the velocity was discovered to vary between 0.1 - 0.15 ns

    return np.linspace(0, 45.45, sample_pts) * .5 * 0.1

#2: the cylindrical dataset in cartesian coordinate
def create_cartes_init(tree_folder = 'Tree4_6x6_migrated', stored_rad='04840', start_radius = 48.4):
    radius = start_radius

    transect1 = np.genfromtxt(f"{tree_folder}/Migrated_{stored_rad}.ASC", dtype=None)
    scaler = MinMaxScaler(feature_range=(-1, 1))  # initializing scalar
    amp_array = scaler.fit_transform(transect1)

    # creating an array that stores the X and Y coordinate for all the transects
    coord_array = create_CardPoints(radius, transect1.shape[1])
    depth_z = createZ(transect1.shape[0], depth='dist')

    return coord_array, amp_array, depth_z

#3: Function that compiles transects 2-end of the tree in cartesian coordinate into an array
def create_cartes_arr(coord_array, amp_array, tree_folder = 'Tree4_6x6_migrated',
                      start_radius = 58.4):
    list_dir = os.listdir(tree_folder)  # a list of the tree's transects
    list_dir = sorted(list_dir)  # Added sorted to the list

    # starting radius of the second transect
    radius = start_radius

    for index, transect in enumerate(list_dir[1:]):
        selected_trans = np.genfromtxt(f"{tree_folder}/{transect}", dtype=None)

        # store the individual file amplitude in the dictionary
        # Normalized the amplitude to be between -1 and 1

        scaler = MinMaxScaler(feature_range=(-1, 1))  # initializing scalar
        amp_array = np.hstack((amp_array, scaler.fit_transform(selected_trans)))  # fixed column
        coord_array = np.vstack((coord_array, create_CardPoints(radius, selected_trans.shape[1])))

        radius += 10  # incrementing 10 cm increase for each transect.

    # Transpose the amp_arr
    amp_array = amp_array.T

    return coord_array, amp_array

#4: Function that Plots the cylindrical dataset in cartesian coordinate
def plot_init_transect(coord_array, depth, top_view=False):
    fig = plt.figure(figsize=(11,9), dpi=100)
    ax = plt.axes(projection='3d')

    # The variables are
    X = coord_array[:, 2]
    Y = coord_array[:, 3]
    Z = depth.reshape(-1, 1)
    ax.plot_surface(X, Y, Z)
    if top_view:
        ax.view_init(azim=180, elev= 90)  # azim=180 rotates the 0 to start from the East
    ax.set_xlabel('X-axis (m)')
    ax.set_ylabel('Y-axis (m)')
    ax.set_zlabel('Depth (m)')
    ax.invert_zaxis()

    plt.show()

def plot_cartes_coord(coord_array, depth, top_view=False):
    fig = plt.figure(figsize=(11,9), dpi=100)
    ax = plt.axes(projection='3d')

    # The variables are
    X = coord_array[:, 2]
    Y = coord_array[:, 3]
    Z = Z = np.linspace(0, depth[-1], coord_array[:, 2].shape[0])
    ax.scatter3D(X, Y, Z, s=2)
    if top_view:
        ax.view_init(azim=180, elev= 90)  # azim=180 rotates the 0 to start from the East
    ax.invert_zaxis()
    ax.set_xlabel('X-axis (m)')
    ax.set_ylabel('Y-axis (m)')
    ax.set_zlabel('Depth (m)')

    plt.show()

#5: Function that creates the Mesh that distributes the amplitude across the cartesian coordinates

def create_mesh(coord_array, amp_array, depth_z):
    xy_coord = coord_array[:, 2:]
    x_arr = []
    y_arr = []
    z_arr = []
    c_arr = []

    for i, (x, y) in enumerate(xy_coord):
        for j in range(depth_z.shape[0]):
            x_arr.append(x), y_arr.append(y)
            z_arr.append(depth_z[j])
            # creating a new index that can be modified
            c_arr.append(amp_array[i, j])

    # converting the list to array
    x_arr, y_arr, z_arr, c_arr = np.array(x_arr), np.array(y_arr), np.array(z_arr), np.array(c_arr)

    return x_arr, y_arr, z_arr, c_arr

#6: Function that slices out the original array to a specific length
def arr_subsetting(arr, depth):
    '''
    Param
    -----
    arr: A list that contains x, y, z, and c arrays in this order
    depth: The prefered point to slice the array.
    '''
    mask = (arr[2] <=depth)
    x_main =arr[0][mask]
    y_main =arr[1][mask]
    z_main =arr[2][mask]
    c_main =arr[3][mask]

    return x_main, y_main, z_main, c_main

#7: Functions that Plots the amplitude in the cartesian coordinate
def matplot_amplitude(x_arr, y_arr, z_arr, c_arr, top_view=False):
    fig = plt.figure(figsize=(11,9), dpi=100)
    ax = plt.subplot(111, projection='3d')

    cmap = plt.cm.rainbow
    plot = ax.scatter3D(x_arr, y_arr, z_arr, c=c_arr, cmap=cmap)
    ax.set_xlabel('X-axis (m)')
    ax.set_ylabel('Y-axis (m)')
    ax.set_zlabel('Depth (m)')

    if top_view:
        ax.view_init(azim=0, elev= 90)
    ax.invert_zaxis()
    fig.colorbar(plot)
    plt.show()

def plotly_amplitude(x_arr, y_arr, z_arr, c_arr, top_view=False):
    fig = px.scatter_3d(x=x_arr, y=y_arr, z=z_arr,
                  color=c_arr, color_continuous_scale='rainbow')
    fig.update_layout(
        scene={
            'zaxis': {'autorange': 'reversed'}, # reverse automatically
        }
    )

    if top_view:
        name = 'eye = (x:0., y:0., z:2.5)'
        camera = dict(
            eye=dict(x=0., y=0., z=2.5)
        )

        fig.update_layout(scene_camera=camera, title=name)
    fig.show()

#8: Function that creates and plots the Depth Slices for the tree
def depth_slice(x, y, z, c, depth=0.05, plot_coarseness = 1):
    '''Plot the depth slice passed into the function.

    Parameters
    ----------
    depth: The particular depth to be plotted.
    plot_coarseness: How rough the surface will be.

    returns:
    A list containing the x, y, z, and c arrays which can be used to
    calculate the volume.
    '''
    mask = (z >= depth) & (z <depth+.01)
    x =x[mask]
    y =y[mask]
    z =z[mask]
    c =c[mask]

    cmap = plt.cm.rainbow
    fig = px.scatter_3d(x=x, y=y, z=z,
                  color=c, color_continuous_scale='rainbow', opacity=plot_coarseness)

    cmap = plt.cm.rainbow

    fig.update_layout(
        scene={
            'zaxis': {'autorange': 'reversed'}, # reverse automatically

        }
    )

    name = 'eye = (x:0., y:0., z:2.5)'
    camera = dict(
        eye=dict(x=0., y=0., z=2.5)
    )

    fig.update_layout(scene_camera=camera, title=name)

    fig.show()

    return [x, y, z, c]

#9: Function that creates and plots the Depth Slice 5 cm - 45 cm for the tree
def return_arr(x, y, z, c, depth=0.05):
    mask = (z >= depth) & (z <depth+.01)
    x_slice =x[mask]
    y_slice =y[mask]
    z_slice =z[mask]
    c_slice =c[mask]

    return [x_slice, y_slice, z_slice, c_slice]

def depth_slice_multiple(x, y, z, c, depth=0.05, plot_coarseness = 1, title='Tree'):
    '''Plot the depth slice passed into the function.

    Parameters
    ----------
    depth: The particular depth to be plotted.
    plot_coarseness: How rough the surface will be.

    returns:
    A list containing the x, y, z, and c arrays which can be used to
    calculate the volume.
    '''

    # Creating the 6x6 depth
    fig = make_subplots(
    rows=3, cols=3,
    shared_yaxes=True,
    horizontal_spacing=0.06,
    shared_xaxes=True,
    vertical_spacing=0.06,
    subplot_titles=("Depth = 5 cm", "Depth = 10 cm", "Depth = 15 cm", "Depth = 20 cm",
                "Depth = 25 cm", "Depth = 30 cm", "Depth = 35 cm", "Depth = 40 cm", "Depth = 45 cm"),
    )

    xyz_5cm = return_arr(x=x, y=y, z=z, c=c, depth = .05)
    fig.add_trace(go.Scatter(x=xyz_5cm[0], y=xyz_5cm[1],
                               mode ='markers',
                               marker=dict(
                               color=xyz_5cm[3],
                               colorscale='Rainbow', coloraxis="coloraxis",
                               opacity=plot_coarseness)),
                  row=1, col=1)

    xyz_10cm = return_arr(x=x, y=y, z=z, c=c, depth = .10)
    fig.add_trace(go.Scatter(x=xyz_10cm[0], y=xyz_10cm[1],
                               mode ='markers',
                               marker=dict(
                               color=xyz_10cm[3],
                               colorscale='Rainbow', coloraxis="coloraxis",
                               opacity=plot_coarseness)),
                  row=1, col=2)

    xyz_15cm = return_arr(x=x, y=y, z=z, c=c, depth = .15)
    fig.add_trace(go.Scatter(x=xyz_15cm[0], y=xyz_15cm[1],
                               mode ='markers',
                               marker=dict(
                               color=xyz_15cm[3],
                               colorscale='Rainbow', coloraxis="coloraxis",
                               opacity=plot_coarseness)),
                  row=1, col=3)

    xyz_20cm = return_arr(x=x, y=y, z=z, c=c, depth = .20)
    fig.add_trace(go.Scatter(x=xyz_20cm[0], y=xyz_20cm[1],
                               mode ='markers',
                               marker=dict(
                               color=xyz_20cm[3],
                               colorscale='Rainbow', coloraxis="coloraxis",
                               opacity=plot_coarseness)),
                  row=2, col=1)

    xyz_25cm = return_arr(x=x, y=y, z=z, c=c, depth = .25)
    fig.add_trace(go.Scatter(x=xyz_25cm[0], y=xyz_25cm[1],
                               mode ='markers',
                               marker=dict(
                               color=xyz_25cm[3],
                               colorscale='Rainbow', coloraxis="coloraxis",
                               opacity=plot_coarseness)),
                  row=2, col=2)

    xyz_30cm = return_arr(x=x, y=y, z=z, c=c, depth = .30)
    fig.add_trace(go.Scatter(x=xyz_30cm[0], y=xyz_30cm[1],
                               mode ='markers',
                               marker=dict(
                               color=xyz_30cm[3],
                               colorscale='Rainbow', coloraxis="coloraxis",
                               opacity=plot_coarseness)),
                  row=2, col=3)

    xyz_35cm = return_arr(x=x, y=y, z=z, c=c, depth = .35)
    fig.add_trace(go.Scatter(x=xyz_35cm[0], y=xyz_35cm[1],
                               mode ='markers',
                               marker=dict(
                               color=xyz_35cm[3],
                               colorscale='Rainbow', coloraxis="coloraxis",
                               opacity=plot_coarseness)),
                  row=3, col=1)

    xyz_40cm = return_arr(x=x, y=y, z=z, c=c, depth = .40)
    fig.add_trace(go.Scatter(x=xyz_40cm[0], y=xyz_40cm[1],
                               mode ='markers',
                               marker=dict(
                               color=xyz_40cm[3],
                               colorscale='Rainbow', coloraxis="coloraxis",
                               opacity=plot_coarseness)),
                  row=3, col=2)

    xyz_45cm = return_arr(x=x, y=y, z=z, c=c, depth = .45)
    fig.add_trace(go.Scatter(x=xyz_45cm[0], y=xyz_45cm[1],
                               mode ='markers',
                               marker=dict(
                               color=xyz_45cm[3],
                               colorscale='Rainbow', coloraxis="coloraxis",
                               opacity=plot_coarseness)),
                  row=3, col=3)

    fig.update_layout(height=1000, width=1000,
                  title_text=f"{title}")

    # Update xaxis properties
    fig.update_xaxes(title_text="xaxis(meter)", showgrid=False, row=3, col=1)
    fig.update_xaxes(title_text="xaxis(meter)", row=3, col=2, showgrid=False)
    fig.update_xaxes(title_text="xaxis(meter)", row=3, col=3, showgrid=False)

    # Update yaxis properties
    fig.update_yaxes(title_text="yaxis(meter)", row=1, col=1, showgrid=False)
    fig.update_yaxes(title_text="yaxis(meter)", showgrid=False, row=2, col=1)
    fig.update_yaxes(title_text="yaxis(meter)", showgrid=False, row=3, col=1)

    fig.update_layout(coloraxis=dict(colorscale='Rainbow'), showlegend=False)
    # Update title and height
    #fig.update_layout(title_text="Customizing Subplot Axes", height=700)

    fig.show()

# 10: Plotting the Interpolation plot using matplotlib library
def multiplot_interpolated(int_mesh, ampl_list, norm_val = 1, inner_rad=0.54, outer_rad=2.54, title='Tree 7'):

    # For creating the small radius
    theta = np.linspace(0, 2 * np.pi, 150)
    x_inner = inner_rad * np.cos( theta )
    y_inner = inner_rad * np.sin( theta )

    # used for heightening the value of the roots.
    norm = PowerNorm(gamma=norm_val)

    # extracting the x_data and y_data
    x_data, y_data = int_mesh[0], int_mesh[1]

    # Unpacking the amplitude
    amp5, amp10, amp15, amp20, amp25, amp30, amp35, amp40, amp45 = ampl_list

    # Create a mask for points outside the circle
    # Circle center and radius
    center_x, center_y = 0, 0
    radius = outer_rad

    mask = (x_data - center_x)**2 + (y_data - center_y)**2 > radius**2
    amp5[mask] = np.nan
    amp10[mask] = np.nan
    amp15[mask] = np.nan
    amp20[mask] = np.nan
    amp25[mask] = np.nan
    amp30[mask] = np.nan
    amp35[mask] = np.nan
    amp40[mask] = np.nan
    amp45[mask] = np.nan

    # Create the figure and axis
    fig, ((ax1, ax2, ax3), (ax4, ax5, ax6), (ax7, ax8, ax9)) = plt.subplots(3, 3, figsize=(13, 12))

    cmap = plt.cm.rainbow

    # Title
    fig.suptitle(f'{title}')

    # Display the pcolormesh inside the circle
    ax1.pcolormesh(x_data, y_data, amp5, cmap=cmap, norm=norm)
    ax1.fill_between(x_inner, y_inner, color='white')
    ax1.set_title('Depth Slice = 5 cm')
    ax1.set_aspect('equal', adjustable='box')  # Set aspect ratio to equal

    ax2.pcolormesh(x_data, y_data, amp10, cmap=cmap, norm=norm)
    ax2.fill_between(x_inner, y_inner, color='white')
    ax2.set_title(f'Depth Slice = 10 cm')
    ax2.set_aspect('equal', adjustable='box')  # Set aspect ratio to equal

    ax3.pcolormesh(x_data, y_data, amp15, cmap=cmap, norm=norm)
    ax3.fill_between(x_inner, y_inner, color='white')
    ax3.set_title('Depth Slice = 15 cm')
    ax3.set_aspect('equal', adjustable='box')  # Set aspect ratio to equal

    ax4.pcolormesh(x_data, y_data, amp20, cmap=cmap, norm=norm)
    ax4.fill_between(x_inner, y_inner, color='white')
    ax4.set_title('Depth Slice = 20 cm')
    ax4.set_aspect('equal', adjustable='box')  # Set aspect ratio to equal

    ax5.pcolormesh(x_data, y_data, amp25, cmap=cmap, norm=norm)
    ax5.fill_between(x_inner, y_inner, color='white')
    ax5.set_title('Depth Slice = 25 cm')
    ax5.set_aspect('equal', adjustable='box')  # Set aspect ratio to equal

    ax6.pcolormesh(x_data, y_data, amp30, cmap=cmap, norm=norm)
    ax6.fill_between(x_inner, y_inner, color='white')
    ax6.set_title('Depth Slice = 30 cm')
    ax6.set_aspect('equal', adjustable='box')  # Set aspect ratio to equal

    ax7.pcolormesh(x_data, y_data, amp35, cmap=cmap, norm=norm)
    ax7.fill_between(x_inner, y_inner, color='white')
    ax7.set_title('Depth Slice = 35 cm')
    ax7.set_aspect('equal', adjustable='box')  # Set aspect ratio to equal

    ax8.pcolormesh(x_data, y_data, amp40, cmap=cmap, norm=norm)
    ax8.fill_between(x_inner, y_inner, color='white')
    ax8.set_title('Depth Slice = 40 cm')
    ax8.set_aspect('equal', adjustable='box')  # Set aspect ratio to equal

    cbar = ax9.pcolormesh(x_data, y_data, amp45, cmap=cmap, norm=norm)
    ax9.fill_between(x_inner, y_inner, color='white')
    ax9.set_title('Depth Slice = 45 cm')
    ax9.set_aspect('equal', adjustable='box')  # Set aspect ratio to equal

    for ax in fig.get_axes():
        ax.label_outer()

    # getting the colorbar for all the subplots
    fig.subplots_adjust(right=0.8)
    cbar_ax = fig.add_axes([0.85, 0.15, 0.05, 0.7])
    fig.colorbar(cbar, cbar_ax)

    # Display the plot
    plt.show()

# 11: Single Interpolated Plotting
def plot_interpolated(int_mesh, ampl, norm_val = 1, inner_rad=0.54, outer_rad=2.54, val=5):

    # For creating the small radius
    theta = np.linspace(0, 2 * np.pi, 150)
    x_inner = inner_rad * np.cos( theta )
    y_inner = inner_rad * np.sin( theta )

    # used for heightening the value of the roots.
    norm = PowerNorm(gamma=norm_val)

    # extracting the x_data and y_data
    x_data, y_data = int_mesh[0], int_mesh[1]

    # Create a mask for points outside the circle
    # Circle center and radius
    center_x, center_y = 0, 0
    radius = outer_rad

    mask = (x_data - center_x)**2 + (y_data - center_y)**2 > radius**2
    ampl[mask] = np.nan

    cmap = plt.cm.rainbow

    # Create the figure and axis
    fig, ax = plt.subplots()

    # Display the pcolormesh inside the circle
    c = ax.pcolormesh(x_data, y_data, ampl, cmap=cmap, norm=norm)
    ax.fill_between(x_inner, y_inner, color='white')
    ax.set_title(f'Depth Slice = {val} cm')

    # Set aspect ratio to equal
    ax.set_aspect('equal', adjustable='box')

    # Display the plot
    plt.show()

# 12: Creating the Interpolation points
# build a mesh to interpolate onto
def interpolator(data_3d, num_grid=200, grid_ext=3):
    '''
    Interpolate the Scatter Plots.

    Param
    -----
    data_3d: contains the x, y, z, and amplitude values.
    '''

    # Will change the dimension when necessary
    int_mesh = np.mgrid[-1*grid_ext:grid_ext:num_grid*1j, -1*grid_ext:grid_ext:num_grid*1j]
    mesh = int_mesh.reshape(2,-1).T

    # perform the interpolation
    points = np.column_stack((data_3d[0], data_3d[1]))
    # print(x, y, points)
    new_vals = RBFInterpolator(points, data_3d[3])(mesh)
    interp_values = new_vals.reshape(num_grid, num_grid)

    return int_mesh, interp_values

# 13:  Return array from 5 cm to 45 cm deep below the soil

def return_arr_depth_5_45cm(x_arr, y_arr, z_arr, c_arr):

    _5cm = return_arr(x_arr, y_arr, z_arr, c_arr, depth=0.05)  # Depth = 5 cm
    _10cm = return_arr(x_arr, y_arr, z_arr, c_arr, depth=0.10)  # Depth = 10 cm
    _15cm = return_arr(x_arr, y_arr, z_arr, c_arr, depth=0.15)  # Depth = 15 cm
    _20cm = return_arr(x_arr, y_arr, z_arr, c_arr, depth=0.20)  # Depth = 20 cm
    _25cm = return_arr(x_arr, y_arr, z_arr, c_arr, depth=0.25)  # Depth = 25 cm
    _30cm = return_arr(x_arr, y_arr, z_arr, c_arr, depth=0.30)  # Depth = 30 cm
    _35cm = return_arr(x_arr, y_arr, z_arr, c_arr, depth=0.35)  # Depth = 35 cm
    _40cm = return_arr(x_arr, y_arr, z_arr, c_arr, depth=0.40)  # Depth = 40 cm
    _45cm = return_arr(x_arr, y_arr, z_arr, c_arr, depth=0.45)  # Depth = 45 cm

    return _5cm ,_10cm, _15cm, _20cm, _25cm, _30cm, _35cm, _40cm, _45cm

# 14: Used in reducing the array size to correct for stationary matrices
def downsample_array(x_arr, y_arr, z_arr, c_arr, downsamp_step=2):

    # Get the shape of the array
    arr_size =x_arr.shape[0]
    downsized = np.arange(0, arr_size, downsamp_step)

    #x_arr, y_arr, z_arr, c_arr = array
    c_arr[0]
    # downsampling the array
    x_arr = x_arr[downsized]
    y_arr = y_arr[downsized]
    z_arr = z_arr[downsized]
    c_arr = c_arr[downsized]
    #print(x_arr)

    return x_arr, y_arr, z_arr, c_arr


class Student:
    def __init__(self, name, grade, subject):
        self.name = name
        self.grade = grade
        self.subject = subject

    def do_work(self, time):
        if time > 3 and self.grade > 3:
            return True
        elif time > 0.5 and self.grade < 3:
            return True
        else:
            return False

class teacher:
    def __init__(self, name, subject):
        self.name = name
        self.subject = subject
        self.x = 'sd'

    def evaluate(self, result=True):
        if result:
            return "GOOD!"
        else:
            return "BAD!"

zaolixin = Student("zaolixin", 4, "math")
liyiping = teacher("liyiping", "math")
liyiping_said = liyiping.evaluate(zaolixin.do_work(4))
print(
    "teacher {0} student {1} ,{2}".format(liyiping.name, zaolixin.name, liyiping_said)
)
print(dir(liyiping))


import random
print('GUESS THE NUMBER')
rnumber=random.randint(1,9)
chances=0
print('Guess the number between 1 to 9-> ')
while chances <5:
    uInput=int(input('enter  your number: '))
    if uInput==rnumber:
        print('Congratulations YOU WON!!!')
        break
    elif uInput<rnumber:
        print('your guess was too low!')
    else:
        print('your guess was too high!')
    chances=chances+1
if not chances<5:
    print('Better luck next time! ;(')


"""
Basic skeleton of a mitmproxy addon.

Run as follows: mitmproxy -s anatomy.py
"""
import os
import pathlib
import signal
import zmq
from typing import Any, cast, Optional
import simplejson as json
import time
import threading
from mitmproxy.http import Headers, Response as MitmResponse, HTTPFlow as MitmHTTPFlow
from common_types import ProxyRequest, ProxyResponse, ProxyWebsocketMessage
from home_page_html import HOME_PAGE_HTML
from sys import argv
from argparse import ArgumentParser

TIMEOUT_AFTER_SECONDS_NO_POLL = 3

# Example of argv:
#
# [
#   '/Users/evan/Code/pntest/venv/bin/mitmdump',
#   '-s',
#   '/Users/evan/Code/pntest/src/mitmproxy/addon.py',
#   '-p',
#   '8080',
#   '--set',
#   'confdir=./include',
#   '--set',
#   'client_certs=./include/mitmproxy-client.pem',
# ]

arg_parser = ArgumentParser()
arg_parser.add_argument('-p', '--port')
arg_parser.add_argument('--client-id')
arg_parser.add_argument('--zmq-server')
args, _ = arg_parser.parse_known_args(argv)

class ProxyHttpFlow(MitmHTTPFlow):
    intercept_response: bool

class ProxyEventsAddon:
    settings: Optional[dict[str,Any]]
    client_id: int
    recording_enabled: bool
    intercept_enabled: bool
    intercepted_flows: list[ProxyHttpFlow]
    socket: zmq.Socket

    def __init__(self, client_id: int):
        current_path = pathlib.Path(__file__).parent.resolve()

        self.client_id = client_id
        self.intercepted_flows = []
        self.settings = None
        self.intercept_enabled = False
        self.recording_enabled = True

    def zmq_connect(self):
        print("[ZMQClient] starting...")

        # Connect to the ZMQ server
        context = zmq.Context()
        self.socket = context.socket(zmq.DEALER)
        self.socket.setsockopt_string(zmq.IDENTITY, str(self.client_id))
        self.socket.connect("tcp://%s" % args.zmq_server)

        # Let em know we've started
        self.socket.send_string(json.dumps({'type': 'started'}))

        # Listen to messages from the server
        listen_thread = threading.Thread(target=self.zmq_listen, daemon=True)
        listen_thread.start()

        print("[ZMQClient] listening...")

    def zmq_listen(self):
        poll = zmq.Poller()
        poll.register(self.socket, zmq.POLLIN)
        last_poll_at = int(time.time())

        while True:
            sockets = dict(poll.poll(1000))

            diff = int(time.time()) - last_poll_at
            # If the src/__main__.py process has stopped, then the proxy should kill itself
            if diff >= TIMEOUT_AFTER_SECONDS_NO_POLL:
                print(f'[Proxy] last poll was {diff} secs ago! Shutting down..')
                os.kill(os.getpid(), signal.SIGTERM)

            if sockets:
                message_raw = self.socket.recv()

                # ZMQ typing is not accurate here
                if type(message_raw) is not bytes:
                    raise Exception(f'[Proxy] Could not parse message of type {type(message_raw)}')

                message_raw_str = message_raw.decode('utf-8')
                message = json.loads(message_raw)

                if message['type'] in ['forward', 'forward_and_intercept']:
                    self.forward_flow(message)

                elif message['type'] == 'drop':
                    self.drop_flow(message)

                elif message['type'] == 'forward_all':
                    self.forward_all()

                elif message['type'] == 'enable_intercept':
                    self.set_intercept_enabled(message['value'])

                elif message['type'] == 'enable_recording':
                    self.set_recording_enabled(message['value'])

                elif message['type'] == 'set_settings':
                    self.set_settings(message['value'])

                elif message['type'] == 'poll':
                    last_poll_at = int(time.time())

    # ---------------------------------------------------------------------------
    # Actions:
    # ---------------------------------------------------------------------------
    def forward_flow(self, message):
        type = message['type']
        modified_flow = message['flow']

        print(f'[Proxy] {type} flow {modified_flow["uuid"]}')
        flow = self.intercepted_flows.pop(0)

        # Overwrite the MitmProxy flow with the values of the Pntest Flow:
        if flow.websocket:
            flow.websocket.messages[-1].content = modified_flow['websocket_messages'][-1]['content'].encode()

        elif flow.response:
            flow.response.status_code = modified_flow['response']['status_code']
            flow.response.headers = self.__convert_headers_for_mitm(modified_flow['response']['headers'])
            flow.response.content = modified_flow['response']['content'].encode()

        else:
            flow.request.path = modified_flow['request']['path']
            flow.request.method = modified_flow['request']['method']
            flow.request.host = modified_flow['request']['host']
            flow.request.port = modified_flow['request']['port']
            flow.request.headers = self.__convert_headers_for_mitm(modified_flow['request']['headers'])
            flow.request.content = modified_flow['request']['content'].encode()
            flow.intercept_response = (message['type'] == 'forward_and_intercept')

        flow.resume()

    def forward_all(self):
        for flow in self.intercepted_flows:
            print(f'[Proxy] forwarding flow {flow.id}')
            flow.intercept_response = False
            flow.resume()

    def drop_flow(self, message):
        type = message['type']
        modified_flow = message['flow']

        print(f'[Proxy] {type} flow {modified_flow["uuid"]}')
        flow = self.intercepted_flows.pop(0)
        flow.kill()

    def intercept_flow(self, flow):
        flow.intercept()
        self.intercepted_flows.append(flow)

    def set_intercept_enabled(self, enabled: bool):
        self.intercept_enabled = enabled

    def set_recording_enabled(self, enabled: bool):
        self.recording_enabled = enabled

    def set_settings(self, settings):
        self.settings = settings

    # ---------------------------------------------------------------------------
    # MitmProxy Events:
    # ---------------------------------------------------------------------------
    def request(self, flow: MitmHTTPFlow):
        print('[Proxy] HTTP request')
        # The default homepage at http://pntest
        if flow.request.host == 'pntest':
            flow.response = MitmResponse.make(200, self.__proxy_home_page_html(), {"content-type": "text/html"})

        if not self.should_request_be_captured(flow):
            return

        request_state = cast(ProxyRequest, convert_dict_bytes_to_strings(flow.request.get_state()))
        request_state['flow_uuid'] = flow.id
        request_state['type'] = 'request'
        request_state['client_id'] = self.client_id
        request_state['intercepted'] = self.__should_intercept_request(flow)
        request_state['content'] = flow.request.text or ''
        # NOTE: WE have to re-write this when in docker_proxy because iptables intercepts this after the host
        # has been replaced with an ip address
        if flow.request.host_header:
            request_state['host'] = flow.request.host_header
        self.__send_message(request_state)

        if request_state['intercepted']:
            self.intercept_flow(flow)

    def response(self, flow: MitmHTTPFlow):
        print('[Proxy] HTTP response')
        intercept_response = getattr(flow, 'intercept_response', False)

        if flow is None:
            return

        if flow.response is None or not self.should_request_be_captured(flow):
            return

        response_state = cast(ProxyResponse, convert_dict_bytes_to_strings(flow.response.get_state()))
        response_state['flow_uuid'] = flow.id
        response_state['type'] = 'response'
        response_state['intercepted'] = intercept_response

        # NOTE: Even though it breaks the type-checking, we convert this to a string so it can be sent
        # over zmq, then in ProxyZmqServer we decode base64 and decode back to raw bytes
        # TODO: Have a seperate ProxyResponseZmq type with content: str
        if flow.response.content is None:
            response_state['content'] = '' # type:ignore
        else:
            response_state['content'] = flow.response.content.hex() # type:ignore

        self.__send_message(response_state)

        if intercept_response:
            self.intercept_flow(flow)

    def websocket_message(self, flow: MitmHTTPFlow):
        print('[Proxy] websocket message')
        if flow.websocket is None or self.recording_enabled == False:
            return

        message = flow.websocket.messages[-1]
        direction = 'outgoing' if message.from_client else 'incoming'

        message_state: ProxyWebsocketMessage = {
            'type': 'websocket_message',
            'flow_uuid': flow.id,
            'direction': direction,
            'content': message.content.decode(),
            'intercepted': self.__should_intercept_request(flow)
        }
        self.__send_message(message_state)

        if message_state['intercepted']:
            flow.intercepted_message = message  # type: ignore
            self.intercept_flow(flow)

    # ---------------------------------------------------------------------------
    # Private methods:
    # ---------------------------------------------------------------------------
    def __should_intercept_request(self, flow):
        return self.intercept_enabled

    def __convert_headers_for_mitm(self, headers):
        headers_obj = json.loads(headers)
        headers_list = []

        for key, value in headers_obj.items():
            header = (key.encode(), value.encode())
            headers_list.append(header)

        return Headers(headers_list)

    def __send_message(self, message):
        try:
            self.socket.send_string(json.dumps(message))
        except UnicodeDecodeError:
            print(f'ERROR => Could not send message for flow {message["flow_uuid"]}')
            return

    def should_request_be_captured(self, flow: MitmHTTPFlow) -> bool:
        if self.recording_enabled == False:
            return False

        if self.settings is None:
            return True

        # Check host
        host_list = self.settings['capture_filters']['host_list']
        has_hosts = len(host_list) > 0
        host_setting = self.settings['capture_filters']['host_setting']

        if flow.request.host in host_list and host_setting == 'exclude' and has_hosts:
            return False

        if flow.request.host not in host_list and host_setting == 'include' and has_hosts:
            return False

        return True

    def __proxy_home_page_html(self) -> str:
        html = HOME_PAGE_HTML

        html = html.replace('{{client_id}}', str(self.client_id))
        html = html.replace('{{proxy_port}}', args.port)
        return html

def convert_dict_bytes_to_strings(d):
    new_d = {}
    for key, value in d.items():
        if type(value) is bytes and key != 'content':
            new_d[key] = value.decode()
        elif key == 'headers':
            new_d[key] = convert_headers_bytes_to_strings(value)
        else:
            new_d[key] = value

    return new_d

def convert_headers_bytes_to_strings(headers):
    new_headers = []
    for header in headers:
        new_header = (header[0].decode(), header[1].decode())
        new_headers.append(new_header)

    return new_headers

proxy_events = ProxyEventsAddon(int(args.client_id))
proxy_events.zmq_connect()

addons = [proxy_events]


# 1번 문제와 2번 문제는 key값의 위치만 다르고 사실상 같다.

# 첫번째 풀이
import sys
input = sys.stdin.readline

coords = list()
for _ in range(int(input())):
    coords.append(tuple(map(int, input().split())))
coords.sort(key=lambda x:(x[0], x[1]))
for x, y in coords:
    print(x, y)

# 두번째 풀이

import sys
input = sys.stdin.readline
coords = sorted([tuple(map(int, input().split())) for _ in range(int(input()))], key=lambda x:(x[0],x[1]))
for x, y in coords:
    print(x, y)

# 세번째 풀이

for x, y in sorted([tuple(map(int, input().split())) for _ in range(int(input()))], key=lambda x:(x[0],x[1])):
    print(x, y)


import random
class Kart():
    def __init__(self,karttur,kartno):
        self.tur=karttur
        self.numara=kartno
deste=[]
for i in range(0,2):
    for j in range(1,11):
        if(i==0):
            karttur="Kırmızı"
        else:
            karttur="Siyah"
        deste.append(Kart(karttur,j))
#rastgele 5 er kart dağıtalım.
oyuncu1=[]
oyuncu2=[]
for i in range(0,5):
    rastgele=random.randint(0,len(deste)-1)
    oyuncu1.append(deste[rastgele])
    deste.pop(rastgele)
    rastgele2=random.randint(0,len(deste)-1)
    oyuncu2.append(deste[rastgele2])
    deste.pop(rastgele2)
oyuncu1puan=0
oyuncu2puan=0

print("1.Oyuncunun kartları")
for i in oyuncu1:
    print(i.tur,i.numara)
print("\n2. Oyuncunun kartları")
for i in oyuncu2:
    print(i.tur,i.numara)
for i in range (5):
    if(oyuncu1[i].tur==oyuncu2[i].tur):
        if(oyuncu1[i].numara>oyuncu1[i].numara):
            oyuncu1puan+=5
        else:
            oyuncu2puan+=5
    else:
        if(oyuncu1[i].tur=="Kırmızı"):
            oyuncu1puan+=10
        else:
            oyuncu2puan+=10
if(oyuncu1puan>oyuncu2puan):
    print("Oyunu toplam",oyuncu1puan,"ile 1. oyuncu kazandı.")
elif(oyuncu1puan<oyuncu2puan):
    print("Oyunu toplam",oyuncu2puan,"ile 2. oyuncu kazandı.")
else:
    print("İki oyuncuda toplam",oyuncu1puan,"puan kazandı.Oyun berabere.")


# deploy_front/app.py
#
import os.path
from flask import Flask
import os
import json
import run_backend

import time

app = Flask(__name__)

def get_predictions():

    videos = []

    novos_videos_json = "novos_videos.json"
    if not os.path.exists(novos_videos_json):
        run_backend.update_db()

    last_update = os.path.getmtime(novos_videos_json) * 1e9

    #if time.time_ns() - last_update > (720*3600*1e9): # aprox. 1 mes
    #    run_backend.update_db()

    with open("novos_videos.json", 'r') as data_file:
        for line in data_file:
            line_json = json.loads(line)
            videos.append(line_json)

    predictions = []
    for video in videos:
        #print(video)
        #print(video['video_id'])
        predictions.append((video['video_id'], video['title'], float(video['score'])))

    predictions = sorted(predictions, key=lambda x: x[2], reverse=True)[:30]

    predictions_formatted = []
    for e in predictions:
        #print(e)
        predictions_formatted.append("
{title}	{score}
".format(title=e[1], link=e[0], score=e[2]))

    return '\n'.join(predictions_formatted), last_update

@app.route('/')
def main_page():
    preds, last_update = get_predictions()
    return """
Recomendador de Vídeos do Youtube

    Segundos desde a última atualização: {}

             {}

    """.format((time.time_ns() - last_update) / 1e9, preds)

if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0')


from models.KF_wrapper import *
from training.KF_train_utils import train_loop_KF
from datasets.utils.get_data import get_mimic_data
from sacred import Experiment
import seml

ex = Experiment()
seml.setup_logger(ex)

@ex.post_run_hook
def collect_stats(_run):
    seml.collect_exp_stats(_run)

@ex.config
def config():
    overwrite = None
    db_collection = None
    if db_collection is not None:
        ex.observers.append(seml.create_mongodb_observer(db_collection, overwrite=overwrite))

@ex.automain
def run(epochs, device, dim, ldim, batch_size, lr, seed, cov_dim, hiddendim, model_name, norm, reg_lambda, ds_seed):

    train, val, _, name = get_mimic_data(norm=norm, small_ds=False, random_state=ds_seed)

    if model_name == "KF":
        model = KF(seed=seed, dim=dim, latent_dim=ldim)
    elif model_name == "NKF":
        model = NKF(seed=seed, dim=dim, latent_dim=ldim)
    elif model_name == "RKF-O":
        model = RKF_O(seed=seed, dim=dim, latent_dim=ldim)
    elif model_name == "RKF-F":
        model = RKF_F(seed=seed, dim=dim, latent_dim=ldim, hidden_dim=hiddendim)
    elif model_name == "RCKF":
        model = RCKF(seed=seed, dim=dim, latent_dim=ldim, hidden_dim=hiddendim, cov_dim=cov_dim)

    experiment_name = train_loop_KF(model, model_name, name, train, val, epochs=epochs, lr=lr, batch_size=batch_size,
                                    device=device, reg_lambda=reg_lambda)

    return experiment_name


# TODO:
# we should have a function that makes the activity maps & separate that from the functions that do curve fits or whatever. Since the activity maps are the most time consuming part of the process.
#

import os
import sys

import pickle
import numpy as np

import utils.model_handling as model_funcs
import utils.dataset_generation as iso_data
import utils.histogram_analysis as hist_funcs

current_path = os.path.dirname(os.path.abspath(__file__))
parent_path = os.path.dirname(current_path)
if parent_path not in sys.path: sys.path.append(parent_path)
santi_path = parent_path+'/santi_iso_response'
santi_etc_path = os.path.join(santi_path, 'etc')
from santi_iso_response.iso_response import utils as santi_utils

# NOTE:This script uses about 19GB of memory with batch_size=100; num_images=900; num_targets=166; num_comparisons=166

with open(os.path.join(santi_etc_path, 'meis.pkl'), 'rb') as g:
    mei = pickle.load(g)
num_mei = len(mei['images'])
neuron_mei = [mei['images'][idx] for idx in range(num_mei)]
target_neuron_ids = [idx for idx in range(num_mei) if mei['performance'][idx] > 0.01]
total_num_neurons = len(neuron_mei)

experiment_params = dict()
experiment_params['batch_size'] = 100
experiment_params['target_neuron_ids'] = target_neuron_ids
experiment_params['num_comparisons'] = len(target_neuron_ids)
experiment_params['min_angle'] = 15
experiment_params['x_range'] = (-2.0, 2.0)
experiment_params['y_range'] = (-2.0, 2.0)
experiment_params['num_images'] = int(30**2)
experiment_params['image_scale'] = 12
experiment_params['target_activity'] = 0.5
experiment_params['iso_window_bounds'] = ((-1, 1), (-1, 1))
experiment_params['comp_method'] = 'closest'
experiment_params['output_directory'] = parent_path+'/iso_analysis/'
experiment_params['save_prefix'] = 'santi_windowed_'

def get_curvatures_from_target_comparison_vectors(model, target_vectors, comparison_vectors, act_func, kwargs):
    contour_dataset, _ = iso_data.get_contour_dataset(
        target_vectors,
        comparison_vectors,
        kwargs['x_range'],
        kwargs['y_range'],
        kwargs['num_images'],
        kwargs['image_scale'],
        return_datapoints=False
    )
    num_neurons = len(target_vectors)
    num_planes = len(comparison_vectors)
    num_edge_images = int(np.sqrt(kwargs['num_images']))
    response_images = np.zeros((num_neurons, num_planes, num_edge_images, num_edge_images))
    all_iso_curvatures = []
    all_attn_curvatures = []
    all_mei_lengths = []
    for target_index, target_proj_matrix in enumerate(contour_dataset['proj_matrix']):
        sub_mei_lengths = []
        sub_iso_curvatures = []
        sub_attn_curvatures = []
        for plane_index, proj_matrix in enumerate(target_proj_matrix): # 1 plane at a time
            datapoints = iso_data.inject_data(proj_matrix, contour_dataset['proj_datapoints'],
                kwargs['image_scale'])
            activations = model_funcs.get_normalized_activations(
                model,
                [kwargs['target_neuron_ids'][target_index]],
                [[datapoints]],
                act_func
            )
            response_images[target_index, plane_index, ...] = np.squeeze(activations).copy()

            iso_curvatures, attn_curvatures = hist_funcs.compute_curvature_poly_fits(
                activations,
                contour_dataset,
                kwargs['target_activity'],
                bounds=kwargs['iso_window_bounds']
                #measure_loc='right'
                #measure_upper_right=False
            )
            ## Add code to measure mei length
            #mei = kwargs['mei']
            # mei_lengths = get_mei_lengths(mei, proj_matrix)
            #     -- normalize mei
            #     -- project mei using proj_matrix
            mei_lengths = None
            sub_mei_lengths.append(mei_lengths)
            sub_iso_curvatures.append(iso_curvatures[0][0])
            sub_attn_curvatures.append(attn_curvatures[0][0])
        all_mei_lengths.append(sub_mei_lengths)
        all_iso_curvatures.append(sub_iso_curvatures)
        all_attn_curvatures.append(sub_attn_curvatures)
    out_dict = {
        'mei_lengths':all_mei_lengths,
        'contour_dataset':contour_dataset,
        'iso_curvatures':all_iso_curvatures,
        'response_images': response_images,
        'attn_curvatures':all_attn_curvatures
    }
    return out_dict

def get_curvatures_from_exciting_vectors(model, exciting_vectors, act_func, kwargs):
    iso_vectors = iso_data.compute_comp_vectors(
        exciting_vectors,
        kwargs['target_neuron_ids'],
        kwargs['min_angle'],
        kwargs['num_comparisons'],
        comp_method=kwargs['comp_method']
    )
    comparison_vector_ids = iso_vectors[0]
    target_vectors = iso_vectors[1]
    comparison_vectors = iso_vectors[2]
    kwargs['mei'] = exciting_vectors
    out_dict = get_curvatures_from_target_comparison_vectors(
        model,
        target_vectors,
        comparison_vectors,
        act_func,
        kwargs
    )
    out_dict['comparison_vector_ids'] = comparison_vector_ids
    out_dict['target_vectors'] = target_vectors
    out_dict['comparison_vectors'] = comparison_vectors
    return out_dict

if not os.path.exists(experiment_params['output_directory']):
    os.makedirs(experiment_params['output_directory'])
np.savez(experiment_params['output_directory']+experiment_params['save_prefix']+'meis_params.npz',
    data=experiment_params)

model = santi_utils.load_model()

"""
Maximum Exciting Images
"""
comp_results = get_curvatures_from_exciting_vectors(
    model,
    neuron_mei,
    santi_utils.get_activations_cell,
    experiment_params
)
np.savez(experiment_params['output_directory']+experiment_params['save_prefix']+'meis.npz',
    data=comp_results)
print('Maximum exciting images experiment complete.')

#"""
#Random planes from MEIs
#"""
#iso_vectors = iso_data.compute_rand_vectors(
#    [neuron_mei[idx] for idx in experiment_params['target_neuron_ids']],
#    experiment_params['num_comparisons']
#)
#target_vectors = iso_vectors[0]
#orth_vectors = iso_vectors[1]
#comp_results = get_curvatures_from_target_comparison_vectors(
#    model,
#    target_vectors,
#    orth_vectors,
#    santi_utils.get_activations_cell,
#    experiment_params
#)
#comp_results['target_vectors'] = target_vectors
#comp_results['comparison_vectors'] = orth_vectors
#np.savez(experiment_params['output_directory']+experiment_params['save_prefix']+'rand.npz',
#    data=comp_results)
#print('Random plane experiment complete.')

#"""
#Maximum Exciting Stimuli
#"""
#iid_stim_images = np.squeeze(model.data.train()[0])
#num_stim = iid_stim_images.shape[0]
#stim_activity = santi_utils.get_activations(model, iid_stim_images)
#stim_argsort = np.argsort(stim_activity, axis=0)
#neuron_mes = [] # most exciting stimulus
#for neuron_idx in range(total_num_neurons):
#    most_exciting_stim = iid_stim_images[stim_argsort[0, neuron_idx], ...]
#    most_exciting_stim = iso_data.normalize_vector(most_exciting_stim)
#    neuron_mes.append(most_exciting_stim)
#del iid_stim_images
#"""
#### PROBLEM - Some neurons have the same exciting stim.
#If this is the case we should assign the second most exciting stim.
#But then we have an assignment problem...
#Not sure what to do here.
#"""
#comp_results = get_curvatures_from_exciting_vectors(
#    model,
#    neuron_mes,
#    santi_utils.get_activations_cell,
#    experiment_params
#)
#np.savez(experiment_params['output_directory']+experiment_params['save_prefix']+'stim.npz',
#    data=comp_results)
#print('Maximum exciting stimuli experiment complete.')


#!/usr/bin/env python3

import os
import subprocess
import signal
from PyQt4 import QtGui, QtCore

from BaseList import *
from config import *

exts = ['wav', 'mp3', 'ogg', 'flac', 'm4a']
audio_only = '|'.join(map(lambda ext: '\.{}'.format(ext), exts))

def play(a_file):
    return subprocess.Popen(['play', '-q', a_file],
                            stdout=subprocess.PIPE,
                            preexec_fn=os.setsid)

class FileListItem(BaseListItem):
    def __init__(self, text, is_single=True):
        super(FileListItem, self).__init__(text, is_single)
        self.playing = None

    def playSample(self):
        self.stop()
        self.playing = play(self.text)

    def stop(self):
        if self.playing:
            os.killpg(self.playing.pid, signal.SIGTERM)

class FileList(BaseList):
    sample_playing = QtCore.pyqtSignal(bool)
    sample_selected = QtCore.pyqtSignal(str)

    def __init__(self, path, parent=None):
        super(FileList, self).__init__(parent)
        self.playback_enabled = False

        self.updateList(path)

    def mimeData(self, item):
        path = os.path.abspath(str(item[0].text))
        print(path)
        if os.path.isfile(path):
            mimeData = QtCore.QMimeData()
            mimeData.setUrls([QtCore.QUrl.fromLocalFile(path)])
            self.updateRecent(path)
            return mimeData

    def _keyEvents(self, event):
        if event.key() == QtCore.Qt.Key_Escape:
            self.updateList(os.getcwd())
        elif event.key() == QtCore.Qt.Key_Delete:
            if os.path.abspath(self.current_item.text) in config['Recent']:
                config['Recent'].remove(os.path.abspath(self.current_item.text))
                self.updateList('Recent')
        elif event.key() == QtCore.Qt.Key_Return \
                or event.key() == QtCore.Qt.Key_Space:
            if self.current_item.is_single: self.current_item.playSample()
            else: self.updateList(self.current_item.text)
        elif event.key() == QtCore.Qt.Key_Right \
                or event.key() == QtCore.Qt.Key_Semicolon:
            if not self.current_item.is_single:
                self.updateList(self.selectedItems()[0].text)

    def activatePressed(self, item):
        if self.select_flag:
            self.select_flag = False
        elif self.current_item:
            if self.current_item.is_single and self.playback_enabled: self.current_item.playSample()
            else: self.updateList(self.current_item.text)

    def _isAudio(self, a_file):
        if os.path.splitext(a_file)[1].lower()[1:] in exts:
            return True
        return False

    def getContents(self):
        entries = os.listdir(os.getcwd())
        entries = [i for i in entries if not i.startswith('.')]
        dir_list = ['..']
        file_list = []
        for entry in entries:
            if os.path.isdir(entry):
                dir_list.append(entry)
            elif os.path.isfile(entry):
                if self._isAudio(entry):
                    file_list.append(entry)
        dir_list.sort(key=str.lower)
        file_list.sort(key=str.lower)

        return dir_list, file_list

    def itemSelected(self, row):
        if self.current_item: self.current_item.stop()
        super(FileList, self).itemSelected(row)
        if self.current_item and self.current_item.is_single:
            self.sample_selected.emit(self.current_item.text)
            if self.playback_enabled: self.current_item.playSample()

    def updateRecent(self, path):
        if path in config['Recent']: config['Recent'].remove(path)
        config['Recent'].append(path)
        if len(config['Recent']) > 50: config['Recent'].pop(0)

    def updateList(self, dest):
        self.clear()
        if dest == "Recent":
            self.cwd_dirs = ['..']
            self.cwd_items = config['Recent'][::-1]
            self.drawContents()
            self.path_updated.emit('Recent')
        else:
            prev_folder = os.path.basename(os.getcwd()) \
                    if os.path.abspath(dest) == os.path.dirname(os.getcwd()) \
                    else None
            os.chdir(dest)
            self.cwd_dirs, self.cwd_items = self.getContents()
            index = self.cwd_dirs.index(prev_folder) \
                    if prev_folder \
                    else 1
            self.drawContents(index)
            self.path_updated.emit(os.getcwd())

    def drawContents(self, curr_index=1):
        super(FileList, self).drawContents(curr_index, FileListItem)

    def enablePlayback(self, state):
        config['Play'] = state
        self.playback_enabled = state

    def parseInput(self, text):
        if len(text) > 0:
            text = str(text)
            if not str(text)[0] == "/": self.searchText(text)

    def searchText(self, text):
        '''uses find, grep and awk to search within the current working directory'''
        ignore_case = ' && '.join(map(
            lambda word: '/{}/'.format(
                ''.join(map(
                    lambda z: '[{}{}]'.format(
                        z.lower(), z.upper()),
                    (c for c in word)))),
                text.split()))

        cmd = "find '{}' | grep -vE '\.asd|\.pf' | grep -E '{}'| awk {}".format(
                os.getcwd(),
                audio_only,
                ignore_case)

        results = subprocess.check_output(cmd, shell=True).decode('utf-8').split('\n')[:100]
        self.showSearch(results)

    def showSearch(self, results):
        self.clear()
        self.cwd_dirs = ['..', os.getcwd()]
        self.cwd_items = map(
                lambda s: './{}'.format(s[len(os.getcwd())+1:]),
                filter(None, results[:100])
                )
        self.drawContents()


#Story Background
print("Welcome to my first game!")
name = input("What is your name? ")
age = int(input("What is your age? "))

skill = 100

#Game Start number question
if age >= 18:
    print("Congrats, you are in the Computer Science Program!")

#Question 2 yes/no
    wants_to_play = input("Do you know the basics?? ").lower()

#Question 2 yes answer
    if wants_to_play == "yes":
        print("Great your skill level is", skill, ".")
        print("Let's start your classes.")

#Question 3 text based answer
        left_or_right = input("First choice... (1)Software Engineering or (2)Art History 1? Choose your class number. ")
        if left_or_right == "1":

#Question 4 text based answer
            ans = input("Ask a coding question from this clas? (for now type software) ")
            if ans == "software":
                print("Great job. You passed your class. Move on to your next steps.")
                skill -= 5

#Scoring Example
                if skill <= 0:
                    print("You might need to repeat this class before moving to the next step.")
                else:
                    print("Congrats you finished your first class. ")

#Question 4 failed answer
            else:
                print("Try again to move forward ")

#Question 3 failed answer
        else:
            print("Maybe Computer Science is not your first choice. Talk to a your advisor to make sure this is the right fit.")

#Question 2 no answer
    else:
        print("Come back when you are ready...")

#Game Start wrong answer
else:
    print("You are too young. Keep practicing and come back after highschool.")


import pygame
import os
import random

# sets working directory to python file folder to fix errors when running game through vscode
os.chdir(os.path.dirname(os.path.abspath(__file__)))

pygame.init()

#Backround and window
win_width = 1000
win_height = 500
win = pygame.display.set_mode((win_width, win_height))
bg_img = pygame.image.load("./assets/img/background.png")
bg = pygame.transform.scale(bg_img, (win_width, win_height))

fonts = pygame.font.get_fonts()
font1 = pygame.font.SysFont(None,48)
font2 = pygame.font.SysFont(None,100)

#Global variables for tracking stuff
lastshot = 0 # for shooting cooldown
lastspawn = 0 #for spawning enemies once in a while
lastdmg = 0 #for not getting instakilled
enemies = [] #support for multiple enemies
obstacles = []
groundlevel = 390
run = True
winning = True
#Initializing sounds
pygame.mixer.init()
pygame.mixer.music.load('./assets/audio/Retrogame_music_1.ogg')
pygame.mixer.music.set_volume(0.4)
pygame.mixer.music.play()

death_sound = pygame.mixer.Sound("./assets/audio/UOHu.ogg")
olkapaa = pygame.mixer.Sound("./assets/audio/Ai_vittu_mun_olkapaa.ogg")
shoot = pygame.mixer.Sound("./assets/audio/Ampuskelu.ogg")
iced = pygame.mixer.Sound("./assets/audio/Jaassssa.ogg")
player_death = pygame.mixer.Sound("./assets/audio/Kertaakaa.ogg")
point = pygame.mixer.Sound("./assets/audio/Pisteaani.ogg")

enemyDeathSounds = [olkapaa,death_sound,iced]

pygame.display.set_caption("Megamogosen")

standing = pygame.image.load("./assets/img/standing.png") #not used ?
bullet_img = pygame.transform.scale(pygame.image.load("./assets/img/new_bullet.png"), (10, 10))

def draw_game():
    win.fill((0,0,0))
    win.blit(bg, (0, 0))
    player.draw(win)
    #pygame.draw.rect(win,(0,255,0),player.rect)
    for e in enemies:
        e.draw(win)
        #pygame.draw.rect(win,(255,0,0),e.rect)            #comment draw.rects out, only for debugging hitboxes
    for bullet in player.bullets:
        bullet.draw_bullet()
        #pygame.draw.rect(win,(255,0,0),bullet.rect)
    for o in obstacles:
        pygame.draw.rect(win,(255,255,255),o.rect)
        o.draw(win)
    pygame.time.delay(30)
    pygame.display.update()

class Hero:
    left = []
    #for picIndex in range(1, 5):
    #    left.append(pygame.image.load("./assets/img/L" + str(picIndex)+ ".png"))
    left.append(pygame.image.load("./assets/img/PL1.png"))
    right = []
    #for picIndex in range(1, 5):
    #    right.append(pygame.image.load("./assets/img/R" + str(picIndex)+ ".png"))
    right.append(pygame.image.load("./assets/img/PR1.png"))
    def __init__(self, x, y):
        self.rect = pygame.Rect(x,y,25,50)
        self.x = x
        self.y = y
        self.velx = 10
        self.vely = 10
        self.face_right = True
        self.face_left = False
        self.stepIndex = 0
        self.jump = False
        self.tolerance = 16
        self.bullets = []
        self.ammo = 25
        self.points = 0
        self.health = 100

    def move(self, userInput):
        if userInput[pygame.K_d] and self.rect.x <= win_width - 55:
            self.x += self.velx
            self.face_right = True
            self.face_left = False
        elif userInput[pygame.K_a] and self.x >= 0:
            self.x -= self.velx
            self.face_right = False
            self.face_left = True
        else:
            self.stepIndex = 0

        if userInput[pygame.K_w] and self.jump is False:
            self.jump = True

        if self.jump == True:
            self.y -= self.vely*1.5
            self.vely -= 1
        if self.y>=groundlevel: #stops character from falling under the ground
            self.jump = False
            self.vely = 10
        if self.jump == False : self.vely = 10  #reset velocity for next jump

        self.rect.x = self.x+20    #update rect pos
        self.rect.y = self.y+15

    def draw(self, win):
        #if self.stepIndex >= 4:
        #    self.stepIndex = 0
        if self.face_left:
            win.blit(self.left[0], (self.x+self.left[0].get_width()/2, self.y+self.left[0].get_height()/3))
        #    self.stepIndex += 1
        if self.face_right:
            win.blit(self.right[0], (self.x+self.left[0].get_width()/2, self.y+self.left[0].get_height()/3))
         #   self.stepIndex += 1
        if self.y > groundlevel: self.y=groundlevel
        ammotext = font1.render("Ammo: "+str(self.ammo), True, (255,255,255))
        win.blit(ammotext,(0,35))

        pointtext = font1.render("Points: "+str(self.points), True, (255,255,255))
        win.blit(pointtext,(0,70))

        healthtext = font1.render("HP: "+str(self.health), True, (255,0,0))
        win.blit(healthtext,(0,0))
        if self.health <= 0:
            self.death()

    def direction(self):
        if self.face_right:
            return 1
        if self.face_left:
            return -1

    def death(self):
        global winning
        pygame.mixer.music.pause()
        pygame.mixer.Sound.play(player_death)
        winning = False
        deathtext = font2.render("GAME OVER", True, (255,0,0))
        win.blit(deathtext,(300,250))

    def shoot(self):
        global lastshot
        cdamount = 200

        if userInput[pygame.K_SPACE] and lastshot+cdamount < pygame.time.get_ticks() and self.ammo > 0:  #shoots only if cdamount (milliseconds) has passed
            pygame.mixer.Sound.play(shoot)
            lastshot = pygame.time.get_ticks() #update time
            self.ammo -= 1
            bullet = Bullet(self.x, self.y+10, self.direction())
            self.bullets.append(bullet)
        for bullet in self.bullets:
            bullet.move()

class Obstacle:
    def __init__(self,x,y,width,height):
        self.rect = pygame.Rect(x,y,width,height)
        self.x = x
        self.y = y
        self.tolerance = 5

    def draw(self, win):
        #win.blit(self.box_image, (self.x, self.y))

        #collision detection
        if self.rect.colliderect(player.rect) and abs(self.rect.top - player.rect.top) < 20:    #if player is colliding and about on the same level
            if abs(player.rect.right - self.rect.left) < 7:     #if players right side is close to obstacles left side, push player to the left
                player.x -= player.velx
            if abs(player.rect.left-self.rect.right)<12:        #above but right side with larger tolerance for weird hitbox
                player.x+= player.velx

        if abs(player.rect.bottom - self.rect.top) < self.tolerance and self.rect.left<player.rect.centerx and self.rect.right>player.rect.centerx: #if player is above obstacle and players center is between obstacles left and right side
            player.jump = False #prevents from falling through
            if player.rect.right < self.rect.centerx or player.rect.left > self.rect.centerx:   #make player fall off the side
                player.vely = 0
                player.jump = True

class Enemy:
    left = []
    for picIndex in range(1, 10):
        left.append(pygame.image.load("./assets/img/L" + str(picIndex)+ "E.png"))

    right = []
    for picIndex in range(1, 10):
        right.append(pygame.image.load("./assets/img/R" + str(picIndex)+ "E.png"))
    def __init__(self, x, y, end):
        self.rect = pygame.Rect(x,y+15,25,50)
        self.x = x
        self.y = y
        self.velx = 5
        self.vely = 10
        self.face_right = True
        self.face_left = False
        self.stepIndex = 0
        self.end = end
        self.path = [self.x,self.end]

    def move(self):
        global lastdmg
        if abs(self.rect.centerx-player.rect.centerx) < 30 and abs(self.rect.top - player.rect.bottom)>25 and lastdmg+1000 < pygame.time.get_ticks():
           lastdmg = pygame.time.get_ticks()
           player.health -= 10
        if self.velx > 0:
            if self.x + self.velx < self.end:
                self.x += self.velx
                self.face_right = True
                self.face_left = False
            else:
                self.velx = self.velx*-1
                self.face_right = False
                self.face_left = True
                self.stepIndex = 0
        else:
            if self.x - self.velx > self.path[0]:
                self.x += self.velx
            else:
                self.velx = self.velx *-1
                self.face_right = False
                self.face_left = True
                self.stepIndex = 0
        self.rect.x = self.x+20

    def draw(self, win):
        self.move()
        if self.stepIndex >= 4:
            self.stepIndex = 0
        if self.face_left:
            win.blit(self.left[self.stepIndex], (self.x, self.y))
            self.stepIndex += 1
        if self.face_right:
            win.blit(self.right[self.stepIndex], (self.x, self.y))
            self.stepIndex += 1

        if self.rect.colliderect(player.rect) and abs(self.rect.top - player.rect.top) < 20:    #check if player is colliding and on the same level
            if abs(player.rect.right - self.rect.left) < 7:     #check which side is closer to determine direction to push player
                player.x -= player.velx
            if abs(player.rect.left-self.rect.right)<7:
                player.x+= player.velx

        if abs(player.rect.bottom - self.rect.top) < 5 and self.rect.left-10<player.rect.centerx and self.rect.right+10>player.rect.centerx: #if player is above obstacle and players center is between obstacles left and right side
            player.jump = False #prevents from falling through
            if player.rect.right < self.rect.centerx or player.rect.left > self.rect.centerx:   #make player fall off the side
                player.vely = 0
                player.jump = True

    def death(self):
        pygame.mixer.Sound.play(random.choice(enemyDeathSounds))
        player.ammo += 2
        player.points += 1
        if player.points%10 == 0: pygame.mixer.Sound.play(point)

class Bullet:
    def __init__(self, x, y, direction):
        self.x = x + 15
        self.y = y + 25
        self.direction = direction
        self.rect = pygame.Rect(x+15,y+25,10,10)
        self.visible = True

    def draw_bullet(self):
        if self.visible:
            win.blit(bullet_img, (self.x, self.y))

    def move(self):
        self.rect.x = self.x
        obstaclec = self.rect.collidelist(obstacles)
        enemyc = self.rect.collidelist(enemies)
        if self.visible:
            if self.direction == 1:
                self.x += 35        #bullet speed

            if self.direction == -1:
                self.x -= 35
            if obstaclec!=-1:
                self.visible = False
            if enemyc!=-1:
                enemies[enemyc].death()                      #call death sound
                del enemies[enemyc]                          #deletes enemy instance that collided
                self.visible = False

player = Hero(250, groundlevel)
#enemies.append(Enemy(random.randint(0,500),groundlevel,random.randint(200,800)))        #always append to enemies list when creating new instances
#enemies.append(Enemy(random.randint(0,500),groundlevel,random.randint(200,800)))        #in Enemy(x,y,z), x is x pos, y is y pos and z is the lenght of the enemy's travel
#enemies.append(Enemy(random.randint(0,500),groundlevel,random.randint(200,800)))
obstacles.append(Obstacle(450,groundlevel,50,50))
#enemies.append(Enemy(200,groundlevel,0))

while run:

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
    if winning:
        if lastspawn+2500 < pygame.time.get_ticks():                   #for spawning enemies every 1.5 second
            lastspawn = pygame.time.get_ticks()
            enemies.append(Enemy(random.randint(0,500),groundlevel,random.randint(200,900)))
        userInput = pygame.key.get_pressed()
        player.shoot()
        player.move(userInput)
        draw_game()


"""
2 вариант.
Получить на вход два файла с предложениями в формате CONLL.
В памяти сформировать деревья предложений,
вывести деревья предложений в консоль, используя пробелы для форматных отступов.
Определить, является ли второе дерево поддеревом первого.

NB:
В чате написали, что вопрос омонимии деревьев решается на усмотрение студента.
Мне кажется, что дерево_1 (родитель: А; потомки: Б, В) != дерево_2 (родитель: А; потомки: В, Б)
Например,  дереву_1 соответствует предложение "она упала и заплакала",
а дереву_2 – предложение "она заплакала и упала". С семантической точки зрения предложения не омонимичны,
хотя 'упала' и 'заплакала' соседи и у них общий предок.
И больше всего будет заметна разница предложений, если мы захотим по дереву восстановить предложение,
как мы делали на одной из лекций.
"""

def tree_of_sentence(filename):
    with open(filename, encoding='utf-8') as f:
        lines = f.readlines()
        words = [l.split() for l in lines]

        tokens = [w[2] for w in words]
        nodes = [('root', [])]
        nodes.extend([(t, []) for t in tokens])

        for num, word in enumerate(words):
            nodes[int(word[6])][1].append(nodes[num+1])
        return nodes[0]

def print_tree(node, shift=0):
    print(' ' * shift, node[0])
    for child in node[1]:
        print_tree(child, shift+2)

def convert_tree(tree):
    res = tree[0]
    for elem in tree[1]:
        res += convert_tree(elem)
    return res

def is_subtree_in_tree(tree, subtree):
    return convert_tree(subtree) in convert_tree(tree)

if __name__ == '__main__':
    # tree2ns.txt – дерево не является поддеревом (not subtree)
    # tree2s.txt – дерево является поддеревом (subtree)
    # можно проветить на обоих файлах, но в коде проверяю на tree2ns.txt
    tree1 = tree_of_sentence('tree1.txt')
    tree2 = tree_of_sentence('tree2ns.txt')

    print('The first tree:')
    print_tree(tree1)

    print(f'\nThe second tree:')
    print_tree(tree2)

    print(f'\nIs the second tree is a subtree of the first one: {is_subtree_in_tree(tree1, tree2)}.')