from cmath import sin
from datetime import datetime
from email.mime import image
from unicodedata import name
import graphene
from graphene_django import DjangoObjectType
from graphene.types.field import Field
from library.songs.models import *
from typing_extensions import Required
from sqlalchemy import desc
from graphene_django import DjangoObjectType
from django_filters import FilterSet, OrderingFilter

class GenreType(DjangoObjectType):
    class Meta:
        model = Genre
        fields = '__all__'
        ordering = ('id',)

class SingerType(DjangoObjectType):
    class Meta:
        model = Singer
        fields = '__all__'
        ordering = ('id',)

class AlbumType(DjangoObjectType):
    class Meta:
        model = Album
        fields = '__all__'
        ordering = ('releaseDate',)

class SongType(DjangoObjectType):
    class Meta:
        model = Song
        fields = '__all__'
        ordering = ('releaseDate',)

class GenreQuery(graphene.ObjectType):
    all_genres_sorting = graphene.List(
        GenreType, first=graphene.Int(), skip=graphene.Int(), asc=graphene.Boolean(required=False), field=graphene.String(required=False))
    genres_by_name_asc = graphene.List(
        GenreType, name=graphene.String(required=True))
    genres_by_name_desc = graphene.List(
        GenreType, name=graphene.String(required=True))

    def resolve_all_genres_sorting(root, info, asc=True, field="id", first=None, skip=None):
        genres = Genre.objects.all().order_by(
            f'{field}' if asc else f'-{field}')
        if skip is not None:
            genres = genres[:skip]
        if first is not None:
            genres = genres[first:]
        return genres

    def resolve_genres_by_name_asc(root, info, name):
        try:
            return Genre.objects.filter(name=name).order_by('id')
        except Genre.DoesNotExist:
            return None
    def resolve_genres_by_name_desc(root, info, name):
        try:
            return Genre.objects.filter(name=name).order_by('-id')
        except Genre.DoesNotExist:
            return None

class SingerQuery(graphene.ObjectType):
    all_singers_sorting = graphene.List(
        SingerType, first=graphene.Int(), skip=graphene.Int(), asc=graphene.Boolean(required=False), field=graphene.String(required=False))
    all_singers_asc = graphene.List(
        SingerType, first=graphene.Int(), skip=graphene.Int())
    all_singers_desc = graphene.List(
        SingerType, first=graphene.Int(), skip=graphene.Int())
    singer_by_name_asc = graphene.List(
        SingerType, name=graphene.String(required=True))
    singer_by_name_desc = graphene.List(
        SingerType, name=graphene.String(required=True))

    def resolve_all_singers_sorting(root, info, asc=True, field="id", first=None, skip=None):
        singers = Singer.objects.all().order_by(f'{field}' if asc else f'-{field}')
        if skip is not None:
            singers = singers[:skip]
        if first is not None:
            singers = singers[first:]
        return singers

    def resolve_all_singers_asc(root, info, first=None, skip=None):

        #     from django.contrib.auth.middleware import get_user
        #     from graphql_jwt.utils import get_payload, get_user_by_payload
        #     context = info.context
        #     print('info',dir(context))
        #     user = info.context.user
        #     print('IS AUTHENTICATED? ', user.is_authenticated)
        #     if not user.is_authenticated:
        #         raise Exception("Authentication credentials were not provided")

        singers = Singer.objects.all().order_by('id')
        if skip is not None:
            singers = singers[:skip]
        if first is not None:
            singers = singers[first:]
        return singers

    def resolve_all_singers_desc(root, info, first=None, skip=None):
        singers = Singer.objects.all().order_by('-id')
        if skip is not None:
            singers = singers[:skip]
        if first is not None:
            singers = singers[first:]
        return singers

    def resolve_singer_by_name_asc(root, info, name):
        try:
            return Singer.objects.filter(name=name).order_by('id')
        except Singer.DoesNotExist:
            return None

    def resolve_singer_by_name_desc(root, info, name):
        try:
            return Singer.objects.filter(name=name).order_by('-id')
        except Singer.DoesNotExist:
            return None

class AlbumQuery(graphene.ObjectType):
    all_albums_sorting = graphene.List(
        AlbumType, first=graphene.Int(), skip=graphene.Int(), asc=graphene.Boolean(required=False), field=graphene.String(required=False))
    album_by_name_asc = graphene.List(AlbumType, name=graphene.String(required=True))
    album_by_name_desc = graphene.List(AlbumType, name=graphene.String(required=True))
    all_albums_asc = graphene.List(AlbumType, first=graphene.Int(), skip=graphene.Int())
    all_albums_desc = graphene.List(AlbumType, first=graphene.Int(), skip=graphene.Int())

    def resolve_all_albums_sorting(root, info, asc=True, field="id", first=None, skip=None):
        albums = Album.objects.all().order_by(f'{field}' if asc else f'-{field}')
        if skip is not None:
            albums = albums[:skip]
        if first is not None:
            albums = albums[first:]
        return albums

    def resolve_album_by_name_asc(root, info, name):
        try:
            return Album.objects.filter(name=name).order_by('releaseDate')
        except Album.DoesNotExist:
            return None

    def resolve_album_by_name_desc(root, info, name):
        try:
            return Album.objects.filter(name=name).order_by('-releaseDate')
        except Album.DoesNotExist:
            return None

    def resolve_all_albums_asc(root, info, first=None, skip=None):
    #     from django.contrib.auth.middleware import get_user
    #     from graphql_jwt.utils import get_payload, get_user_by_payload
    #     context = info.context
    #     print('info',dir(context))
    #     user = info.context.user
    #     print('IS AUTHENTICATED? ', user.is_authenticated)
    #     if not user.is_authenticated:
    #         raise Exception("Authentication credentials were not provided")
        albums = Album.objects.all().order_by('releaseDate')
        if skip is not None:
            albums = albums[:skip]
        if first is not None:
            albums = albums[first:]
        return albums

    def resolve_all_albums_desc(root, info, first=None, skip=None):
        albums = Album.objects.all().order_by('-releaseDate')
        if skip is not None:
            albums = albums[:skip]
        if first is not None:
            albums = albums[first:]
        return albums

class SongQuery(graphene.ObjectType):
    song_by_id = graphene.Field(SongType, id=graphene.Int(required=True))
    song_by_name_asc = graphene.List(SongType, name=graphene.String(required=True))
    song_by_name_desc = graphene.List(SongType, name=graphene.String(required=True))
    all_songs_asc = graphene.List(SongType, first=graphene.Int(), skip=graphene.Int())
    all_songs_desc = graphene.List(SongType, first=graphene.Int(), skip=graphene.Int())
    all_songs_sorting = graphene.List(
        SongType, first=graphene.Int(), skip=graphene.Int(), asc=graphene.Boolean(required=False), field=graphene.String(required=False))

    def resolve_all_songs_sorting(root, info, asc=True, field="id", first=None, skip=None):
        songs = Song.objects.all().order_by(f'{field}' if asc else f'-{field}')
        if skip is not None:
            songs = songs[:skip]
        if first is not None:
            songs = songs[first:]
        return songs

    def resolve_all_songs_asc(root, info, first=None, skip=None):
        songs = Song.objects.all().order_by('releaseDate')
        if skip is not None:
            songs = songs[:skip]
        if first is not None:
            songs = songs[first:]
        return songs

    def resolve_all_songs_desc(root, info, first=None, skip=None):
        # from django.contrib.auth.middleware import get_user
        # from graphql_jwt.utils import get_payload, get_user_by_payload
        # context = info.context
        # print('info',dir(context))
        # user = info.context.user
        # print('IS AUTHENTICATED? ', user.is_authenticated)
        # if not user.is_authenticated:
        #     raise Exception("Authentication credentials were not provided")
        songs = Song.objects.all().order_by('-releaseDate')
        if skip is not None:
            songs = songs[:skip]
        if first is not None:
            songs = songs[first:]
        return songs

    def resolve_song_by_id(root, info, id):
        try:
            return Song.objects.get(pk=id)
        except Song.DoesNotExist:
            return None

    def resolve_song_by_name_asc(root, info, name):
        try:
            return Song.objects.filter(name__contains=name).order_by('releaseDate')
        except Song.DoesNotExist:
            return None

    def resolve_song_by_name_desc(root, info, name):
        try:
            return Song.objects.filter(name__contains=name).order_by('-releaseDate')
        except Song.DoesNotExist:
            return None

class GenresInput(graphene.InputObjectType):
    id = graphene.ID()
    name = graphene.String()

class SingersInput(graphene.InputObjectType):
    id = graphene.ID()
    name = graphene.String()
    lastName = graphene.String()
    stageName = graphene.String()
    nationality = graphene.String()
    image = graphene.String()

class AlbumsInput(graphene.InputObjectType):
    id = graphene.ID()
    name = graphene.String(required=True)
    releaseDate = graphene.String()
    physicalPrice = graphene.Int()
    stock = graphene.Int()
    image = graphene.String()
    singer = graphene.Field(SingersInput)
    genre = graphene.Field(GenresInput)

class SongsInput(graphene.InputObjectType):
    id = graphene.ID()
    name = graphene.String(required=True)
    releaseDate = graphene.String()
    duration = graphene.Int()
    completeFile = graphene.String()
    previewFile = graphene.String()
    digitalPrice = graphene.Decimal()
    singer = graphene.Field(SingersInput)
    album = graphene.Field(AlbumsInput)

class UpsertGenreMutation(graphene.Mutation):
    class Arguments:
        # The input arguments for this mutation
        id = graphene.ID()
        name = graphene.String(required=True)
    # The class attributes define the response of the mutation
    genre = graphene.Field(GenreType)
    status = graphene.String()

    @classmethod
    def mutate(cls, root, info, name, id=None):
        genre = None
        if id is not None:
            try:
                genre = Genre.objects.get(pk=id)
                genre.name = name
                genre.save()
            except Genre.DoesNotExist:
                return cls(genre=None, status='Genre not found')
        else:
            genre = Genre.objects.create(name=name)
            genre.save()
        # Notice we return an instance of this mutation
        return UpsertGenreMutation(genre=genre)

class UpsertSingerMutation(graphene.Mutation):
    class Arguments:
        # The input arguments for this mutation
        id = graphene.ID()
        stageName = graphene.String(required=True)
        name = graphene.String(required=True)
        lastName = graphene.String(required=True)
        nationality = graphene.String(required=True)
        image = graphene.String(required=True)
    # The class attributes define the response of the mutation
    singer = graphene.Field(SingerType)
    status = graphene.String()

    @classmethod
    def mutate(cls, root, info, stageName, name, lastName, nationality, image, id=None):
        singer = None
        if id is not None:
            try:
                singer = Singer.objects.get(pk=id)
                singer.name = name
                singer.stageName = stageName
                singer.lastName = lastName
                singer.nationality = nationality
                singer.image = image
                singer.save()
            except Singer.DoesNotExist:
                return cls(singer=None, status='Singer not found')
        else:
            singer = Singer.objects.create(
                name=name, stageName=stageName, lastName=lastName, nationality=nationality, image=image)
            singer.save()
        # Notice we return an instance of this mutation
        return UpsertSingerMutation(singer=singer)

class UpsertAlbumMutation(graphene.Mutation):
    class Arguments:
        # The input arguments for this mutation
        id = graphene.ID()
        name = graphene.String(required=True)
        releaseDate = graphene.String()
        physicalPrice = graphene.Decimal(
            required=True, description='Physical price')
        stock = graphene.Int(required=True)
        image = graphene.String()
        singer = SingersInput(required=True)
        genre = GenresInput(required=True)
    # The class attributes define the response of the mutation
    album = graphene.Field(AlbumType)
    status = graphene.String()

    @classmethod
    def mutate(cls, root, info, **kwargs):
        print('info:', dir(info.context))
        print('headers:', info.context.headers)
        aux_singer = None
        if 'singer' in kwargs:
            singer = kwargs.pop('singer')
            if 'id' in singer:
                try:
                    aux_singer = Singer.objects.get(pk=singer['id'])
                    if 'name' in singer:
                        aux_singer.name = singer['name']
                    if 'lastName' in singer:
                        aux_singer.lastName = singer['lastName']
                    if 'stageName' in singer:
                        aux_singer.stageName = singer['stageName']
                    if 'nationality' in singer:
                        aux_singer.nationality = singer['nationality']
                    if 'name' in singer:
                        aux_singer.image = singer['image']
                    aux_singer.save()
                except Singer.DoesNotExist:
                    return cls(status='Singer not found', singer=None)
            else:
                aux_singer = Singer.objects.create(
                    name=singer['name'],
                    lastName=singer['lastName'],
                    stageName=singer['stageName'],
                    nationality=singer['nationality'],
                    image=singer['image']
                )
                aux_singer.save()
        aux_genre = None
        if 'genre' in kwargs:
            genre = kwargs.pop('genre')
            if 'id' in genre:
                try:
                    aux_genre = Genre.objects.get(pk=genre['id'])
                    if 'name' in genre:
                        aux_genre.name = genre['name']
                    aux_genre.save()
                except Genre.DoesNotExist:
                    return cls(status='Genre not found', genre=None)
            else:
                aux_genre = Genre.objects.create(name=genre['name'])
                aux_genre.save()
        if 'id' in kwargs:
            album = None
            try:
                album = Album.objects.get(pk=kwargs['id'])
                album.name = kwargs['name']
                album.physicalPrice = kwargs['physicalPrice']
                album.stock = kwargs['stock']
                album.genre = aux_genre
                album.singer = aux_singer
                if 'releaseDate' in kwargs:
                    album.releaseDate = datetime.strptime(
                        kwargs['releaseDate'], "%Y-%m-%d")
                if 'image' in kwargs:
                    album.image = kwargs['image']
                album.save()
            except Album.DoesNotExist:
                return cls(album=None, status='Album not found')
        else:
            album = Album.objects.create(
                name=kwargs['name'],
                physicalPrice=kwargs['physicalPrice'],
                stock=kwargs['stock'],
                genre=aux_genre,
                singer=aux_singer
            )
            if 'releaseDate' in kwargs:
                album.releaseDate = datetime.strptime(
                    kwargs['releaseDate'], "%Y-%m-%d")
            if 'image' in kwargs:
                album.image = kwargs['image']
            album.save()
        # Notice we return an instance of this mutation
        return UpsertAlbumMutation(album=album, status='ok')

class UpsertSongMutation(graphene.Mutation):
    class Arguments:
        # The input arguments for this mutation
        id = graphene.ID()
        name = graphene.String(required=True)
        releaseDate = graphene.String()
        duration = graphene.Int(
            required=True, description='Duration of the Song')
        completeFile = graphene.String()
        previewFile = graphene.String()
        digitalPrice = graphene.Decimal(
            required=True, description='Average price')
        singerId = graphene.Int(required=True)
        albumId = graphene.Int(required=True)
    # The class attributes define the response of the mutation
    song = graphene.Field(SongType)
    status = graphene.String()

    @classmethod
    def mutate(cls, root, info, **kwargs):
        print('info:', dir(info.context))
        print('headers:', info.context.headers)
        if 'id' in kwargs:
            song = None
            try:
                song = Song.objects.get(pk=kwargs['id'])
                song.name = kwargs['name']
                print("===============")
                print(kwargs['completeFile'])
                print("===============")
                song.digitalPrice = kwargs['digitalPrice']
                song.completeFile = kwargs['completeFile']
                song.duration = kwargs['duration']
                song.previewFile = kwargs['previewFile']
                song.album = Album.objects.get(pk=kwargs['albumId'])
                song.singer = Singer.objects.get(pk=kwargs['singerId'])
                if 'releaseDate' in kwargs:
                    song.releaseDate = datetime.strptime(
                        kwargs['releaseDate'], "%Y-%m-%d")
                song.save()
            except Song.DoesNotExist:
                return cls(song=None, status='Song not found')
        else:
            song = Song.objects.create(
                name = kwargs['name'],
                digitalPrice = kwargs['digitalPrice'],
                completeFile = kwargs['completeFile'],
                duration = kwargs['duration'],
                previewFile = kwargs['previewFile'],
                album = Album.objects.get(pk=kwargs['albumId']),
                singer = Singer.objects.get(pk=kwargs['singerId'])
                )
            if 'releaseDate' in kwargs:
                song.releaseDate = datetime.strptime(kwargs['releaseDate'], "%Y-%m-%d")
            song.save()
        # Notice we return an instance of this mutation
        return UpsertSongMutation(song=song, status='ok')

class DeleteGenreMutation(graphene.Mutation):
    ok = graphene.Boolean()

    class Arguments:
        id = graphene.ID()

    @classmethod
    def mutate(cls, root, info, **kwargs):
        genre = Genre.objects.get(pk=kwargs["id"])
        genre.delete()
        return cls(ok=True)

class DeleteSingerMutation(graphene.Mutation):
    ok = graphene.Boolean()

    class Arguments:
        id = graphene.ID()

    @classmethod
    def mutate(cls, root, info, **kwargs):
        singer = Singer.objects.get(pk=kwargs["id"])
        singer.delete()
        return cls(ok=True)

class DeleteAlbumMutation(graphene.Mutation):
    ok = graphene.Boolean()

    class Arguments:
        id = graphene.ID()

    @classmethod
    def mutate(cls, root, info, **kwargs):
        album = Album.objects.get(pk=kwargs["id"])
        album.delete()
        return cls(ok=True)

class DeleteSongMutation(graphene.Mutation):
    ok = graphene.Boolean()

    class Arguments:
        id = graphene.ID()

    @classmethod
    def mutate(cls, root, info, **kwargs):
        song = Song.objects.get(pk=kwargs["id"])
        song.delete()
        return cls(ok=True)

class SongMutation(graphene.ObjectType):
    pass
    upsert_genre = UpsertGenreMutation.Field()
    upsert_singer = UpsertSingerMutation.Field()
    upsert_album = UpsertAlbumMutation.Field()
    upsert_song = UpsertSongMutation.Field()
    delete_genre = DeleteGenreMutation.Field()
    delete_singer = DeleteSingerMutation.Field()
    delete_album = DeleteAlbumMutation.Field()
    delete_song = DeleteSongMutation.Field()


import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
import numpy as np

'''
    3D VQVAE parts for animation
'''

def get_animation_encoder(latent_dim, num_frames):
    encoder_inputs = keras.Input(shape=(num_frames, 128, 128, 3), name="input")
    x = layers.Conv3D(32, 3, activation="relu", strides=(1, 2, 2), padding="same")(
        encoder_inputs
    )
    x = layers.BatchNormalization()(x)
    x = layers.Conv3D(64, 3, activation="relu", strides=(1, 2, 2), padding="same")(x)
    x = layers.BatchNormalization()(x)
    x = layers.Conv3D(64, 3, activation="relu", strides=1, padding="same")(x)
    x = layers.BatchNormalization()(x)
    x = layers.Conv3D(128, 3, activation="relu", strides=1, padding="same")(x)
    x = layers.BatchNormalization()(x)
    x = layers.Conv3D(64, 1, activation="relu", strides=1, padding="same")(x)
    encoder_outputs = layers.Conv3D(latent_dim, 1, padding="same")(x)
    return keras.Model(encoder_inputs, encoder_outputs, name="encoder")

def get_animation_decoder(latent_dim, num_frames):
    latent_inputs = keras.Input(shape=get_animation_encoder(latent_dim, num_frames).output.shape[1:])

    x = layers.Conv3DTranspose(128, 3, activation="relu", strides=(1, 2, 2), padding="same")(
        latent_inputs
    )
    x = layers.BatchNormalization()(x)
    x = layers.Conv3DTranspose(64, 3, activation="relu", strides=(1, 2, 2), padding="same")(
        x
    )
    x = layers.BatchNormalization()(x)
    x = layers.Conv3DTranspose(64, 3, activation="relu", strides=1, padding="same")(
        x
    )
    x = layers.BatchNormalization()(x)
    x = layers.Conv3DTranspose(64, 3, activation="relu", strides=1, padding="same")(
        x
    )
    x = layers.BatchNormalization()(x)
    x = layers.Conv3DTranspose(32, 3, activation="relu", strides=1, padding="same")(x)
    x = layers.BatchNormalization()(x)
    x = layers.Conv3DTranspose(16, 1, activation="relu", strides=1, padding="same")(x)
    decoder_outputs = layers.Conv3DTranspose(3, 3, padding="same", activation="sigmoid", name="output")(x)
    return keras.Model(latent_inputs, decoder_outputs, name="decoder")

def get_animation_vqvae(latent_dim=32, num_embeddings=64, num_frames=6):
    vq_layer = VectorQuantizer(num_embeddings, latent_dim, name="vector_quantizer")
    encoder = get_animation_encoder(latent_dim, num_frames)
    decoder = get_animation_decoder(latent_dim, num_frames)
    inputs = keras.Input(shape=(num_frames, 128, 128, 3))

    # TODO: reintroduce augmentation
    # augmented = keras.layers.RandomFlip('horizontal')(inputs)

    encoder_outputs = encoder(inputs)
    quantized_latents = vq_layer(encoder_outputs)
    reconstructions = decoder(quantized_latents)
    model = keras.Model(inputs, reconstructions, name="vq_vae")
    print(model.summary())
    return model

class VectorQuantizer(layers.Layer):
    def __init__(self, num_embeddings, embedding_dim, beta=0.25, **kwargs):
        super().__init__(**kwargs)
        self.embedding_dim = embedding_dim
        self.num_embeddings = num_embeddings
        self.beta = (
            beta  # This parameter is best kept between [0.25, 2] as per the paper.
        )

        # Initialize the embeddings which we will quantize.
        w_init = tf.random_uniform_initializer()
        self.embeddings = tf.Variable(
            initial_value=w_init(
                shape=(self.embedding_dim, self.num_embeddings), dtype="float32"
            ),
            trainable=True,
            name="embeddings_vqvae",
        )

    def call(self, x):
        # Calculate the input shape of the inputs and
        # then flatten the inputs keeping `embedding_dim` intact.
        input_shape = tf.shape(x)
        flattened = tf.reshape(x, [-1, self.embedding_dim])

        # Quantization.
        encoding_indices = self.get_code_indices(flattened)
        encodings = tf.one_hot(encoding_indices, self.num_embeddings)
        quantized = tf.matmul(encodings, self.embeddings, transpose_b=True)
        quantized = tf.reshape(quantized, input_shape)

        # Calculate vector quantization loss and add that to the layer. You can learn more
        # about adding losses to different layers here:
        # https://keras.io/guides/making_new_layers_and_models_via_subclassing/. Check
        # the original paper to get a handle on the formulation of the loss function.
        commitment_loss = self.beta * tf.reduce_mean(
            (tf.stop_gradient(quantized) - x) ** 2
        )
        codebook_loss = tf.reduce_mean((quantized - tf.stop_gradient(x)) ** 2)
        self.add_loss(commitment_loss + codebook_loss)

        # Straight-through estimator.
        quantized = x + tf.stop_gradient(quantized - x)
        return quantized

    def get_code_indices(self, flattened_inputs):
        # Calculate L2-normalized distance between the inputs and the codes.
        similarity = tf.matmul(flattened_inputs, self.embeddings)
        distances = (
            tf.reduce_sum(flattened_inputs ** 2, axis=1, keepdims=True)
            + tf.reduce_sum(self.embeddings ** 2, axis=0)
            - 2 * similarity
        )

        # Derive the indices for minimum distances.
        encoding_indices = tf.argmin(distances, axis=1)
        return encoding_indices


from src.tools.parameters import default_max_deceleration, default_max_acceleration, default_time_of_reaction as dt
from src.tools.methods import solve_degree_two

default_max_deceleration = 2

def get_acceleration_non_moving_obstacle(a_min, current_speed, current_pos, current_pos_obstacle):

    # first condition:
    z = 2 * (current_pos_obstacle - current_pos) / (dt ** 2) - 2 * current_speed / dt

    print("z = " + str(z))

    a1 = -(dt ** 2) / a_min
    a2 = (-dt * current_speed / a_min + (dt ** 2) / 2)
    a3 = - (current_speed ** 2) / (2 * a_min) + current_speed * dt + current_pos - current_pos_obstacle

    print("a1 = " + str(a1))
    print("a2 = " + str(a2))
    print("a3 = " + str(a3))

    try:
        x, y = solve_degree_two(a1, a2, a3)
        print("x = " + str(x))
        print("y = " + str(y))
    except:
        print("except")
        return a_min

    # second condition: acceleration must be lower than y

    a = min(y, z, default_max_acceleration)
    print("a = " + str(a))

    # third condition:
    w = current_speed / dt
    print("w = " + str(w))

    return a

a_min = - default_max_deceleration
current_speed = 10
current_pos = 0
current_pos_obstacle = 100

i = 0

while True:
    i += 1
    print(i)

    a = get_acceleration_non_moving_obstacle(a_min, current_speed, current_pos, current_pos_obstacle)

    current_pos = current_pos + current_speed * dt + 0.5 * a * dt ** 2
    current_speed = max(current_speed + a * dt, 0)

    if i > 10:
        current_pos_obstacle = 300

    print("current_speed: " + str(current_speed))
    print("current_pos: " + str(current_pos))


from rest_framework.response import Response
from rest_framework.decorators import api_view
from rest_framework import status
from .models import Product
from .serializers import *

@api_view(['GET'])
def productsView(request):
    data    = Product.objects.filter(owner=request.user)
    print(data)

    ser     = ProductSerializer(data, many=True)
    return Response(ser.data, status=status.HTTP_200_OK)

@api_view(['GET', 'PUT', 'DELETE'])
def productView(request, product_id):
    data    = Product.objects.get(pk=product_id)
    return True
@api_view(['GET', 'POST'])
def students_list(request):
    if request.method == 'GET':
        data = Student.objects.all()

        serializer = StudentSerializer(data, context={'request': request}, many=True)

        return Response(serializer.data)

    elif request.method == 'POST':
        serializer = StudentSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(status=status.HTTP_201_CREATED)

        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

@api_view(['PUT', 'DELETE'])
def students_detail(request, pk):
    try:
        student = Student.objects.get(pk=pk)
    except Student.DoesNotExist:
        return Response(status=status.HTTP_404_NOT_FOUND)

    if request.method == 'PUT':
        serializer = StudentSerializer(student, data=request.data,context={'request': request})
        if serializer.is_valid():
            serializer.save()
            return Response(status=status.HTTP_204_NO_CONTENT)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    elif request.method == 'DELETE':
        student.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)
@api_view(['GET', 'POST'])
def servicesList(request, title=None, description=None):
    if request.method == 'GET':
        data = Services.objects.all()
        serializer = ServicesSerializer(data, context={'request': request}, many=True)
        return Response(serializer.data)
    if request.method == 'POST':
        data = Services()
        data.title = title
        data.description = description
        data.save()

        return Response(status=status.HTTP_201_CREATED)
@api_view(['GET', 'DELETE'])
def service(request, service_title):
    service_title.lower()
    print(service_title)
    try:
        data = Services.objects.get(title=service_title)
        print(data)
    except:
        return Response(status=status.HTTP_204_NO_CONTENT)
    if request.method == 'GET':
        serailizer = ServicesSerializer(data, context={'request': request}, many=True)
        return Response(serailizer.data)

    else :
        if request.method == 'DELETE':
            try:
                data.delete()
            except:
                pass
            return Response(status=status.HTTP_200_OK)


from random import randint
from Other import Other

class Engine(object):

    def __init__(self, players: list, map_table: map):
        """

        :param players:
        :param map_table:
        """
        self.players = players
        self.map = map_table
        self.other = Other()

    def play(self):
        """

        :return:
        """
        # start player
        start_player = randint(0, 1)
        print(f"Player: {self.players[start_player].name} starts with symbol {self.players[start_player].symbol}.")
        # Show instructions
        self.map.plot_coordinates()
        # Show map
        self.map.plot_map()
        # Start playing!
        win = False
        tie = False
        turn = start_player
        turn_counter = 0
        while win is False and tie is False:
            # Get the map position
            map_position = self.players[turn].play()
            # Populate the map
            populated = self.map.populate_table(map_position, self.players[turn].symbol_num)
            # If operation was correct, update turn
            if populated:
                # The other player's turn
                turn = 1 - turn
                # Increment the turn counter
                turn_counter += 1
            # Show the map
            self.map.plot_map()
            # Verify for win condition
            win = self.win_condition(self.map.map_table)
            if turn_counter == 9:
                tie = True  # Tie condition
        print("The game has ended! Thanks for playing! :)")
        if tie and not win:
            print("Tie! No winners!")
        exit(0)

    def win_condition(self, matrix) -> list:  # Assuming players have 1 and -1 values
        # horizontal win condition
        win_h, who_symbol_num_h = self.horizontal_win_condition(matrix)
        # vertical win condition
        win_v, who_symbol_num_v = self.vertical_win_condition(matrix)
        # diagonal win condition
        win_d = self.diagonal_win_condition(matrix)
        return win_h or win_v or win_d

    def horizontal_win_condition(self, matrix):
        win = False
        who_symbol_num = None
        # horizontal win condition
        row_count = 0
        while (win is False) and (row_count <= len(matrix) - 1):
            total = sum(matrix[row_count])
            if abs(total) == 3:  # is there any winner?
                win = True
                who_symbol_num = self.other.sign_to_list_single_integer([total])
                self.who_has_won(who_symbol_num)
                return win, who_symbol_num
            else:
                row_count += 1
        return win, who_symbol_num

    def vertical_win_condition(self, matrix):
        # Transpose matrix
        transposed_matrix = list(map(list, zip(*matrix)))
        # Horizontal win condition
        win, who_symbol_num = self.horizontal_win_condition(transposed_matrix)
        return win, who_symbol_num

    def diagonal_win_condition(self, matrix):
        main_diag, second_diag = self.other.extract_diagonals(matrix)
        win_d1, who_symbol_num_d1 = self.horizontal_win_condition([main_diag])
        win_d2, who_symbol_num_d2 = self.horizontal_win_condition([second_diag])
        return win_d1 or win_d2

    def who_has_won(self, who_symbol_num):
        # Show that someone has won!
        players_to_sign = [player.symbol_num for player in self.players]
        print("{} has won!".format(self.players[players_to_sign.index(who_symbol_num)].name))

if __name__ == "__main__":
    from Map import Map
    from Player import Player

    # Create Map
    map_tab = Map()
    # Create players
    p1 = Player("selfstiano", "o")
    p2 = Player("Ignazio", "x")
    # generate a list of players
    players = [p1, p2]
    # Generate the engine
    engine = Engine(players, map_tab)

    print("Player names: {} and {}".format(*[player.name for player in players]))
    print("Player symbol: {} and {}".format(*[player.symbol for player in players]))
    print("Player symbol_to_num: {} and {}".format(*[player.symbol_num for player in players]))

    # Horizontal test - 1
    print("Horizontal tests")
    matrix = [[1, 1, 1], [0, 0, 0], [0, 0, 0]]
    engine.win_condition(matrix)
    matrix = [[0, 0, 0], [1, 1, 1], [0, 0, 0]]
    engine.win_condition(matrix)
    matrix = [[0, 0, 0], [0, 0, 0], [1, 1, 1]]
    engine.win_condition(matrix)

    # Horizontal test - 2
    matrix = [[-1, -1, -1], [0, 0, 0], [0, 0, 0]]
    engine.win_condition(matrix)
    matrix = [[0, 0, 0], [-1, -1, -1], [0, 0, 0]]
    engine.win_condition(matrix)
    matrix = [[0, 0, 0], [0, 0, 0], [-1, -1, -1]]
    engine.win_condition(matrix)

    # Vertical test - 1
    print("Vertical test")
    matrix = [[1, 0, 0], [1, 0, 0], [1, 0, 0]]
    engine.win_condition(matrix)
    matrix = [[0, 1, 0], [0, 1, 0], [0, 1, 0]]
    engine.win_condition(matrix)
    matrix = [[0, 0, 1], [0, 0, 1], [0, 0, 1]]
    engine.win_condition(matrix)

    # Vertical test - 2
    matrix = [[-1, 0, 0], [-1, 0, 0], [-1, 0, 0]]
    engine.win_condition(matrix)
    matrix = [[0, -1, 0], [0, -1, 0], [0, -1, 0]]
    engine.win_condition(matrix)
    matrix = [[0, 0, -1], [0, 0, -1], [0, 0, -1]]
    engine.win_condition(matrix)

    # Diagonal test - 1
    print("Diagonal test")
    matrix = [[1, 0, 0], [0, 1, 0], [0, 0, 1]]
    engine.win_condition(matrix)
    matrix = [[0, 0, 1], [0, 1, 0], [1, 0, 0]]
    engine.win_condition(matrix)

    # Diagonal test - 2
    matrix = [[-1, 0, 0], [0, -1, 0], [0, 0, -1]]
    engine.win_condition(matrix)
    matrix = [[0, 0, -1], [0, -1, 0], [-1, 0, 0]]
    engine.win_condition(matrix)

    # Random tests
    print("Random Test: Not winning")
    matrix = [[0, 0, 0], [0, 0, 0], [1, -1, -1]]
    engine.win_condition(matrix)
    matrix = [[1, 0, -1], [0, 0, -1], [-1, 1, 1]]
    engine.win_condition(matrix)

    print("Single list of lists")
    matrix = [[1, 1, 1]]
    engine.win_condition(matrix)


from ctypes import sizeof

s1 = input()
s2 = input()

s3 = ""

n , m = len(s1),len(s2)
count = 0
while count < n:
    s3 += s1[count] + s2[m-1]
    m -= 1
    count +=1

print(s3)

Second semester/OOP/2 week/Module 3.5/question_no_5.py


#sum of more than one digit numbers
n=input("please Enter the value of number:")
sum=0
i=0
print(f"lenght of numbers is:{len(n)}")
while i <len(n):
    print(f"index {i} value is: {n[i]}")
    sum=sum+int(n[i])
    i+=1
print(f"sum of {n} digits is:{sum}")


from algorithms import Qlearning, SARSA
import matplotlib.pyplot as plt
import gridworlds
import numpy as np
import gym

env = gym.make('PuddleWorld-v0')

def get_derivables(learner, num_episodes, num_expts, show_policy = False, show_plots = True):
	''' num_episodes is number of episodes '''
	''' num_expts is number of experiments to average the performance over '''
	''' if show_policy is True, an image will be displayed showing optimal policy found by the agent after all episodes '''
	x_axis = np.arange(num_episodes)
	avg_steps = np.zeros(num_episodes)
	avg_reward = np.zeros(num_episodes)
	for i in range(num_expts):
		print ("Experiment number %d" % i)
		steps, rwd = learner.run(num_episodes)
		avg_steps += steps
		avg_reward += rwd
		if show_policy or i == num_expts - 1:
			learner.show_policy()

	avg_steps /= float(num_expts)
	avg_reward /= float(num_expts)

	if (show_plots):
		plt.figure(1)
		plt.semilogy(x_axis, avg_steps)
		plt.ylabel("Average steps to reach the goal (log scale)")
		plt.xlabel("episodes")

		plt.figure(2)
		plt.plot(x_axis, avg_reward)
		plt.ylabel("Average reward per episode")
		plt.xlabel("episodes")

		plt.show()

	return avg_steps, avg_reward

get_derivables(Qlearning(env, verbose = False), 2000, 10, False)
#get_derivables(SARSA(env, Lambda = 0.7, verbose = False), 100, 1, False)

"""
avg_steps = []
avg_reward = []
lambdas = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7]
for l in lambdas:
	print ("    Lambda = {}".format(l))
	steps, reward = get_derivables(SARSA(env, Lambda = l, verbose = False), 25, 10, show_plots = False)
	avg_steps.append(steps[24])
	avg_reward.append(reward[24])

plt.figure(3)
plt.plot(lambdas, avg_steps)
plt.title(r"Average steps after 25 episodes for different $\lambda$")
plt.ylabel("Average steps to reach the goal (averaged over 10 experiments)")
plt.xlabel(r"$\lambda$")

plt.figure(2)
plt.plot(lambdas, avg_reward)
plt.title(r"Average reward after 25 episodes for different $\lambda$")
plt.ylabel("Average reward per episode(averaged over 10 experiments)")
plt.xlabel(r"$\lambda$")

plt.show()
"""


from sklearn.linear_model import LogisticRegression as LR
from sklearn.tree import DecisionTreeClassifier as DR
import xclib.evaluation.xc_metrics as xc_metrics
from xc.libs.utils import pbar
import scipy.sparse as sp
import numpy as np
import joblib

class Fusion(object):
    def __init__(self, reg="DecisionTrees", A=0.55, B=1.5, use_psp=False):
        self.A = A
        self.B = B
        if reg == "DecisionTrees":
            self.regressor = DR(max_depth=7)
        if reg == "LogisticRegression":
            self.regressor = LR(penalty='l2', verbose=1, n_jobs=8)

        self.inv_psp = None
        self.use_psp = use_psp
        self.valid = True
        self.val = np.asarray([])

    def split(self, trn_dset, valid_frac=0.035):
        print("FUSION:Generating SPLITS")
        valid_int = int(np.ceil(len(trn_dset)*valid_frac))
        val = np.random.choice(len(trn_dset), size=valid_int, replace=False)
        trn = np.setdiff1d(np.arange(len(trn_dset)), val)
        self.val = val
        return trn, val

    @property
    def val_indices(self):
        return self.val

    def build_psp(self, trn_y):
        print("FUSION:Building PSP")
        self.inv_psp = xc_metrics.compute_inv_propesity(
            trn_y, A=self.A, B=self.B)

    def prep_descriptor(self, m2, m4):
        rows, cols = m2.nonzero()
        module2_data = np.ravel(m2.tolil()[rows, cols].todense())
        module4_data = np.ravel(m4.tolil()[rows, cols].todense())
        inv_psp = np.ravel(self.inv_psp[cols])
        return np.vstack([inv_psp, module2_data, module4_data]).T, rows, cols

    def fit(self, m2, m4, trn_y):
        self.valid = True
        print("FUSION::SETTING UP PARAMETERS")
        X, rows, cols = self.prep_descriptor(m2, m4)
        y = np.ravel(trn_y.tolil()[rows, cols].todense())
        print("FUSION::TRAINING FUSION LAYER")
        self.regressor.fit(X, y)

    def predict(self, m2, m4, batch_size=200, a_min=1e-1):
        num_docs = m4.shape[0]
        final_score = sp.lil_matrix(m4.shape)
        for start in pbar(np.arange(0, num_docs, batch_size),
                          desc="fusion", write_final=True):
            end = min(num_docs, start+batch_size)
            chotu_m4 = m4[start:end]
            chotu_m2 = m2[start:end]
            X, rows, cols = self.prep_descriptor(chotu_m2, chotu_m4)
            y = self.regressor.predict_proba(X)[:, 1]
            y = np.clip(y, a_min, 1-a_min)
            final_score[rows+start, cols] = y
            del chotu_m2, chotu_m4
        return final_score.tocsr()

    def save(self, model_path):
        joblib.dump({"regressor": self.regressor,
                     "inv_psp": self.inv_psp,
                     "valid": self.valid,
                     "val": self.val}, model_path)

    def load(self, model_path):
        data = joblib.load(model_path)
        self.regressor = data["regressor"]
        self.inv_psp = data["inv_psp"]
        self.valid = data["valid"]
        self.val = data["val"]


import inspect, hashlib

def createHashCode(self):

    # get the source code of the operation
    source = inspect.getsource(self.operation)

    def remove_all_whitespace(str):
        ws_chars = [' ', '\t', '\n']
        for char in ws_chars:
            str = str.replace(char, '')
        return str

    def append_args(target, args):
        for a in args.values():
            target += str(a)
        return target

    # scrap the whitespace to prevent unnecessary
    # re-queries
    source_no_ws = remove_all_whitespace(source)

    # concatenate it with the arguments
    target = append_args(source_no_ws, self.arguments)

    # convert string to a hash
    hash = hashlib.md5(target.encode()).hexdigest()
    self.hashcode = hash
    self.output_file = hash
    return hash


print(" Cейчас вам будет предоставлена возможность введения слов")
print(" Когда заходите остановиться, просто введите q")

slovar = {}

while True:
    key = input("Ведите слово на английском\n: ").strip().lower()
    if key == 'q':
        break
    value = input("Ведите слово на русском\n: ").strip().lower()
    slovar[key] = value
print(slovar)

print("Сейчас у нас будет проверка, больше 3 ошибок нельзя")

errors = 0
bonus = 0

for key in slovar.keys():
    print("Ввeдите перевод слова", key, ": ")
    answer = input(": ").strip().lower()
    if slovar[key] == answer:
        bonus += 1
        print("Ваш счет составляет", bonus)
    elif errors > 3:
        print("game over")
        break
    else:
        errors +=1
        print(slovar[key], "- правильный ответ")


import os
import random
import shutil
import sys

import PyInstaller.__main__

def build(name, version, console, onefile, uac_admin, icon, files, folders):
	work_path = "build"
	while os.path.isdir(work_path):
		work_path = f"build_{random.randint(1, 1_000_000_000)}"
	work_path = os.path.join(os.path.abspath("."), work_path)

	result_path = os.path.abspath(".")

	run_list = ['main.py',
	            '--noconfirm',
	            '--clean',
	            '--name', f"{name}-v{version}",
	            '--workpath', work_path,
	            '--specpath', work_path,
	            '--distpath', result_path]

	if console:
		run_list.append("--console")
	else:
		run_list.append("--noconsole")

	if onefile:
		run_list.append("--onefile")
	else:
		run_list.append("--onedir")

	if uac_admin:
		run_list.append("--uac-admin")

	if icon != "":
		icon_path = os.path.join(os.path.abspath("."), icon)
		if not os.path.isfile(icon_path):
			raise Exception("Invalid icon!")
		else:
			run_list.extend(('--icon', icon_path))

	for file in files:
		if os.path.isfile(os.path.join(os.path.abspath("."), file)):
			run_list.extend(('--add-data', f'{os.path.join(os.path.abspath("."), file)};{os.path.dirname(file)}'))
		else:
			raise Exception("Invalid file!")

	for folder in folders:
		if os.path.isdir(folder):
			for walk in os.walk(folder, followlinks=False):
				for file in walk[2]:
					if os.path.isfile(os.path.join(walk[0], file)):
						run_list.extend(('--add-data', f'{os.path.join(os.path.abspath("."), os.path.join(walk[0], file))};{os.path.dirname(os.path.join(walk[0], file))}'))
					else:
						raise Exception("Invalid folder!")
		else:
			raise Exception("Invalid folder!")

	PyInstaller.__main__.run(run_list)
	shutil.rmtree(path=work_path, ignore_errors=True)

def main():
	name = "Full-Tilt!-Pinball"
	version = "4.0.2"

	console = False
	onefile = True
	uac_admin = False
	icon = "full-tilt-icon.ico"

	files = []
	folders = [
		"boards\\Alien",
		"boards\\Cadet",
		"boards\\Dragon",
		"boards\\Hero",
		"boards\\Mad",
		"boards\\Pirates",
	]

	if len(sys.argv) > 1 and sys.argv[1] == "--version":
		print(version)
	elif len(sys.argv) > 1 and sys.argv[1] == "--name":
		print(name)
	else:
		build(name, version, console, onefile, uac_admin, icon, files, folders)

if __name__ == '__main__':
	main()


import numpy as np
import torch
import random
from eval.eval import f1
import pdb

def load_ricap(images, targets, dilates):
    batch_images = torch.empty(images.size())
    batch_targets = torch.empty(targets.size())
    batch_dilates = torch.empty(dilates.size())
    for i in range(images.size()[0]):
        patched_image, patched_target, patched_dilate = ricap(images, targets, dilates)
        batch_images[i] = patched_image
        batch_targets[i] = patched_target
        batch_dilates[i] = patched_dilate

    return batch_images, batch_targets, batch_dilates

def ricap(images, targets, dilates):

    # size of image
    I_x, I_y = images.size()[2:]

    # generate boundary position (w, h)
    w = int(np.round(I_x * np.random.uniform(0.3, 0.7)))
    h = int(np.round(I_y * np.random.uniform(0.3, 0.7)))
    w_ = [w, I_x-w, w, I_x-w]
    h_ = [h, h, I_y-h, I_y-h]

    # select four images
    cropped_images = {}
    cropped_target = {}
    cropped_dilate = {}
    c_ = {}
    W_ = {}

    for k in range(4):
        index = random.choice(torch.randperm(images.size(0)))
        x_k = np.random.randint(0, I_x - w_[k] + 1)
        y_k = np.random.randint(0, I_y - h_[k] + 1)

        cropped_images[k] = images[index, :, x_k:x_k + w_[k], y_k:y_k + h_[k]]
        cropped_target[k] = targets[index, :, x_k:x_k + w_[k], y_k:y_k + h_[k]]
        cropped_dilate[k] = dilates[index, :, x_k:x_k + w_[k], y_k:y_k + h_[k]]
        c_[k] = targets[index]
        W_[k] = (w_[k] * h_[k]) / (I_x * I_y)

    # patch cropped images
    patched_images = torch.cat(
        (torch.cat((cropped_images[0], cropped_images[1]), 1),
         torch.cat((cropped_images[2], cropped_images[3]), 1)),
        2)
    patched_target = torch.cat(
        (torch.cat((cropped_target[0], cropped_target[1]), 1),
         torch.cat((cropped_target[2], cropped_target[3]), 1)),
        2)
    print(patched_target.size())
    patched_dilate = torch.cat(
        (torch.cat((cropped_dilate[0], cropped_dilate[1]), 1),
         torch.cat((cropped_dilate[2], cropped_dilate[3]), 1)),
        2)

    targets = (c_, W_)
    return patched_images, patched_target, patched_dilate

if __name__ == '__main__':
    input_image = torch.rand(4, 3, 256, 256)
    input_target = torch.rand(4, 1, 256, 256)
    input_target = (input_target> 0.5)*1

    image, target, dilate = load_ricap(input_image, input_target, input_target)
    print(target.size())

    acc, _, _, f1_score = f1(target, target, dilate)
    print(acc, f1_score)


from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from sklearn.utils import shuffle

import numpy as np
import tensorflow as tf

import glob
import cv2
import os

import tensorflow as tf

#local imports
from data import *

import utils as utils
from CNN import new_fc_layer
from CNN import flatten_layer
from CNN import new_conv_layer
from CNN import initiate

# disables cpu instruction warnings
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

#################################
####	global variabless 	#####
#################################

true = True
false = False
none = None

total_iterations = None     #explained later
x = None                    #explained later
y_true = None               #explained later
session = None              #explained later
optimizer = None            #explained later
accuracy = None             #explained later
graph = None

image_size = 100 									# size of the images
image_size_flat = image_size * image_size  			# Images are stored in one-dimensional arrays of this length.
image_shape = (image_size, image_size)  				# Tuple with height and width of images used to reshape arrays.
num_channels = 1  								# Number of color channels for the images: 1 channel for gray-scale.
num_classes = 2  								# Number of classes, one class for each of 10 digits.
plt_show = true  								# To show the plotted values set to true, to never plot anything set to false
class_zero = "rand"
class_one = "kw"
file_name_identifier = "kw"  					# something distinguishable to tell the two images apart
data_directory = "resized/load/chosen"			# directory to load the train images

#####################
####	Layers	#####
#####################

# Convolutional Layer 1.
filter_size1 = 10  # Convolution filters are filter_size x filter_size pixels. might change this to 0.178 * img_size xxx
num_filters1 = 16  # There are 16 of these filters.
# Convolutional Layer 2.
filter_size2 = 10  # Convolution filters are 5 x 5 pixels.
num_filters2 = 36  # There are 36 of these filters.
# Fully-connected layer.
fc_size = 128  # Number of neurons in fully-connected layer.

def initiate():
	data.test.images, data.test.labels = load_data(data_directory, file_name_identifier, image_size_flat)
	data.test = data.test.init()
	data.test._name = "test"
	data.test.cls = np.argmax(data.test.labels, axis=1)

	x = tf.placeholder(tf.float32, shape=[None, image_size_flat], name='x')
	x_image = tf.reshape(x, [-1, image_size, image_size, num_channels])

	x2 = tf.placeholder(tf.float32, shape=[None, image_size_flat], name='x2')
	x2_image = tf.reshape(x2, [-1, image_size, image_size, num_channels])

	y_true = tf.placeholder(tf.float32, shape=[None, num_classes], name='y_true')
	y_true_cls = tf.argmax(y_true, axis=1)

	layer_conv1, weights_conv1 = new_conv_layer(input=x_image, num_input_channels=num_channels,
												filter_size=filter_size1, num_filters=num_filters1, use_pooling=True)

	layer_conv2, weights_conv2 = new_conv_layer(input=layer_conv1, num_input_channels=num_filters1,
												filter_size=filter_size2, num_filters=num_filters2, use_pooling=True)

	layer_flat, num_features = flatten_layer(layer_conv2)

	layer_fc1 = new_fc_layer(input=layer_flat, num_inputs=num_features, num_outputs=fc_size, use_relu=True)

	layer_fc2 = new_fc_layer(input=layer_fc1, num_inputs=fc_size, num_outputs=num_classes, use_relu=False)

	y_pred = tf.nn.softmax(layer_fc2)
	y_pred_cls = tf.argmax(y_pred, axis=1)
	cross_entropy = tf.nn.softmax_cross_entropy_with_logits_v2(logits=layer_fc2,
															   labels=y_true)
	cost = tf.reduce_mean(cross_entropy)
	optimizer = tf.train.AdamOptimizer(learning_rate=1e-4).minimize(cost)
	correct_prediction = tf.equal(y_pred_cls, y_true_cls)
	accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

	saver = tf.train.Saver()

	return data, x, x_image, y_true, y_true_cls, layer_conv1, layer_conv2, weights_conv1, weights_conv2, layer_flat, \
		   num_features, layer_fc1, layer_fc1, layer_fc2, y_pred, y_pred_cls, cost, optimizer, correct_prediction, \
		   accuracy, saver, x2, x2_image

'''
	you need to create the data object
	Load the data with the load_data function
	and then use the init to re-structure the data correctly.
'''

# initiates some variables

def next_batch(self, batch_size, shuffle=True):
		"""Return the next `batch_size` examples from this data set."""
		start = self._index_in_epoch
		# Shuffle for the first epoch
		if self._epochs_completed == 0 and start == 0 and shuffle:
			perm0 = np.arange(self._num_examples)
			np.random.shuffle(perm0)
			self._images = self.images[perm0]
			self._labels = self.labels[perm0]
		# Go to the next epoch
		if start + batch_size > self._num_examples:
			# Finished epoch
			self._epochs_completed += 1
			# Get the rest examples in this epoch
			rest_num_examples = self._num_examples - start
			images_rest_part = self._images[start:self._num_examples]
			labels_rest_part = self._labels[start:self._num_examples]
			# Shuffle the data
			if shuffle:
				perm = np.arange(self._num_examples)
				np.random.shuffle(perm)
				self._images = self.images[perm]
				self._labels = self.labels[perm]
			# Start next epoch
			start = 0
			self._index_in_epoch = batch_size - rest_num_examples
			end = self._index_in_epoch
			images_new_part = self._images[start:end]
			labels_new_part = self._labels[start:end]
			return1 = np.concatenate((images_rest_part, images_new_part), axis=0)
			return2 = np.concatenate((labels_rest_part, labels_new_part), axis=0)
			return return1, return2
		else:
			self._index_in_epoch += batch_size
			end = self._index_in_epoch
			return self._images[start:end], self._labels[start:end]

def load_data(data_directory, file_name_identifier, img_size_flat, file_format="png"):
	# data_directory is the directoy where the data is located. if you are loading from the ./training_data/ folder then this should be /training_data
	# file_name_identifier is a unique identifier that should be present in only one of the classes filenames
	# img_size_flat is the product of image height timed by image width. E.g in a 100x100 picture it would be 100 * 100 = 10 000
	# NOTE: this only works for images which are a square with sides ABCD where A=B=C=D. E.g. 4 equal sides

	# load all files in path
	files = glob.glob(os.path.join(data_directory, "*.{}".format(file_format)))

	# init labels and images
	labels = []
	images = []

	for f in files:
		# read the image as a ndarray
		image = cv2.imread(f, 0)
		image = np.asarray(image, dtype="float32")
		# image = image.flatten()
		# add current image to image list
		images.append(image)
		# print("images = {}".format(type(images)))
		# convert filename to 0 or 1 based on if it contains kw or not

		label = 0
		if f.find(file_name_identifier) == -1:
			label = 1
		# add label to labels list
		labels.append(label)

	# shuffle both lists in the same order eg. x = [1, 2, 3], y = [1, 2, 3] ----> x = [3, 1, 2], y = [3, 1, 2]
	images, labels = shuffle(images, labels, random_state=0)
	# converts the images and labels to np_arrays for use with the tensorflow functions
	images = np.asarray(images)
	labels = np.asarray(labels)

	# reshapes the images to be of the correct shape
	images = images.reshape(-1, img_size_flat)
	return images, labels

def one_hot_encode(labels):
	# creates an array for the labels
	one_hot_labels = []
	for label in labels:
		if label == 0:
			one_hot_labels.append([0, 1])  # appends the labels array with a one hot coded label for 0
		else:
			one_hot_labels.append([1, 0])  # appends the labels array with a one hot coded label for 0
	one_hot_labels = np.asarray(one_hot_labels)  # converts the array to np_array
	return one_hot_labels

def graph():
	# Now load the model from file. The way TensorFlow
	# does this is confusing and requires several steps.

	# Create a new TensorFlow computational graph.
	graph = tf.get_default_graph()

	global x
	global y_true
	global session
	global optimizer
	global accuracy
	global graph

	session = tf.Session()
	session.run(tf.global_variables_initializer())

	data, x, x_image, y_true, y_true_cls, layer_conv1, layer_conv2, weights_conv1, weights_conv2, layer_flat, \
	num_features, layer_fc1, layer_fc1, layer_fc2, y_pred, y_pred_cls, cost, optimizer, correct_prediction, \
	accuracy, saver, x2, x2_image = initiate()

	load_dir = 'resized/load/meta'
	load_dir2 = 'resized/load/checkpoints'
	load_path_meta = os.path.join(load_dir, 'best_validation.meta')
	load_path = os.path.join(load_dir, 'best_validation')
	load_path2 = os.path.join(load_dir2, 'best_validation')

	new_saver = tf.train.import_meta_graph(load_path_meta)
	saver.restore(sess=session, save_path=load_path2)

	w1 = graph.get_tensor_by_name("x:0")
	w2 = graph.get_tensor_by_name("x:0")
	w3 = graph.get_tensor_by_name("x:0")
	w5 = graph.get_tensor_by_name("x:0")
	w4 = graph.get_tensor_by_name("y_true:0")

	w1 = tf.identity(w1, name="style")
	w2 = tf.identity(w2, name="content")
	w3 = tf.identity(w3, name="test")
	w5 = tf.identity(w5, name="test2")

	print("Session at {} has been restored successfully".format(load_path))

	arr = [w1, w2, w3, w4, w5]

	input = w3

	return graph, session, arr, input

def init():
	style_data.set.graph, style_data.set._session, style_data.set.layer_tensors,  style_data.set.input = graph()
	return style_data.set

class style_data:

	class set:
		tensor_name_input_image = "content:0"
		tensor_name_input_image2 = "test2:0"

		layer_names = ['content:0', 'style:0', 'test:0', 'y_true:0', 'test2:0']

		layer_tensors = []

		# Names of the tensors for the dropout random-values.. not sure if this works
		tensor_name_dropout = 'dropout/random_uniform:0'
		tensor_name_dropout1 = 'dropout_1/random_uniform:0'

		def tostring(self):
			return "labels = {}, images = {}, cls = {}".format(len(self._labels), len(self._images), len(self.cls))

		def tostring_long(self):
			return "labels = {}, images = {}, cls = {}".format(self._labels, self._images, self.cls)

		def images(self):
			return self._images

		def labels(self):
			return self._labels

		def num_examples(self):
			return self._num_examples

		def epochs_completed(self):
			return self._epochs_completed

		def init(self):
			self._num_examples = len(self.images)
			self.labels = one_hot_encode(self.labels)
			self._images = self.images
			self._labels = self.labels
			return self

		def get_layer_names(self, layer_ids):
			return [self.layer_names[idx] for idx in layer_ids]

		def create_feed_dict(self, image, id):
			"""
			Create and return a feed-dict with an image.
			:param image:
				The input image is a 3-dim array which is already decoded.
				The pixels MUST be values between 0 and 255 (float or int).
			:return:
				Dict for feeding to the graph in TensorFlow.
			"""
			# Create feed-dict for inputting data to TensorFlow.
			feed_dict = {self.layer_names[id[0]]: image}

			print("#################### create_feed_dict() ####################")
			print("self.layer_names = {}".format(self.layer_names))
			print("image.shape = {}".format(image.shape))
			print("id = {}".format(id))
			print("feed_dict = {}".format(feed_dict))
			print("###############################################################")

			return feed_dict

		def create_feed_dict2(self, image):
			"""
			Create and return a feed-dict with an image.
			:param image:
				The input image is a 3-dim array which is already decoded.
				The pixels MUST be values between 0 and 255 (float or int).
			:return:
				Dict for feeding to the graph in TensorFlow.
			"""

			# Create feed-dict for inputting data to TensorFlow.
			feed_dict = {self.tensor_name_input_image: image}

			return feed_dict

		def create_feed_dict3(self, image):
			"""
			Create and return a feed-dict with an image.
			:param image:
				The input image is a 3-dim array which is already decoded.
				The pixels MUST be values between 0 and 255 (float or int).
			:return:
				Dict for feeding to the graph in TensorFlow.
			"""

			# Create feed-dict for inputting data to TensorFlow.
			feed_dict = {self.tensor_name_input_image2: image}

			return feed_dict

		def get_layer_tensors(self, layer_ids):
			"""
			Return a list of references to the tensors for the layers with the given id's.
			"""

			print("layer 0 = {}".format(self.layer_tensors[0]))
			print("layer 1 = {}".format(self.layer_tensors[1]))

			if layer_ids == [0]:
				test = [self.layer_tensors[1]]
			else:
				test = [self.layer_tensors[0]]

			# test = [self.layer_tensors[idx] for idx in layer_ids]

			return test

		def get_tensor_by_name(self, name):
			"""
			Return a list of references to the tensors for the layers with the given id's.
			"""
			tensor = graph.get_tensor_by_name(name)
			return tensor

		_index_in_epoch = 0
		_epochs_completed = 0
		_num_examples = 0
		_labels = np.array([])
		_images = np.array([])
		cls = []

	def tostring(self):
		return "[\n\ttrain = [{}], \n\ttest = [{}], \n\tvalidation = [{}]\n]".format(self.train.tostring(),
																					 self.test.tostring(),
																					 self.validation.tostring())

	def tostring_long(self):
		return "[\n\ttrain = [{}], \n\ttest = [{}], \n\tvalidation = [{}]\n]".format(self.train.tostring_long(),
																					 self.test.tostring_long(),
																					 self.validation.tostring_long())

	_file_names = ''
	train = set()
	test = set()
	validation = set()


import pathlib
import sys

import numpy as np

_parentdir = pathlib.Path("../../mmdetection/").parent.parent.resolve()
sys.path.insert(0, str(_parentdir))
# trunk-ignore(flake8/E402)
from mmdetection.mmdet.apis import inference_detector, init_detector

sys.path.remove(str(_parentdir))

class Model(object):
    """
    Represents a object detection model from mmdetection
    """

    def __init__(self, params: dict) -> None:

        self.model = init_detector(
            params["config"], params["check_pnt"], device="cuda:0"
        )
        self.classes = self.model.CLASSES

        print("Available classes:")
        for i, j in enumerate(self.classes):
            print(i, "-", j)

    def predict(self, img):
        """Detects objects in a given image"""
        result = inference_detector(self.model, img)

        boxes, confidences, labels = self.prepare_result(result)

        return zip(boxes, confidences, labels)

    def prepare_result(self, result) -> tuple:
        """Prepare the predictions to be used"""
        boxes, confs, labels = [], [], []
        # for idx in range(len(result)):
        for idx in [2, 13]:
            for content in result[idx]:
                ax, ay, cx, cy, conf = content
                bx, by, dx, dy = cx, ay, ax, cy
                box = np.array([[ax, ay], [bx, by], [cx, cy], [dx, dy]])
                boxes.append(box)
                confs.append(conf)
                labels.append(idx)

        return boxes, confs, labels


#Helper functions
import os
import pandas as pd
import matplotlib.pyplot as plt
from datetime import datetime # this actually means import datetime.datetime
import seaborn as sns
import emoji

def create_chat_list(path='./data/nacho_gleb_original.txt'):
    with open(path, encoding='utf8') as f:
        chat = f.read()
        chat = chat.split('\n')[:len(chat.split('\n'))-1]
    return chat

# I should add a function that indentifies european vs american calendar dates
# Also another function that identifies 24h format vs am,pm
def clean_chat_list(chat_list):
    """Unifies messages that are split by \n incorrectly"""

    clean_chat_list = []
    clean_counter = -1

## TRY WITH REGEX: re.split(r'\d\d?/\d\d?/\d\d\s\d\d?:\d\d?\s-\s', chat_test[0])
## re.findall(r'\d\d?/\d\d?/\d\d\s\d\d?:\d\d?', chat_test[i])

    for i in chat_list:
        try:
            if (datetime.strptime(i.split(' - ')[0], '%d/%m/%y %H:%M') and \
                i.split(' - ')[1].split(':')[1]):
                    clean_chat_list.append(i)
                    clean_counter += 1
            else:
                clean_chat_list[clean_counter] = \
                clean_chat_list[clean_counter] + ' ' + i
        except:
            clean_chat_list[clean_counter] = \
            clean_chat_list[clean_counter] + ' ' + i

    return clean_chat_list

def chat_to_df(chat):
    """Creates a df with datetime index and additional time columns"""

    times = []
    user = []
    message = []

    try:
        for i in chat:
            times.append(i.split(' - ')[0])
            user.append(i.split(' - ')[1].split(':',1)[0])
            message.append(i.split(' - ')[1].split(':',1)[1])
    except:
        pass

    assert len(times) == len(user) == len(message)

    #times = pd.to_datetime(times)
    times = pd.to_datetime(times)

    dataframe_chat = {
        'id': range(len(times)),
        'date': times,
        'user': user,
        'message': message
    }

    df = pd.DataFrame(dataframe_chat).set_index('date')

    df['year'] = df.index.year
    df['month'] = df.index.month
    df['week'] = df.index.week
    df['day'] = df.index.day
    df['dayweek'] = df.index.dayofweek
    df['hour'] = df.index.hour
    df['minute'] = df.index.minute
    df['emoji_count'] = df.loc[:,'message'].apply(lambda x: emoji_counter(x))
    df['media'] = df.message.apply(lambda x: '<Multimedia omitido>' in x or \
                                   '<Media omitted>' in x).astype(int)
    df['words_count'] = df.message.apply(lambda x: len(x.split(' ')))

    return df

def extract_emojis(s):
    """Extracts emojis from a string"""
    return ''.join(c for c in s if c in emoji.UNICODE_EMOJI)

def emoji_counter(msg):
    if len(emoji.emoji_lis(msg)) != 0:
        return len(extract_emojis(msg))
    else:
        return 0

"""
Code to finish, get the most used emojis:

def emoji_taker(msg):
    if len(emoji.emoji_lis(msg)) != 0:
        return extract_emojis(msg)
    else:
        return 0

def emoji_counter(msg):
    if len(emoji.emoji_lis(msg)) != 0:
        return len(extract_emojis(msg))
    else:
        return 0

df['emoji_count'] = df.loc[:,'message'].apply(lambda x: emoji_counter(x))
df['emoji'] = df.loc[:,'message'].apply(lambda x: emoji_taker(x))

df[df.emoji_count != 0].loc[:, ['emoji']]
"""

def longest_word(msg):

    word = ''

    for i in msg:
        for j in i.split(' '):
            try:
                if len(j) > len(word) and j.isalpha():
                    word = j
            except:
                continue
    return word

# Creating Statistics for first page

def number_msgs(df):
    """ Gives table with the information of the total number of messages and words by user"""

    # Counting total messages

    df1 = pd.DataFrame(
        df.groupby('user').count().iloc[:,0:1],
    )

    total_messages = df1.iloc[:,0].sum()

    df1['% Total Messages'] = round(df1.iloc[:,0]/total_messages*100, 2)

    df1.columns = ['Total Messages', '% Total Messages']

    # Counting total words

    df2 = pd.DataFrame(df.groupby('user').words_count.sum())

    total_words = df2.sum()[0]

    df2['% Total words'] = round(df2.iloc[:,0]/total_words*100, 2)

    df2.columns = ['Total Words', '% Total words']

    return pd.concat([df1, df2], axis=1)

def longest_word_user(df):

    users = df.user.unique()

    df = pd.DataFrame(
     {user : longest_word(df[df.user == user].message) for user in users}.values(),
     df.groupby('user').size().index
    )

    df.columns = ['Longest word']

    return df

def most_words(df):

    users = df.user.unique()

    most_words = {
        user : str(df[df.user == user].resample('d').sum().sort_values('words_count').words_count.\
        iloc[-1]) + ' (' + str(df[df.user == user].resample('d').sum().\
        sort_values('words_count').words_count.index[-1])[:10] + ')' for user in users
    }

    most_messages = {
        user : str(df[df.user == user].resample('d').count().sort_values('message').message.\
        iloc[-1]) + ' (' + str(df[df.user == user].resample('d').count().\
        sort_values('message').index[-1])[:10] + ')' for user in users
    }

    #Creating the dataframes before concatenating
    df1 = pd.DataFrame(most_words.values(), index=users)
    df1.columns = ['Most words']
    df2 = pd.DataFrame(most_messages.values(), index=users)
    df2.columns = ['Most messages']

    df = pd.concat([df1,df2], axis=1)

    return df

def emojis_used(df):
    users = df.user.unique()

    emojis_user = {
         user: df[df.user == user].sum().emoji_count for user in users
    }

    df = pd.DataFrame(emojis_user.values(), index=users)
    df.columns = ['Total emojis used']

    return df

def statistics_users(df):

    return pd.concat(
                        [number_msgs(df),
                         longest_word_user(df),
                         most_words(df),
                         emojis_used(df)],
                         axis=1).transpose()


# -*- coding: utf-8 -*
from math import degrees, acos
import numpy as np
from matplotlib import pyplot as plt

from vector_class import vector

INFINITE_VALUE = 10000.0

def unit_vector(v):
    """ Returns the unit vector of the vector.  """
    return v / np.linalg.norm(v)

def radian_between_vectors(v1, v2):
    """ Returns the angle in radians between vectors 'v1' and 'v2'::

            > angle_between((1, 0, 0), (0, 1, 0))
            1.5707963267948966
            > angle_between((1, 0, 0), (1, 0, 0))
            0.0
            > angle_between((1, 0, 0), (-1, 0, 0))
            3.141592653589793
    """
    v1_u = unit_vector(v1)
    v2_u = unit_vector(v2)
    return np.arccos(np.clip(np.dot(v1_u, v2_u), -1.0, 1.0))

def degree_between_vectors(ref_vector, target_vector, tangent_vector=None):
    """
    두 벡터간 각도를 구함
    tangent_vector 가 있으면 방향을 고려함
    0~360을 리턴
    """
    dv1, dv2 = ref_vector / ref_vector.length(), target_vector / target_vector.length()
    angle = degrees(acos(dv1.dot(dv2)))

    if tangent_vector and tangent_vector.dot(dv1.cross(dv2)) < 0:
        angle = 360 - angle

    return angle

def intersection_point_of_plane_and_line(point_in_plane, normal_vector_of_plane, point_in_line, vector_of_line):
    """
    point_in_plane    : 평면의  임의의  점
    normal_vector_of_plane    : 평면의 법선벡터
    point_in_line     : 직선위의 임의의 점
    vector_of_line     : 직선의 벡터
    """

    t = (point_in_plane - point_in_line).dot(normal_vector_of_plane) / normal_vector_of_plane.dot(vector_of_line)

    return point_in_line if t == 0 else point_in_line + vector_of_line * t

def intersection_point_of_plane_and_curve(point, normal_vector, curve):
    """
    get intersection point of curve and plane defined by point point and
      normal_vector normal_vector (direction of normal of the plane)

    NOTE return None if there does not exist that point
    """
    u, inc, EPSILON = 0.0, 0.01, 0.00000001
    sign = normal_vector.dot(point - curve.get_pos(0)) > 0
    p_prev, u_prev = None, None
    while 0.0 <= u <= 1.0:
        u += inc
        p1 = curve.get_pos(u)
        if sign != (normal_vector.dot(point - p1) > 0):
            if inc <= EPSILON:
                return (vector(p1) + p_prev) / 2, (u_prev + u) / 2
            sign, inc = not sign, inc * -0.1
        p_prev, u_prev = p1, u
    return None, None

def is_line_inside_outline(p1, p2, outline):
    """
    두 점이 하나의 폐곡선 안에 속해 있는지 체크함
    동일한 근관을 #
    """

    cross_count = 0
    prev_point = start_point = outline.pop()

    while outline:
        cur_point = outline.pop()
        if is_two_line_segments_intersect_in_XY_plane(prev_point, cur_point, p1, p2):
            cross_count += 1
        prev_point = cur_point

    if is_two_line_segments_intersect_in_XY_plane(prev_point, start_point, p1, p2):
        cross_count += 1

    return True if cross_count % 2 == 0 else False

def is_two_line_segments_intersect_in_XY_plane(AP1, AP2, BP1, BP2):
    """
    두선분이 교차하는지 체크함
    x,y축만으로 계산, z축 좌표는 무시
    폐곡선안에 특정 점이 포함되었는지 판단하기 위해 사용함
    """

    under = (BP2[1] - BP1[1]) * (AP2[0] - AP1[0]) - (BP2[0] - BP1[0]) * (AP2[1] - AP1[1])
    if under == 0: return False

    _t = (BP2[0] - BP1[0]) * (AP1[1] - BP1[1]) - (BP2[1] - BP1[1]) * (AP1[0] - BP1[0])
    _s = (AP2[0] - AP1[0]) * (AP1[1] - BP1[1]) - (AP2[1] - AP1[1]) * (AP1[0] - BP1[0])

    t, s = _t / under, _s / under

    if t < 0.0 or t > 1.0 or s < 0.0 or s > 1.0: return False
    if _t == 0 and _s == 0: return False

    # IP->x = AP1[0] + t * (double)(AP2[0]-AP1[0]);
    # IP->y = AP1[1] + t * (double)(AP2[1]-AP1[1]);
    return True

def mindist_btn_contours(contour1, contour2):
    """
        두 윤곽선(contour)간 최단 거리 구함
        예) 치료전 근관, 치근표면간 최소거리
    """
    from scipy.spatial import distance
    ret = distance.cdist(contour1, contour2, metric='euclidean')
    min_index = np.where(ret == ret.min())

    return ret.min(), contour1[int(min_index[0])], contour2[int(min_index[1])]

def mindist_btn_contours_old(contour1, contour2):
    """
        두 윤곽선(contour)간 최단 거리 구함
        예) 치료전 근관, 치근표면간 최소거리
    """
    assert (len(contour1) > 0 and len(contour2) > 0)
    min_dist = INFINITE_VALUE
    min_p1 = min_p2 = None
    for p1 in contour1:
        cur_min_dist, p2 = mindist_btn_contour_and_point(contour2, p1)
        if cur_min_dist < min_dist:
            min_dist, min_p1, min_p2 = cur_min_dist, p1, p2

    return min_dist, min_p1, min_p2

def mindist_btn_contour_and_point(contour, point):
    """
    윤곽선(contour)과 점의 최단거리를 구함
    Get min distance and point
    exception handling , no intersection point
    """

    min_dist = INFINITE_VALUE
    min_point = None
    if len(contour) == 0:
        return None, None
    for vtx in contour:
        if (vector(point) - vector(vtx)).length() < min_dist:
            min_dist, min_point = (vector(point) - vector(vtx)).length(), vtx

    return min_dist, min_point

def curve_to_points(nerve_path, n=100):
    '''
    get list of (n + 1) points along nerve path corresponding to u from 0 to 1
    '''
    return [nerve_path.get_pos(i / n) for i in range(0, n + 1)]

def closest_distance_btn_lines(line1, line2, clampAll=True,
                               clampA0=False, clampA1=False, clampB0=False, clampB1=False):
    '''
    https://stackoverflow.com/questions/2824478/shortest-distance-between-two-line-segments
    Given two lines defined by numpy.array pairs (a0,a1,b0,b1)
    Return the closest points on each segment and their distance
    '''

    a0, a1 = line1
    b0, b1 = line2

    # If clampAll=True, set all clamps to True
    if clampAll:
        clampA0 = True
        clampA1 = True
        clampB0 = True
        clampB1 = True

    # Calculate denomitator
    A = a1 - a0
    B = b1 - b0
    magA = np.linalg.norm(A)
    magB = np.linalg.norm(B)

    _A = A / magA
    _B = B / magB

    cross = np.cross(_A, _B);
    denom = np.linalg.norm(cross) ** 2

    # If lines are parallel (denom=0) test if lines overlap.
    # If they don't overlap then there is a closest point solution.
    # If they do overlap, there are infinite closest positions, but there is a closest distance
    if not denom:
        d0 = np.dot(_A, (b0 - a0))

        # Overlap only possible with clamping
        if clampA0 or clampA1 or clampB0 or clampB1:
            d1 = np.dot(_A, (b1 - a0))

            # Is segment B before A?
            if d0 <= 0 >= d1:
                if clampA0 and clampB1:
                    if np.absolute(d0) < np.absolute(d1):
                        return a0, b0, np.linalg.norm(a0 - b0)
                    return a0, b1, np.linalg.norm(a0 - b1)

            # Is segment B after A?
            elif d0 >= magA <= d1:
                if clampA1 and clampB0:
                    if np.absolute(d0) < np.absolute(d1):
                        return a1, b0, np.linalg.norm(a1 - b0)
                    return a1, b1, np.linalg.norm(a1 - b1)

        # Segments overlap, return distance between parallel segments
        return None, None, np.linalg.norm(((d0 * _A) + a0) - b0)

    # Lines criss-cross: Calculate the projected closest points
    t = (b0 - a0);
    detA = np.linalg.det([t, _B, cross])
    detB = np.linalg.det([t, _A, cross])

    t0 = detA / denom;
    t1 = detB / denom;

    pA = a0 + (_A * t0)  # Projected closest point on segment A
    pB = b0 + (_B * t1)  # Projected closest point on segment B

    # Clamp projections
    if clampA0 or clampA1 or clampB0 or clampB1:
        if clampA0 and t0 < 0:
            pA = a0
        elif clampA1 and t0 > magA:
            pA = a1

        if clampB0 and t1 < 0:
            pB = b0
        elif clampB1 and t1 > magB:
            pB = b1

        # Clamp projection A
        if (clampA0 and t0 < 0) or (clampA1 and t0 > magA):
            dot = np.dot(_B, (pA - b0))
            if clampB0 and dot < 0:
                dot = 0
            elif clampB1 and dot > magB:
                dot = magB
            pB = b0 + (_B * dot)

        # Clamp projection B
        if (clampB0 and t1 < 0) or (clampB1 and t1 > magB):
            dot = np.dot(_A, (pB - a0))
            if clampA0 and dot < 0:
                dot = 0
            elif clampA1 and dot > magA:
                dot = magA
            pA = a0 + (_A * dot)

    return [np.linalg.norm(pA - pB), pA, pB]

def axisEqual3D(ax):
    extents = np.array([getattr(ax, 'get_{}lim'.format(dim))() for dim in 'xyz'])
    sz = extents[:,1] - extents[:,0]
    centers = np.mean(extents, axis=1)
    maxsize = max(abs(sz))
    r = maxsize/2
    for ctr, dim in zip(centers, 'xyz'):
        getattr(ax, 'set_{}lim'.format(dim))(ctr - r, ctr + r)

def fitted_plane_of_points(points, ref_vector):
    """
    points를 지나는 평면을 구함, ref_vector와 법선벡터의 방향을 맞춤

    :param t_points: np.array
    :param ref_vector: 방향
    :return: 평면의 normal vector, 평면위의 한점
    """
    chart = False

    t_points = points.T

    xs = t_points[0].tolist()
    ys = t_points[1].tolist()
    zs = t_points[2].tolist()

    # do fit
    tmp_A, tmp_b = [], []
    for i in range(len(xs)):
        tmp_A.append([xs[i], ys[i], 1])
        tmp_b.append(zs[i])
    b = np.mat(tmp_b).T
    A = np.mat(tmp_A)

    # Manual solution
    fit = (A.T * A).I * A.T * b
    errors = b - A * fit
    residual = np.linalg.norm(errors)

    a, b, c = fit[0, 0], fit[1, 0], fit[2, 0]

    # a*x + b*y + c = z
    # (-a/c) * x + (-b/c) * y + 1/c * z = 1
    # ==> normal vector (-a/c, -b/c, 1/c)

    normal_vector = np.array([-a/c, -b/c, 1/c])

    # ref_vector와 방향이 반대면 normal vector의 방향을 바꿈
    normal_vector = normal_vector * -1 if degree_between_vectors(vector(normal_vector), ref_vector) > 90 else normal_vector

    # points들의 X, Y, Z 축의 각 중간점
    median_coord = np.median(points, axis=0)
    a_point_on_plane = np.array([median_coord[0], median_coord[1],
                                 a * median_coord[0] + b * median_coord[1] + c])

    if chart:
        degrees = [f'{degree_between_vectors(vector(normal_vector.tolist()), vector(p) - vector(a_point_on_plane)):.2f}' for p in points]
        print(f'solution: {a} x + {b} y + {c} = z')
        # print(f'solution: {normal_vector[0]} x + {normal_vector[1]} y + {normal_vector[2]} z = 1')
        # print("errors: \n", errors)
        print("residual:", residual)
        print(f' angles -- {degrees}')

        plt.figure()
        ax = plt.subplot(111, projection='3d')
        ax.scatter(xs, ys, zs, color='b')
        # normal vector
        ax.plot(*zip(a_point_on_plane, a_point_on_plane + normal_vector * 10), color='r')

        # plot plane
        xlim = ax.get_xlim()
        ylim = ax.get_ylim()
        X,Y = np.meshgrid(np.arange(xlim[0], xlim[1]),
                          np.arange(ylim[0], ylim[1]))
        Z = np.zeros(X.shape)
        for r in range(X.shape[0]):
            for c in range(X.shape[1]):
                Z[r, c] = fit[0] * X[r, c] + fit[1] * Y[r, c] + fit[2]
        ax.plot_wireframe(X,Y,Z, color='k')
        ax.set_xlabel('x')
        ax.set_ylabel('y')
        ax.set_zlabel('z')
        axisEqual3D(ax)
        plt.show()

    return normal_vector, a_point_on_plane


import time
from picraftzero.log import logger
from pprint import pformat
import subprocess
import threading

from picraftzero.config import get_config

# see: https://pymotw.com/2/threading/

class RemoteCommands:

    DEFAULT_COMMAND_TIMEOUT_SECONDS = 30

    def __init__(self):
        self.user = 'pi'
        self.timeout = RemoteCommands.DEFAULT_COMMAND_TIMEOUT_SECONDS

    def run_remote_command(self, host, command, result):
        result[host]['COMMAND'] = command
        logger.debug("run_remote_command: {}".format([self.user, host, command]))
        prog = subprocess.Popen(["/usr/bin/ssh", "{}@{}".format(self.user, host), command], stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False)
        out = prog.communicate()
        result[host]['STATUS'] = 'COMPLETED'

        result[host]['RC'] = prog.returncode
        result[host]['STDOUT'] = out[0]
        result[host]['STDERR'] = out[1]

        #logger.error("stderr; {}".format(errdata))

    def run_remote_commands(self, hosts, command):
        results = {}
        threads = []

        for host in hosts:
            results[host] = {}
            results[host]['STATUS'] = 'STARTING'

            logger.debug("Host: {} Cmd: {}".format(host, command))
            t = threading.Thread(target=self.run_remote_command, args=(host, command, results), name=host)
            threads.append(t)
            t.start()

        for t in threads:
            logger.info('Waiting for %s', t.getName())
            t.join(self.timeout)
            logger.info('Final status for {} = {}'.format(t.getName(), t.isAlive()))

        logger.info("Results: {}".format(pformat(results)))
        for host in hosts:
            if host in results:
                if results[host]['STATUS'] != 'COMPLETED':
                    results[host]['STATUS'] = 'TIMEOUT'

                elif results[host]['RC'] == 0:
                    results[host]['STATUS'] = "OK"
                else:
                    results[host]['STATUS'] = "ERROR"
            else:
                logger.error("No results found for {}".format(host))

        return results

    def start_service(self, hosts, service):
        self.run_remote_commands(hosts, "sudo systemctl start {}".format(service))

    def restart_service(self, hosts, service):
        self.run_remote_commands(hosts, "sudo systemctl restart {}".format(service))

    def stop_service(self, hosts, service):
        self.run_remote_commands(hosts, "sudo systemctl stop {}".format(service))

    def disable_service(self, hosts, service):
        self.run_remote_commands(hosts, "sudo systemctl disable {}".format(service))

    def service_status(self, hosts, service):
        self.run_remote_commands(hosts, "sudo systemctl status {}".format(service))

    def reboot(self, hosts):
        self.run_remote_commands(hosts, "sudo reboot")

    def poweroff(self, hosts):
        self.run_remote_commands(hosts, "sudo poweroff")

    def _run_test(self, hosts, cmd):
        results = self.run_remote_commands(hosts, cmd)
        logger.info(pformat(results))

if __name__ == "TEST__main__":

    cmd = RemoteCommands()
    cmd._run_test(['cam0.local'], "sleep {}".format(cmd.timeout+10))
    cmd._run_test(['cam0.local'], "no_such_command")
    cmd._run_test(['no_such_host'], "date")
    cmd._run_test(['cam0.local'], "date")

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

class PiCraftServices:

    def __init__(self):
        self.remote_cmds = RemoteCommands()
        self.config = get_config()
        self.camera_services = self.config['services_topology']['services']['camera']
        self.www_services = self.config['services_topology']['services']['www']
        self.topology = self.config['services_topology']['hosts_services_mapping']

    def all_hosts(self):
        return list(self.topology.keys())

    def all_services(self):
        all_services = []
        for host, services in self.topology.items():
            all_services += services
        return set(all_services)

    def hosts_for_service(self, service):
        hosts = []
        for host, services in self.topology.items():
            if service in services:
                hosts.append(host)
        logger.info("Service {} is installed on : {}".format(service, hosts))
        return hosts

    def camera_hosts(self):
        hosts = []
        for host, services in self.topology.items():
            #print(host, services)
            if set(self.camera_services).intersection(set(services)):
                hosts.append(host)
        return hosts

    def www_hosts(self):
        hosts = []
        for host, services in self.topology.items():
            if set(self.www_services).intersection(set(services)):
                hosts.append(host)
        return hosts

    # ---

    def service_status(self):
        for service in self.all_services():
            hosts = self.hosts_for_service(service)
            logger.info("Getting status for service {} on hosts: {}".format(service, hosts))
            self.remote_cmds.service_status(hosts, service)

    def www_services_status(self):
        for service in self.www_services:
            hosts = self.hosts_for_service(service)
            logger.info("Getting status for service {} on hosts: {}".format(service, hosts))
            self.remote_cmds.service_status(hosts, service)

    def camera_services_status(self):
        for service in self.camera_services:
            hosts = self.hosts_for_service(service)
            logger.info("Getting status for service {} on hosts: {}".format(service, hosts))
            self.remote_cmds.service_status(hosts, service)

    def restart_camera_services(self):
        for service in self.camera_services:
            self.remote_cmds.restart_service(self.camera_hosts(), service)

    def restart_www_services(self):
        for service in self.www_services:
            self.remote_cmds.restart_service(self.www_hosts(), service)

    def stop_www_services(self):
        for service in self.www_services:
            self.remote_cmds.stop_service(self.www_hosts(), service)

    def reboot_all(self):
        self.remote_cmds.reboot(self.all_hosts())

    def poweroff_all(self):
        self.remote_cmds.poweroff(self.all_hosts())
        #TODO: expected t fail!
""" 'cam2.local': {'COMMAND': 'sudo poweroff',
                'RC': 255,
                'STATUS': 'COMPLETED',
                'STDERR': 'Connection to cam2.local closed by remote host.\r\n',
                'STDOUT': ''}}"""

if __name__ == "__main__":
    # see: https://mkaz.tech/code/python-argparse-cookbook/
    import argparse

    pcs = PiCraftServices()

    logger.info("All hosts                 : {}".format(pcs.all_hosts()))
    logger.info("All services              : {}".format(pcs.all_services()))
    logger.info("Hosts with camera services: {}".format(pcs.camera_hosts()))
    logger.info("Hosts with www services   : {}".format(pcs.www_hosts()))

    commands = dict(
        service_status=pcs.service_status,
        www_service_restart=pcs.restart_www_services,
        www_service_status=pcs.www_services_status,
        www_service_stop=pcs.stop_www_services,
        camera_service_restart=pcs.restart_camera_services,
        camera_service_status=pcs.camera_services_status,
        reboot_all=pcs.reboot_all,
        poweroff_all=pcs.poweroff_all,
    )

    parser = argparse.ArgumentParser(description='Run admin scripts')

    parser.add_argument('-v', '--verbose', action="store_true", help="verbose output")
    parser.add_argument('-d', '--dryrun', action="store_true", help="dry run, don't execute remote commands")
    parser.add_argument('-l', '--logfile', type=argparse.FileType('w'), help="logfile to be created")
    parser.add_argument('-c', '--command', choices=list(commands.keys()), help="command")

    args = parser.parse_args()

    if args.command:
        commands[args.command]()


import sys
import random
from PyQt5.QtWidgets import (QWidget, QToolTip,QPushButton,QLabel, QApplication,QLCDNumber,QTextEdit, QSlider, QVBoxLayout,QMainWindow,QCheckBox,QFrame,QProgressBar,QCalendarWidget,QAction, qApp)
from PyQt5.QtGui import (QIcon,QFont,QColor,QPixmap)
from PyQt5.QtCore import Qt
from PyQt5.QtCore import pyqtSignal, QObject,QBasicTimer,QDate,QMetaObject,QSize,QRect,QTimer

class Window(QMainWindow):
    resized = pyqtSignal()
    click=pyqtSignal()
    def  __init__(self, parent=None):
        super().__init__()
        self.j=0

        self.UI()
    def UI(self):
        self.btn_mas=[]
        self.label_mas=[]
        self.image_mas=[]
        self.btn_x=0
        self.btn_y=100
        self.width_btn=150

        self.height_btn=300

        self.resized.connect(self.someFunction)
        self.centralwidget=QWidget(self)
        self.setWindowTitle('Resize')
        self.resize(1600,1600)

        self.CreateLabel()
        self.CreateImage()
        self.CreateButton()

        self.show()
    def CreateImage(self):
        mas_image=[]
        for i in range(9):
             path='{}'.format(i)+'.jpg'
             print(path)
             pixmap1=QPixmap(path)
             pixmap1=pixmap1.scaled(QSize(150,300))
             mas_image.append(pixmap1)

        return mas_image
    def CreateLabel(self):
        mas=[]
        self.label_number=[]
        mas_image=self.CreateImage()
        print(mas_image)

        for x in range (0, 30):
             num = random.randint(0, 30)
             while num in mas:
                 num = random.randint(0, 30)
             mas.append(num)

        j=0
        for i in range(30):

            if self.btn_x>1500:
                self.btn_x=0
                self.btn_y+=302

            label=QLabel(self)
            label.setGeometry(self.btn_x,self.btn_y,self.width_btn,self.height_btn)

            if j>8:
                j=0

            label.setPixmap(mas_image[j])
            self.label_number.append(str(j))
            j+=1
            label.setVisible(True)

            self.label_mas.insert(mas[i],label)

            self.btn_x+=160

    def CreateButton(self):

        self.j+=1

        self.btn_x=0
        self.btn_y=100

        for i in range(30):

            if self.btn_x>1500:
                self.btn_x=0
                self.btn_y+=302
            self.btn=QPushButton(self)

            self.btn.setGeometry(self.btn_x,self.btn_y,self.width_btn,self.height_btn)
            pixmap=QPixmap('10.jpg')

            pixmap=pixmap.scaled(QSize(150,300))

            self.btn.setIcon(QIcon(pixmap))

            self.btn.setIconSize(QSize(150,300))

            self.btn.setVisible(True)

            self.btn_x+=160
            self.btn.clicked.connect(self.Click)

            self.btn_mas.append(self.btn)

    def Click(self):
        j=0

        sender=self.sender()
        print(sender,'sender')
        for i in self.btn_mas:
          if sender==i:

            (self.btn_mas[j].setVisible(False))
            break
          j+=1
          print(j)

        print(self.label_number[j],'mas')

    def Button(self,event):
        print(self.sender().text())
    def resizeEvent(self, event):
        self.resized.emit()
        return super(Window, self).resizeEvent(event)

    def someFunction(self):
        print(self.width())

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

Код урока последний.py

Код урока последний.py


# -*- coding: utf-8 -*-
'''
Created on 2018年7月5日

@author: xulin.huang
'''
import os

class Reader(object):
    '''导表读取器(基类)
    '''

    def __init__(self, dirPath, fileName):
        self.dirPath = dirPath # 导表文件所在目录
        self.fileName = fileName # 导表文件名
        self.fullFileName = os.path.join(dirPath, fileName) # 导表文件全路径
        self.data = {} # 导表数据，如: {1:{1:field1,2:field2,...}, 2:{1:field1,2:field2,...},}
        self.fieldNameList = {} # 字段名列表，如: {1:fieldName1,2:fieldName2,...}
        self.formatList = {} # 格式列表，如: {1:format1,2:format2,...}
        self.blankRowNoList = [] # 空行的行号列表，如: [行号1,行号5,行号7,...]

    def getFileName(self):
        return self.fileName

    def getFullFileName(self):
        return self.fullFileName

    def getFieldRowNo(self):
        '''字段名行号
                            该行内容如: id、name
        '''
        raise Exception("请在子类实现方法 getFieldRowNo")

    def getFieldNameByColNo(self, colNo):
        '''根据列号获取字段名
        '''
        return self.fieldNameList.get(colNo, None)

    def transFieldName(self, fieldName):
        '''转换成字段名
                            假如字段名附加了信息，就需要在这里过滤掉，如: id|I、text|S
        '''
        strList = fieldName.split("|", 1)
        if len(strList) == 2:
            return strList[0]
        return fieldName

    def transToFieldNameList(self, valueList):
        '''转换成字段名列表
        '''
        self.fieldNameList = {}
        for colIndex, value in enumerate(valueList):
            colNo = colIndex + 1
            self.fieldNameList[colNo] = self.transFieldName(value)

    def getFormatRowNo(self):
        '''数据格式行号
                            该行内容如: 编号|I、名称|S
        '''
        raise Exception("请在子类实现方法 getFormatRowNo")

    def getFormatByColNo(self, colNo):
        '''根据列号获取格式
        '''
        return self.formatList.get(colNo, "")

    def transFormat(self, fieldFormat):
        '''获取字段格式
                            一般情况 下，格式是附加在字段后面的，所以需要过滤出来，如: 编号|I、名称|S
        可以支持多个字段格式，如: 奖励|I|L
        '''
        strList = fieldFormat.split("|", 1)
        if len(strList) == 2:
            return strList[1]
        return ""

    def transToFormatList(self, valueList):
        '''转换成格式列表
        '''
        self.formatList = {}
        for colIndex, value in enumerate(valueList):
            colNo = colIndex + 1
            self.formatList[colNo] = self.transFormat(value)

    def getDataBeginRowNo(self):
        '''导表数据开始行号
                            该行内容如: 编号|I、名称|S
        '''
        raise Exception("请在子类实现方法 getDataBeginRowNo")

    def iterData(self):
        '''迭代导表数据
                            迭代顺序：行号升序
        '''
        rowNoList = list(self.data.keys())
        rowNoList.sort()
        for rowNo in rowNoList:
            yield rowNo, self.data[rowNo]

    def iterColData(self, colNo):
        '''根据列号迭代导表数据
        '''
        if colNo > self.getColCount():
            return

        rowNoList = list(self.data.keys())
        rowNoList.sort()
        for rowNo in rowNoList:
            fieldObj = self.data[rowNo].get(colNo)
            if fieldObj:
                yield rowNo, fieldObj

    def readData(self):
        '''读取导表数据
        '''
        raise Exception("请在子类实现方法 readData")

    def transLineData(self, rowNo, valueList):
        '''转换行数据
        '''
        if rowNo < self.getDataBeginRowNo():
            if rowNo == self.getFieldRowNo(): # 字段名行
                self.transToFieldNameList(valueList)
            if rowNo == self.getFormatRowNo(): # 格式行
                self.transToFormatList(valueList)
            return

        if len(valueList) == 0: # 空的数据行
            self.blankRowNoList.append(rowNo)
            return

        # 下面是数据行的转换
        fieldObjList = {}
        for colIndex, value in enumerate(valueList):
            colNo = colIndex + 1
            fieldName = self.getFieldNameByColNo(colNo)
            if not fieldName:
                break
            fieldFormat = self.getFormatByColNo(colNo)
            fieldObjList[colNo] = self.newField(fieldName, value, fieldFormat, rowNo, colNo)
        self.data[rowNo] = fieldObjList

    def newField(self, fieldName, fieldValue, fieldFormat, rowNo, colNo):
        '''创建字段
        '''
        fieldObj = Field(fieldName, fieldValue, fieldFormat, rowNo, colNo)
        fieldObj.fileName = self.fileName
        return fieldObj

    def getRowCount(self):
        '''获取行数
        '''
        return len(self.data)

    def getColCount(self):
        '''获取列数
        '''
        return len(self.fieldNameList)

    def getBlankRowNoList(self):
        '''空行的行号列表
        '''
        return self.blankRowNoList

    def getDuplicateIdList(self):
        '''获取重复id列表
        '''
        idList = {}
        for rowNo, fieldObj in self.iterColData(1):
            idValue = fieldObj.value
            fieldList = idList.setdefault(idValue, [])
            fieldList.append(fieldObj)

        duplicateIdList = []
        for idValue, fieldList in idList.items():
            if len(fieldList) > 1:
                duplicateIdList.append(idValue)
        return duplicateIdList

    def findSameValueField(self, colNo, value):
        '''搜寻相同值的字段
        '''
        for rowNo, fieldObj in self.iterColData(colNo):
            if fieldObj.value == value:
                return fieldObj
        return None

    def __str__(self):
        infoList = []
        infoList.append("  文件名:{}".format(self.fileName))
        infoList.append("  行数:{}".format(self.getRowCount()))
        infoList.append("  列数:{}".format(self.getColCount()))
        infoList.append("  字段名列表:{}".format(",".join(self.fieldNameList.values())))
        infoList.append("  格式列表:{}".format(",".join(self.formatList.values())))
        return "{{\n{}\n}}".format("\n".join(infoList))

class Field(object):
    '''字段
    '''

    def __init__(self, name, value, fieldFormat, rowNo, colNo):
        self.name = name # 字段名
        self.value = value # 字段值
        self.required = False # 是否必填
        self.formatStr = fieldFormat # 格式字符串
        self.formatList = [] # 字段格式列表，格式可以有多个
        if fieldFormat:
            self.setFieldFormat(fieldFormat)
        self.rowNo = rowNo # 行号
        self.colNo = colNo # 列号
        self.fileName = "" # 导表文件名

    def setFieldFormat(self, fieldFormat):
        '''设置字段格式
        '''
        self.formatStr = fieldFormat
        if fieldFormat.startswith("!"):
            self.required = True
            fieldFormat = fieldFormat[1:]
        if fieldFormat:
            self.formatList = re.findall("\w+\(.+\)|\w+", fieldFormat)

    def __str__(self):
        infoList = []
        infoList.append("字段名:{}".format(self.name))
        infoList.append("行号:{}".format(self.rowNo))
        infoList.append("列号:{}".format(self.colNo))
        infoList.append("格式:{}".format(self.formatStr))
        infoList.append("字段值:'{}\'".format(self.value))
        return "{}".format(",".join(infoList))

import re