import random

from .BaseOptimizer import BaseOptimizer, Vector, xmap

class PSO(BaseOptimizer):
  def __init__(self,
               populationSize,
               nDimensions,
               createNewIndividual,
               fitness,
               wSchedule = lambda x: 0.9,
               c1 = 2,
               c2 = 2,
               bounds = None,
               **kwargs
  ):
    super().__init__(fitness, **kwargs)
    from math import inf

    #self._populationSize = populationSize
    self._nDimensions = nDimensions
    self._createNewIndividual = createNewIndividual
    #self._fitness = lambda x: self.wrapFitness(fitness, x)
    #self._fitness = fitness

    self._w = wSchedule
    self._c1 = c1
    self._c2 = c2
    self._bounds = bounds

    self._iteration = 0

    self.particles = []

    self.best = (None, -inf)

    if not hasattr(populationSize, '__iter__'):
      populationSize = range(populationSize)

    def createAndScore(data):
      i, pos = data
      position = Vector(pos)
      velocity = Vector([0 for i in range(nDimensions)])
      score = self._fitness(position.pos)

      #self.particles.append((position, velocity, score, position, score, i))
      return (position, velocity, score, position, score, i)

    print('starting')
    self.particles = xmap(createAndScore, [(i, createNewIndividual(i)) for i in populationSize], processes=self._processes)
    print('Generated initial %d particles' % len(self.particles))

    for particle in self.particles:
      position, vel, score, bpos, bscore, i = particle

      if score > self.best[1]:
        self.best = (position, score)

    if self.best[0] is None:
      print([p[2] for p in self.particles])
      raise TypeError('No initial gradient, did everyone fail?')

  def getIndividuals(self):
    return [p[0] for p in self.particles]

  def prepare(self):
    # Find our best particle
    globalPosition, globalScore = self.best

    # Update everyone
    w = self._w(self._iteration)
    newParticles = []
    for position, velocity, score, bestPosition, bestScore, idx in self.particles:
      toBest = bestPosition - position
      toGlobal = globalPosition - position

      toBest.perturb()
      toGlobal.perturb()

      gamma = 0.1

      vInertia = velocity * w
      vCognitive = self._c1 * toBest
      vSocial = self._c2 * toGlobal

      # Get the new stats
      newVelocity = vInertia + vCognitive + vSocial
      newPosition = position + gamma * newVelocity

      # Constrain, if we have bounds
      if self._bounds is not None:
        newPosition, newVelocity = self.bound(newPosition, newVelocity)

      # Score will be filled in in a moment
      newParticles.append((newPosition, newVelocity, score, bestPosition, bestScore, idx))

    self.particles = newParticles

    #print('best is', globalScore)
    return self.getBest()

  def bound(self, pos, vel):
    """
    Modify pos to be within our (possibly repeating) bounds.
    If a violation is detected, the velocity is also set to zero
    """
    for i in range(self._nDimensions):
      bound = self._bounds[i % len(self._bounds)]
      if len(bound) != 2:
        raise TypeError('Bounds should have an upper and lower')

      lower, upper = bound

      if lower is not None and pos[i] < lower:
        pos[i] = lower
        if vel[i] < 0:
          vel[i] = 0

      if upper is not None and pos[i] > upper:
        pos[i] = upper
        if vel[i] > 0:
          vel[i] = 0

    return pos, vel

  def update(self, fitnesses):
    if len(self.particles) != len(fitnesses):
      raise TypeError('Incorrect fitness vector')

    newParticles = []
    for i in range(len(self.particles)):
      position, velocity, score, bestPosition, bestScore, idx = self.particles[i]
      newScore = fitnesses[i]

      if newScore > bestScore:
        #print('  ', position, newScore, '>', bestPosition, bestScore)
        bestScore = newScore
        bestPosition = position

      newParticles.append((position, velocity, newScore, bestPosition, bestScore, idx))

    # Store the updated particles
    self.particles = sorted(newParticles, key=lambda p: p[2])

    # Check best
    newBest = self.getBest()
    if newBest[1] > self.best[1]:
      #print('new best', self.best, newBest, self._fitness(newBest[0]))
      self.best = newBest

  def getBest(self):
    bestPos, highScore = None, 0

    for position, velocity, score, bestPosition, bestScore, idx in self.particles:
      if bestPos is None or score > highScore:
        bestPos = position
        highScore = score

    return bestPos, highScore

  def snapshot(self, o, n):
    o('PSOv2:' + str(n) + ':' + str(self.best[1]))
    o([particle[2] for particle in self.particles])
    particles = self.particles[-n:]
    for particle in particles:
      o(particle[2])
      o(particle[0].pos)

  def dump(self, o):
    o('PSOv2final:' + str(len(self.particles)) + ':' + str(self.best[1]))
    for particle in self.particles:
      # position, velocity, score, bestPosition, bestScore, idx
      # ->
      # score, position, velocity, bestPosition, bestScore
      o(particle[2])
      o(particle[0].pos)
      o(particle[1].pos)
      o(particle[3].pos)
      o(particle[4])


import json

import adsk.core
import adsk.fusion
import traceback

from .fusion_data_api_id_utils import get_fusion_data_ids_for_active_document, get_fusion_data_ids_for_component

app = adsk.core.Application.get()
ui = app.userInterface

# Print results to text command palette
def run(context):
    try:
        break_string = '************* Assembly Data *************\n'
        app.log(break_string, adsk.core.LogLevels.InfoLogLevel, adsk.core.LogTypes.ConsoleLogType)

        results = get_fusion_data_ids_for_active_document()
        output_string = json.dumps(results, indent=4)
        app.log(output_string, adsk.core.LogLevels.InfoLogLevel, adsk.core.LogTypes.ConsoleLogType)

        adsk.doEvents()

        break_string = '\n\n************* Component Data *************\n'
        app.log(break_string, adsk.core.LogLevels.InfoLogLevel, adsk.core.LogTypes.ConsoleLogType)

        selection = ui.selectEntity('Pick a Component', 'Occurrences,RootComponents')
        if selection.entity.objectType == adsk.fusion.Component.classType():
            component = adsk.fusion.Component.cast(selection.entity)
        elif selection.entity.objectType == adsk.fusion.Occurrence.classType():
            occurrence = adsk.fusion.Occurrence.cast(selection.entity)
            component = occurrence.component
        else:
            raise TypeError('Selection Type was invalid')

        results = get_fusion_data_ids_for_component(component)
        output_string = json.dumps(results, indent=4)
        app.log(output_string, adsk.core.LogLevels.InfoLogLevel, adsk.core.LogTypes.ConsoleLogType)

    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))


from datetime import datetime, timezone
from fastapi import status
from src.store.exceptions import DeleteProductItemException, UpdateUserException
from src.store.exceptions import DeleteProductItemException, UpdateUserException
from src.authorization.schemas import UpdateUserData
from src.schemas.response_items import ResponseItemsSchema
from src.store.phrases import INVALID_BUSKET_MONEY_COUNT
from src.user.phrases import *
from src.authentication.exceptions import *
from src.authorization.schemas import SubjectData
from src.database.exceptions import *
from src.schemas.message import MessageSchema
from src.services.unit_of_work import IUnitOfWork
from src.user.exceptions import *
from src.user.phrases import RESET_EMAIL_SUCCESS
from src.user.schemas import *
from src.database.models import *
from src.utils import check_count_items

class UserService:
    def __init__(self, uow: IUnitOfWork):
        self.__uow = uow

    async def reset_email(self, subject_data: SubjectData, data: ResetEmailSchema):
        async with self.__uow:
            try:
                user = await self.__uow.users.get_by_id(subject_data.id)
                if user is None:
                    raise InvalidUsernameException()
                user.email = data.new_email
                await self.__uow.users.update(user)
                await self.__uow.commit()
                return MessageSchema(message=RESET_EMAIL_SUCCESS)
            except GetItemByIdException as e:
                raise GetResetEmailException() from e
            except UpdateItemException as e:
                raise GetResetEmailException() from e
            except UniqueViolationException as e:
                raise GetResetEmailException(
                    e.message, status.HTTP_400_BAD_REQUEST
                ) from e

    async def get_by_id(self, user_id: int):
        async with self.__uow:
            try:
                user = await self.__uow.users.get_by_id(user_id)
                if user is None:
                    raise InvalidUserIdException(code=404)
                return UserGetByIdSchema.from_orm(user)
            except GetItemByIdException as e:
                raise GetUserByIdException() from e

    async def update_profile(self, subject_data: SubjectData, data: UpdateUserData):
        async with self.__uow:
            try:
                user_db = await self.__uow.users.get_by_id(subject_data)
                if user_db is None:
                    raise InvalidUserIdException(code=404)
                if data.birthdate is not None and user_db.birthdate is None:
                    age_tag = await self._get_age_tag(data.birthdate)
                    await self.__uow.customer_tag_links.add(
                        CustomerTagLink(customer_id=subject_data, tag_id=age_tag)
                    )
                user_db.birthdate = data.birthdate
                user_db.firstname = data.firstname
                user_db.lastname = data.lastname
                user_db.patronymic = data.patronymic
                user_db.img = data.image
                await self.__uow.users.update(user_db)
                await self.__uow.commit()
                return MessageSchema(message=CHANGE_USER_SUCCESS)
            except GetItemByIdException as e:
                raise GetUserByIdException() from e
            except UpdateItemException as e:
                raise UserUpdateException() from e

    async def post_customer_tag_links(
        self, subject_data: SubjectData, tags: list[int] | None
    ):
        async with self.__uow:
            try:
                user_db = await self.__uow.users.get_by_id(subject_data)
                if user_db is None:
                    raise InvalidUserIdException(code=404)
                for tag in tags:
                    await self.__uow.customer_tag_links.add(
                        CustomerTagLink(customer_id=subject_data, tag_id=tag)
                    )
                await self.__uow.commit()
                return MessageSchema(message=ADD_TAG_SUCCESS)
            except GetItemByIdException as e:
                raise GetUserByIdException(code=status.HTTP_400_BAD_REQUEST) from e
            except UniqueViolationException as e:
                raise AddCustomerTagLinkException(
                    code=status.HTTP_400_BAD_REQUEST
                ) from e
            except AddItemException as e:
                raise AddCustomerTagLinkException() from e

    async def get_friend_types(self):
        async with self.__uow:
            friend_types = await self.__uow.friend_types.get_all()
            return [FriendTypeSchema.from_orm(f_t) for f_t in friend_types]

    async def post_friend(self, user_id: int, friend: FriendPostSchema):
        async with self.__uow:
            try:
                user_db = await self.__uow.users.get_by_id(user_id)
                if user_db is None:
                    raise InvalidUserIdException(code=404)
                friend_db = Friend(
                    initator_id=user_id, friend_id=friend.friend_id, type=friend.type
                )
                friend_exist = await self.__uow.friends.get_by_id(friend_db)
                if friend_exist is not None:
                    raise InvalidFriendException(code=400)
                await self.__uow.friends.add(friend_db)
                await self.__uow.commit()
                return MessageSchema(message=ADD_FRIEND_SUCCESS)
            except GetItemByIdException as e:
                raise GetUserByIdException(code=status.HTTP_400_BAD_REQUEST) from e
            except AddItemException as e:
                raise AddFriendException() from e

    async def add_to_favourite(self, user_id: int, p_item: FavouritePostSchema):
        async with self.__uow:
            try:
                user_db = await self.__uow.users.get_by_id(user_id)
                if user_db is None:
                    raise InvalidUserIdException(code=404)
                favourite_exist = (
                    await self.__uow.favourites.get_by_user_id_product_item_id(
                        user_id, p_item.product_item_id
                    )
                )
                product_item_exist = await self.__uow.product_items.get_by_id(
                    p_item.product_item_id
                )
                if product_item_exist is None:
                    raise InvalidNoProductItemException(code=404)
                if favourite_exist is not None:
                    raise InvalidProductItemException(code=404)
                favourite_db = Favourite(
                    user_id=user_id, product_item_id=p_item.product_item_id
                )
                await self.__uow.favourites.add(favourite_db)
                await self.__uow.commit()
                return MessageSchema(message=ADD_PRODUCT_ITEM_SUCCESS)
            except GetItemByIdException as e:
                raise GetUserByIdException(code=status.HTTP_400_BAD_REQUEST) from e
            except AddItemException as e:
                raise AddProductItemException() from e

    async def add_to_basket(self, user_id: int, basket_item: BasketPostSchema):
        async with self.__uow:
            try:
                user_db = await self.__uow.users.get_by_id(user_id)
                if user_db is None:
                    raise InvalidUserIdException(code=404)
                basket_exist = await self.__uow.baskets.get_by_user_id_product_item_id(
                    user_id, basket_item.product_item_id
                )
                product_item_exist = await self.__uow.product_items.get_by_id(
                    basket_item.product_item_id
                )
                if product_item_exist is None:
                    raise InvalidNoProductItemException(code=404)
                if basket_exist is not None:
                    if basket_exist.count > 0:
                        if basket_item.count < 0:
                            if abs(basket_item.count) > basket_exist.count:
                                raise InvalidNoProductItemException(
                                    message="Недостаточно единиц продукта в корзине",
                                    code=404,
                                )
                            basket_exist.count += basket_item.count
                        else:
                            basket_exist.count += basket_item.count
                    await self.__uow.baskets.update(basket_exist)
                else:
                    basket_item_db = Basket(
                        user_id=user_id,
                        product_item_id=basket_item.product_item_id,
                        count=basket_item.count,
                    )
                    await self.__uow.baskets.add(basket_item_db)
                await self.__uow.commit()
                return MessageSchema(message=ADD_PRODUCT_ITEM_SUCCESS)
            except GetItemByIdException as e:
                raise GetUserByIdException(code=status.HTTP_400_BAD_REQUEST) from e
            except AddItemException as e:
                raise AddProductItemException() from e

    async def post_event(self, user_id: int, event: EventPostSchema):
        async with self.__uow:
            try:
                user_db = await self.__uow.users.get_by_id(user_id)
                if user_db is None:
                    raise InvalidUserIdException(code=404)
                event_db = Event(
                    description=event.description,
                    time=event.time,
                    details=event.details,
                    user_id=user_id,
                )
                await self.__uow.events.add(event_db)
                if "product_id" in event.details.keys():
                    product_item_db = await self.__uow.product_items.get_by_id(
                        event.details["product_id"]
                    )
                    if product_item_db is None:
                        raise InvalidProductItemException(
                            message=INVALID_NO_PRODUCT_ITEM, code=404
                        )
                    if user_db.cash < product_item_db.price:
                        raise InvalidUserIdException(
                            message=INVALID_BUSKET_MONEY_COUNT, code=404
                        )
                    user_db.cash -= product_item_db.price
                    owner_db_id = await self._get_owner_by_product_item_id(
                        product_item_db.id
                    )
                    owner_db = await self.__uow.users.get_by_id(owner_db_id)
                    owner_db.cash += product_item_db.price * 0.95
                    await self.__uow.users.update(owner_db)
                    await self.__uow.users.update(user_db)
                    await self._add_purshase_history(user_id, product_item_db)
                await self.__uow.commit()
                return MessageSchema(message=POST_EVENT_SUCCESS)
            except GetItemByIdException as e:
                raise GetUserByIdException(code=status.HTTP_400_BAD_REQUEST) from e
            except AddItemException as e:
                raise AddEventException() from e

    async def delete_event(self, user_id: int, event_id: int):
        async with self.__uow:
            try:
                user_db = await self.__uow.users.get_by_id(user_id)
                if user_db is None:
                    raise InvalidUserIdException(code=404)
                event_exist = await self.__uow.events.get_by_id(event_id)
                if event_exist is None:
                    raise InvalidEventException(message=EXIST_EVENT_EXCEPTION)
                if "product_id" in event_exist.details.keys():
                    if event_exist.time > datetime.now(timezone.utc):
                        product_item_db = await self.__uow.product_items.get_by_id(
                            event_exist.details["product_id"]
                        )
                        user_db.cash += product_item_db.price * 0.97
                        owner_db_id = await self._get_owner_by_product_item_id(
                            product_item_db.id
                        )
                        owner_db = await self.__uow.users.get_by_id(owner_db_id)
                        owner_db.cash -= product_item_db.price * 0.95
                        await self.__uow.users.update(owner_db)
                        await self.__uow.users.update(user_db)
                await self.__uow.events.delete(event_id)
                await self.__uow.commit()
                return MessageSchema(message=DELETE_EVENT_SUCCESS)
            except GetItemByIdException as e:
                raise GetUserByIdException(code=status.HTTP_400_BAD_REQUEST) from e
            except DeleteItemException as e:
                raise DeleteProductItemException() from e

    async def delete_from_favourite(self, item_id: int):
        async with self.__uow:
            try:
                favourite_exist = await self.__uow.favourites.get_by_id(item_id)
                if favourite_exist is None:
                    raise InvalidProductItemException(
                        message=DELETE_PRODUCT_ITEM_EXCEPTION
                    )
                await self.__uow.favourites.delete(item_id)
                await self.__uow.commit()
                return MessageSchema(message=DELETE_PRODUCT_ITEM_SUCCESS)
            except DeleteItemException as e:
                raise DeleteProductItemException() from e

    async def delete_from_basket(self, item_id: int):
        async with self.__uow:
            try:
                basket_exist = await self.__uow.baskets.get_by_id(item_id)
                if basket_exist is None:
                    raise InvalidProductItemException(
                        message=DELETE_PRODUCT_ITEM_EXCEPTION
                    )
                await self.__uow.baskets.delete(item_id)
                await self.__uow.commit()
                return MessageSchema(message=DELETE_PRODUCT_ITEM_SUCCESS)
            except DeleteItemException as e:
                raise DeleteProductItemException() from e

    async def put_money_on_cash(self, user_id: int, money: int):
        async with self.__uow:
            try:
                user_db = await self.__uow.users.get_by_id(user_id)
                if user_db is None:
                    raise InvalidUserIdException(code=404)
                user_db.cash += money
                await self.__uow.users.update(user_db)
                await self.__uow.commit()
                return MessageSchema(message="Счет успешно пополнен!")
            except GetItemByIdException as e:
                raise GetUserByIdException(code=status.HTTP_400_BAD_REQUEST) from e
            except UpdateItemException as e:
                raise UpdateUserException() from e

    async def get_friends(
        self, user_id: int, limit: int | None, offset: int | None, substr: str | None
    ) -> ResponseItemsSchema[FriendWithFriendSchema]:
        async with self.__uow:
            try:
                user_db = await self.__uow.users.get_by_id(user_id)
                if user_db is None:
                    raise InvalidUserIdException(code=404)
                friends = await self.__uow.friends.get_all(
                    user_id, limit, offset, substr
                )
                l = check_count_items(friends, FRIENDS_NOT_FOUND)
                return ResponseItemsSchema.Of(
                    [FriendWithFriendSchema.from_orm(f) for f in friends], offset, l
                )
            except GetItemByIdException as e:
                raise GetUserByIdException(code=status.HTTP_400_BAD_REQUEST) from e
            except GetAllItemsException as e:
                raise GetAllFriendsException(e.message) from e

    async def get_my_purshase_history(
        self, user_id: int, limit: int | None, offset: int | None, date: datetime | None
    ) -> ResponseItemsSchema[HistorySchema]:
        async with self.__uow:
            try:
                user_db = await self.__uow.users.get_by_id(user_id)
                if user_db is None:
                    raise InvalidUserIdException(code=404)
                history = await self.__uow.purshase_histories.get_all(
                    user_id, limit, offset, date
                )
                l = check_count_items(history, PURSHASES_NOT_FOUND)
                return ResponseItemsSchema.Of(
                    [HistorySchema.from_orm(h) for h in history], offset, l
                )
            except GetItemByIdException as e:
                raise GetUserByIdException(code=status.HTTP_400_BAD_REQUEST) from e
            except GetAllItemsException as e:
                raise GetAllFriendsException(e.message) from e

    async def get_events_all(
        self, user_id: int, limit: int | None, offset: int | None, substr: str | None
    ) -> ResponseItemsSchema[EventSchema]:
        async with self.__uow:
            try:
                user_db = await self.__uow.users.get_by_id(user_id)
                if user_db is None:
                    raise InvalidUserIdException(code=404)
                events = await self.__uow.events.get_all(user_id, limit, offset, substr)
                l = check_count_items(events, EVENTS_NOT_FOUND)
                return ResponseItemsSchema.Of(
                    [EventSchema.from_orm(e) for e in events], offset, l
                )
            except GetItemByIdException as e:
                raise GetUserByIdException(code=status.HTTP_400_BAD_REQUEST) from e
            except GetAllItemsException as e:
                raise GetAllFriendsException(e.message) from e

    async def delete_friend(self, user_id: int, friend_id: int):
        async with self.__uow:
            try:
                user_db = await self.__uow.users.get_by_id(user_id)
                if user_db is None:
                    raise InvalidUserIdException(code=404)
                friend_db = Friend(initator_id=user_id, friend_id=friend_id)
                friend_exist = await self.__uow.friends.get_by_id(friend_db)
                if friend_exist is None:
                    raise InvalidFriendNoException(code=400)
                await self.__uow.friends.delete(friend_db)
                await self.__uow.commit()
                return MessageSchema(message=FRIEND_DELETE_SUCCESS)
            except GetItemByIdException as e:
                raise GetFriendByIdException(code=status.HTTP_400_BAD_REQUEST) from e

    async def basket_by_user_id(
        self,
        user_id: int,
        limit: int | None,
        offset: int | None,
        substr: str | None,
    ) -> ResponseItemsSchema[GetBasketSchema]:
        async with self.__uow:
            try:
                user_db = await self.__uow.users.get_by_id(user_id)
                if user_db is None:
                    raise InvalidUserIdException(code=404)
                product_items = await self.__uow.baskets.get_all(
                    user_id, limit, offset, substr
                )
                l = check_count_items(product_items, BASKET_IS_EMPTY)
                return ResponseItemsSchema.Of(
                    [GetBasketSchema.from_orm(b) for b in product_items], offset, l
                )
            except GetItemByIdException as e:
                raise GetUserByIdException(code=status.HTTP_400_BAD_REQUEST) from e
            except GetAllItemsException as e:
                raise GetAllItemsException(e.message) from e

    async def favourite_by_user_id(
        self, user_id: int, limit: int | None, offset: int | None, substr: str | None
    ) -> ResponseItemsSchema[GetFavouriteSchema]:
        async with self.__uow:
            try:
                user_db = await self.__uow.users.get_by_id(user_id)
                if user_db is None:
                    raise InvalidUserIdException(code=404)
                product_items = await self.__uow.favourites.get_all(
                    user_id, limit, offset, substr
                )
                l = check_count_items(product_items, FAVOURITE_IS_EMPTY)
                return ResponseItemsSchema.Of(
                    [GetFavouriteSchema.from_orm(b) for b in product_items], offset, l
                )
            except GetItemByIdException as e:
                raise GetUserByIdException(code=status.HTTP_400_BAD_REQUEST) from e
            except GetAllItemsException as e:
                raise GetAllItemsException(e.message) from e

    async def get_recommend_by_relative(
        self,
        user_id: int,
        limit: int | None,
        offset: int | None,
        friend_type: list[str] | None,
    ) -> ResponseItemsSchema[RecommendFriendSchema]:
        async with self.__uow:
            try:
                user_db = await self.__uow.users.get_by_id(user_id)
                if user_db is None:
                    raise InvalidUserIdException(code=404)
                product_items_db = await self.__uow.friends.get_recommend_by_relative(
                    user_id, limit, offset, friend_type
                )
                return [RecommendFriendSchema.from_orm(p) for p in product_items_db]
            except GetItemByIdException as e:
                raise GetUserByIdException(code=status.HTTP_400_BAD_REQUEST) from e

    async def _calculate_age_user(self, birthdate):
        return datetime.utcnow().year - birthdate.year

    async def _get_age_tag(self, age):
        all_age_tags = await self.__uow.tags.get_all(
            None, None, [AGE_TAG_GROUP_ID], None, None, None
        )
        age_user = await self._calculate_age_user(age)
        for tag in all_age_tags:
            if (
                age_user >= tag.details["age_min"]
                and age_user <= tag.details["age_max"]
            ):
                age_tag = tag.id
                return age_tag

    async def _add_purshase_history(self, user_id: int, p_i: ProductItem):
        p_h = PurshaseHistory(
            count=1, price=p_i.price, user_id=user_id, product_item_id=p_i.id
        )
        await self.__uow.purshase_histories.add(p_h)

    async def _get_owner_by_product_item_id(self, product_item_id: int):
        owner_db = await self.__uow.product_items.get_owner_by_id(product_item_id)
        owner_id = owner_db.product.store.owner.id
        return owner_id


#!/usr/bin/env python
#coding=utf-8

import rospy
import numpy as np
from Python_API import Sendmessage
import time

send = Sendmessage()
class view_message:
    def __init__(self):
        #影像位置
        self.basket_X       =   0   #框
        self.basket_XMin    =   0
        self.basket_XMax    =   0

        self.basket_Y       =   0
        self.basket_YMin    =   0
        self.basket_YMax    =   0

        self.ball_X         =   0   #球
        self.ball_XMin      =   0
        self.ball_XMax      =   0

        self.ball_Y         =   0
        self.ball_YMin      =   0
        self.ball_YMax      =   0

        self.white_X        =   0
        self.white_XMin     =   0   #線
        self.white_XMax     =   0

        self.white_YMin     =   0
        self.white_YMax     =   0

        self.basket_size    =   0   #大小
        self.ball_size      =   0

    def imageinfor(self):

        for basket_red in range (send.color_mask_subject_cnts[5]):

            if send.color_mask_subject_size[5][basket_red] > 700:
                self.basket_X       =   send.color_mask_subject_X[5][basket_red]
                self.basket_XMin    =   send.color_mask_subject_XMin[5][basket_red]
                self.basket_XMax    =   send.color_mask_subject_XMax[5][basket_red]

                self.basket_Y       =   send.color_mask_subject_Y[5][basket_red]
                self.basket_YMin    =   send.color_mask_subject_YMin[5][basket_red]
                self.basket_YMax    =   send.color_mask_subject_YMax[5][basket_red]

                self.basket_size    =   send.color_mask_subject_size[5][basket_red]
            else:
                self.basket_X       =   0
                self.basket_XMin    =   0
                self.basket_XMax    =   0

                self.basket_Y       =   0
                self.basket_YMin    =   0
                self.basket_YMax    =   0

                self.basket_size    =   0

        for ball_orange in range (send.color_mask_subject_cnts[0]):

            if send.color_mask_subject_size[0][ball_orange] > 200:
                self.ball_X         =   send.color_mask_subject_X[0][ball_orange]
                self.ball_XMin      =   send.color_mask_subject_XMin[0][ball_orange]
                self.ball_XMax      =   send.color_mask_subject_XMax[0][ball_orange]

                self.ball_Y         =   send.color_mask_subject_Y[0][ball_orange]
                self.ball_YMin      =   send.color_mask_subject_YMin[0][ball_orange]
                self.ball_YMax      =   send.color_mask_subject_YMax[0][ball_orange]

                self.ball_size      =   send.color_mask_subject_size[0][ball_orange]
            else:
                self.ball_X         =   0
                self.ball_XMin      =   0
                self.ball_XMax      =   0

                self.ball_Y         =   0
                self.ball_YMin      =   0
                self.ball_YMax      =   0

                self.ball_size      =   0

send = Sendmessage()
class move_message:

    def __init__(self):
        #動作位置
        self.reset_flag         =   False

        self.now_RL_Position    =   2048
        self.now_UD_Position    =   2048

        self.find_ball_flag     =   False
        self.move_enough        =   0

        self.now_waist_Position =   0

        self.robot_theta        =   0

        self.stage              =   "Find ball"

        self.turn_head          =   0

        self.Record_Goal_X      =   None
        self.Record_Goal_Y      =   None

        self.walk_flag          =   False

        self.Move_X             =   0
        self.Move_Y             =   0
        self.Fallow_Goal_X      =   0
        self.Fallow_Goal_Y      =   0

        self.change_point       =   0

    def now_HeadMotor(self,ID,Position,Speed):	    #頭部馬達 ID: 1左右 2上下

        if ID == 1:
            self.now_RL_Position = Position

        if ID == 2:
            self.now_UD_Position = Position

        send.sendHeadMotor(ID,Position,Speed)

    def Body_walk(self, walk_state):

        if walk_state == False and self.walk_flag == True:          #不要走 且 正在走
            send.sendBodyAuto(0,0,0,0,1,0)
            self.walk_flag = False
            print("\n'''''''''''''''''STOP'''''''''''''''''''\n")

        if walk_state == True  and self.walk_flag == False:         #要走  且 沒在走
            send.sendBodyAuto(0,0,0,0,1,0)
            self.walk_flag = True
            print("\n'''''''''''''''''MOVE'''''''''''''''''''\n")

    def now_SingleMotor(self,ID,Position,Speed):    #全身馬達

        if ID == 9:                                 #9號 腰部馬達

            if Position > 0:
                self.now_waist_Position += Position

            if Position < 0:
                self.now_waist_Position += Position

        if move.now_waist_Position > 650 or move.now_waist_Position < -650:
            print("\n''''''''''''''MOVE TO MUCH''''''''''''''\n")

        else:
            send.sendSingleMotor(ID,Position,Speed)

    def now_sendContinuousValue(self,x,y,z,theta,sensor):

        self.robot_theta = theta
        send.sendContinuousValue(x - 400, y - 200, z, theta - 3, sensor)

    def find_goal(self, View_Goal_X, Head_DN_Position, move_Max, move_min, speed):   #初始階段 0 :找球

        if self.turn_head == 0:
            move.now_HeadMotor(2, 2048 - 200, speed)                #抬頭

            if move.now_RL_Position < move_Max:
                move.now_HeadMotor(1, move.now_RL_Position + 20, speed)
                # print("View_ball_size = ", view.ball_size)
                print("now_RL_Position = ", move.now_RL_Position)
                print("View_Goal_X = ", View_Goal_X)
                time.sleep(0.05)   #延遲

            else:
                self.turn_head = 1
                print("head_right")

        if self.turn_head == 1:
            move.now_HeadMotor(2, Head_DN_Position, speed)          #低頭

            if move.now_RL_Position > move_min:
                move.now_HeadMotor(1, move.now_RL_Position - 20, speed)
                # print("View_ball_size = ", view.ball_size)
                print("now_RL_Position = ", move.now_RL_Position)
                print("View_Goal_X = ", View_Goal_X)
                time.sleep(0.05)   #延遲

            else:
                self.turn_head = 0
                print("head_left")

    def Fallow_Goal(self, View_Goal_X, View_Goal_Y, speed):
        if View_Goal_X > 0:
            #追蹤
            self.Move_X = View_Goal_X - 160

            self.Fallow_Goal_X = round( ( 70.42 * ( self.Move_X / 320 ) ) * 0.25 * ( 4096 / 360 ) )
                                                                                #How much scale to move

            move.now_HeadMotor(1, move.now_RL_Position - self.Fallow_Goal_X, speed)

        if View_Goal_Y > 0:
            #追蹤
            self.Move_Y = View_Goal_Y - 120

            self.Fallow_Goal_Y = round( ( 70.42 * ( self.Move_Y / 240 ) ) * 0.25 * ( 4096 / 360 ) )
                                                                                #How much scale to move

            move.now_HeadMotor(2, move.now_UD_Position - self.Fallow_Goal_Y, speed)

    def turn_to_goal(self, View_Goal_X, X, Y, left_big_theta, right_big_theta):

        if View_Goal_X > 2100:    #目標在左
            move.now_sendContinuousValue(X, Y, 0, left_big_theta, 0)            #旋轉量
            print("turn_left_big")
            print("now_theta = ", self.robot_theta)

        if View_Goal_X < 2000:    #目標在右
            move.now_sendContinuousValue(X, Y, 0, right_big_theta, 0)           #旋轉量
            print("turn_right_big")
            print("now_theta = ", self.robot_theta)

        print("now_RL_Position = ", move.now_RL_Position)

    def Go_to_Goal(self, x_Max, x_Min,   X, Y,   left_small_theta, right_small_theta,   forword_X, forword_Y, forword_theta):

        if move.now_RL_Position > x_Max:     #目標在左邊
            move.now_sendContinuousValue(X, Y, 0, left_small_theta, 0)          #旋轉量
            print("turn_left_small")
            print("now_theta = ", self.robot_theta)

        elif move.now_RL_Position < x_Min:   #目標在右邊
            move.now_sendContinuousValue(X, Y, 0, right_small_theta, 0)         #旋轉量
            print("turn_right_small")
            print("now_theta = ", self.robot_theta)

        else:                       #直走
            move.now_sendContinuousValue(forword_X, forword_Y, 0, forword_theta, 0)
            print("go straight")
            print("now_theta = ", self.robot_theta)

    def Turn_Waist_to_Goal(self, Goal_x, Big_move,left_Waist_Amount, Right_Waist_Amount, speed):

        if Goal_x < 160:

            if (160 - Goal_x) > 20:
                move.now_SingleMotor(9, left_Waist_Amount + Big_move, speed - 200)

            else:
                move.now_SingleMotor(9, left_Waist_Amount, speed)

        elif Goal_x > 160:

            if (160 - Goal_x) > 20:
                move.now_SingleMotor(9, Right_Waist_Amount - Big_move, speed - 200)

            else:
                move.now_SingleMotor(9, Right_Waist_Amount, speed)

    def Go_Back_and_straight(self, Goal, Max, Min,   Back_X, Back_Y, Back_theta,   Straight_X, Straight_Y, Straight_theta,   left_X, left_Y, left_theta,   right_X, right_Y, right_theta):

        if Goal > Max:                      #退至線後
            move.now_sendContinuousValue( Back_X, Back_Y, 0, Back_theta, 0)
            print("go back")
            print("now_theta = ", move.robot_theta)

        if Goal < Min:                      #退過頭往前
            move.now_sendContinuousValue( Straight_X, Straight_Y, 0, Straight_theta, 0)
            print("go straight")
            print("now_theta = ", move.robot_theta)

        if move.now_RL_Position < 2000:
            move.now_sendContinuousValue( left_X, left_Y, 0, right_theta, 0)
            print("Go Right")
            print("now_theta = ", move.robot_theta)

        if move.now_RL_Position > 2100:
            move.now_sendContinuousValue( right_X, right_Y, 0, left_theta, 0)
            print("Go Left")
            print("now_theta = ", move.robot_theta)

if __name__ == '__main__':
    view = view_message()
    move = move_message()
    try:
        while not rospy.is_shutdown():
            # if send.Web == False :

            if send.is_start == False :

                view.imageinfor()

                send.drawImageFunction(1,0,  160,160,   0,240,      0,0,0)
                send.drawImageFunction(2,0,  0,320,     120,120,    0,0,0)
                send.drawImageFunction(3,1,  120,200,   80,160,     0,0,0)
                send.drawImageFunction(4,1,  80,240,    40,200,     0,0,0)

                send.drawImageFunction(5,0,  0,320,     view.basket_YMin,view.basket_YMin,    255,0,0)
                send.drawImageFunction(6,0,  0,320,     view.basket_YMax,view.basket_YMax,    255,0,0)

                send.drawImageFunction(7,1,  view.ball_XMin,view.ball_XMax,     view.ball_YMin,view.ball_YMax,  255,0,0)

                print("\nbasket_size = ", view.basket_size)
                print("ball_size = ", view.ball_size)
                print("\nbasket_X = ", view.basket_X)
                print("basket_Y = ", view.basket_Y)

                move.Body_walk(False)

                if move.reset_flag == True:
                    send.sendBodySector(29)
                    send.sendHeadMotor(1, 2048, 100)
                    send.sendHeadMotor(2, 2048, 100)
                    print("'''''''''''''''''''stand''''''''''''''''''''")

                view.__init__()
                move.__init__()

                move.reset_flag = False

                time.sleep(1)

            # if send.Web == True :

            if send.is_start == True :

                view.imageinfor()
                move.reset_flag = True

                send.drawImageFunction(1,0,160,160,0,240,0,0,0)
                send.drawImageFunction(2,0,0,320,120,120,0,0,0)
                send.drawImageFunction(3,1,120,200,80,160,0,0,0)
                send.drawImageFunction(4,1,80,240,40,200,0,0,0)

                send.drawImageFunction(5,0,0,320,view.white_YMin,view.white_YMin,255,0,0)
                send.drawImageFunction(6,0,0,320,view.white_YMax,view.white_YMax,255,0,0)

                send.drawImageFunction(7,1,  view.ball_XMin,view.ball_XMax,     view.ball_YMin,view.ball_YMax,  255,0,0)

                if move.stage == "Find ball":                   #進入階段 0 :找球
                    view.imageinfor()

                    if view.ball_X > 80 and view.ball_X < 240 or move.find_ball_flag == True:
                        move.find_ball_flag = True

                        if view.ball_size > 2500 or move.move_enough < 5 :
                            print("'''''''''''''''Too Close''''''''''''''''")

                            move.Fallow_Goal( view.ball_X, view.ball_Y, 200)
                            # View_Goal_X, View_Goal_Y, speed

                            move.Body_walk(True)                               #開啟連續步態
                            move.Go_to_Goal( 2100, 2000,   -500, 0, 9, -7,   -1300, 0, 0)
                            # x_Max, x_Min,   X, Y, left_small_theta, right_small_theta,
                            #                 forword_X, forword_Y, forword_theta

                            print("\nball_size = ", view.ball_size)

                            if view.ball_size < 2500:
                                print("move_enough = ", move.move_enough)
                                move.move_enough += 1

                            time.sleep(0.2)                                      #延遲

                        else:
                            move.stage = "Turn to ball"         #進入階段 1 :轉向球
                            print("\nstage = ", move.stage)     #找球結束

                            time.sleep(2)                                   #延遲

                    else:
                        move.find_goal( view.ball_X, 1350, 2600, 1400, 100)
                        # View_Goal_X, Head_DN_Position, move_Max, move_min, speed

                if move.stage == "Turn to ball":
                    view.imageinfor()
                    print("\nNow_RL_Position = ", move.now_RL_Position)

                    print("\nFallow_Goal_X = ", move.Fallow_Goal_X)
                    print("Fallow_Goal_Y = ", move.Fallow_Goal_Y)

                    move.Body_walk(True)                                    #啟動連續步態

                    if move.now_RL_Position > 1900 and move.now_RL_Position < 2200:
                        move.stage = "Go to ball"               #進入階段 2 :走向球
                        print("\nstage = ", move.stage)         #轉向球結束

                    else:
                        move.Fallow_Goal( view.ball_X, view.ball_Y, 200)
                        # View_Goal_X, View_Goal_Y, speed

                        move.turn_to_goal( move.now_RL_Position,    0, 0,    9, -7)
                        # View_Goal_X,     X, Y,    left_big_theta, right_big_theta
                        time.sleep(0.2)

                if move.stage == "Go to ball":
                    view.imageinfor()
                    print("\nNow_UD_Position = ", move.now_UD_Position)

                    if move.now_UD_Position < 1670:                         #頭低到多少角度停下
                        move.now_sendContinuousValue(0, 0, 0, 0, 0)
                        print("No Headway")                                 #原地踏步
                        time.sleep(1)                                       #延遲

                        move.Body_walk(False)                               #關閉連續步態
                        time.sleep(1)                                       #延遲

                        send.sendBodySector(101)                            #蹲下, 抬手, 轉手
                        time.sleep(4.5)                                      #延遲

                        move.now_HeadMotor(1, 2048 -140, 100)               #頭看向手爪1
                        move.now_HeadMotor(2, 1740, 100)
                        view.imageinfor()
                        time.sleep(0.5)                                       #延遲

                        move.now_HeadMotor(1, 2048 -280, 100)               #頭看向手爪2
                        time.sleep(0.5)                                       #延遲

                        move.stage = "Catch ball"               #進入階段 3 :夾球
                        print("\nstage = ", move.stage)         #走向球結束

                    else:
                        move.Fallow_Goal( view.ball_X, view.ball_Y, 200)
                        # View_Goal_X, View_Goal_Y, speed

                        move.Go_to_Goal( 2100, 2000,   400, 0, 9, -7,   1500, 0, 1)
                        # x_Max, x_Min,   X, Y, left_small_theta, right_small_theta,
                        #                 forword_X, forword_Y, forword_theta
                        time.sleep(0.1)

                if move.stage == "Catch ball":
                    view.imageinfor()
                    print("\nView_Ball_X = ", view.ball_X)

                    if view.ball_X > 158 and view.ball_X < 162:
                        print("start to chack ball")

                        send.sendBodySector(102)                            #手臂下降到球位置夾球
                        time.sleep(4)                                       #延遲

                        move.now_SingleMotor(9, - move.now_waist_Position, 150)
                        time.sleep(1.5)                                       #腰轉回來

                        send.sendBodySector(103)                            #手臂回原位並起立
                        time.sleep(3.5)                                       #延遲

                        move.now_HeadMotor(1, 2048, 100)
                        move.now_HeadMotor(2, 2048, 100)                    #頭轉正
                        time.sleep(1)                                       #延遲

                        move.stage = "Find basket"              #進入階段 4 :找框
                        print("\nstage = ", move.stage)         #夾球結束

                    else:                                                   #轉腰
                        view.imageinfor()
                        move.Turn_Waist_to_Goal( view.ball_X, 9, 1, -1, 300)
                        # Goal_x, Big_move,left_Waist_Amount, Right_Waist_Amount, speed
                        print("Now_Waist_Position = ", move.now_waist_Position)
                        time.sleep(0.05)

                if move.stage == "Find basket":
                    view.imageinfor()

                    if view.basket_X > 80 and view.basket_X < 240:

                        if move.change_point == 0:
                            move.stage = "Turn to basket"       #進入階段 5 :轉向框
                            print("\nstage = ", move.stage)     #找框結束

                        if move.change_point == 1 or move.change_point == 2:
                            move.stage = "Turn waist to basket" #進入階段 9 :腰轉向框
                            move.now_HeadMotor(1, 2048, 100)
                            print("\nstage = ", move.stage)     #找框結束

                        time.sleep(1)                                       #延遲

                    else:
                        move.find_goal( view.basket_X, 2048, 2800, 1200, 100)
                        # View_Goal_X, Head_DN_Position, move_Max, move_min, speed

                if move.stage == "Turn to basket":
                    view.imageinfor()
                    print("\nNow_RL_Position = ", move.now_RL_Position)

                    move.Body_walk(True)                                    #啟動連續步態

                    if move.now_RL_Position > 2000 and move.now_RL_Position < 2100:
                        move.now_HeadMotor(1, 2048, 100)                    #頭擺正
                        move.now_HeadMotor(2, 2048, 100)                    #抬頭

                        move.stage = "Go to basket"             #進入階段 6 :走向框

                        # move.stage = "Back to line"             #進入階段 8 :退到線後
                        # move.change_point = 1                   #到5分線後
                        # move.change_point = 2                   #到3分線後

                        print("\nstage = ", move.stage)         #轉向框結束

                        time.sleep(1)

                    else:
                        move.Fallow_Goal( view.basket_X, view.basket_Y, 200)
                        # View_Goal_X, View_Goal_Y, speed

                        move.turn_to_goal( move.now_RL_Position,   0, 0,    9, -7)
                        # View_Goal_X,     X, Y,    left_big_theta, right_big_theta
                        time.sleep(0.2)

                if move.stage == "Go to basket":
                    view.imageinfor()
                    print("\nView_Basket_X = ", view.basket_X)
                    print("Now_UD_Position = ", move.now_UD_Position)

                    if move.now_UD_Position < 1690:             #頭低到多少角度停下

                        move.now_sendContinuousValue(0, 0, 0, 0, 0)
                        print("No Headway")                                 #原地踏步
                        time.sleep(1)                                       #延遲

                        move.Body_walk(False)                               #關閉連續步態
                        time.sleep(1)

                        send.sendBodySector(104)                            #腰抬正, 手臂平舉, 手臂向上舉高
                        time.sleep(6)                                       #延遲

                        move.now_HeadMotor(1, 2048 -130, 100)               #頭看向手爪

                        move.stage = "Start dunk"               #進入階段 7 :灌籃
                        print("\nstage = ", move.stage)         #走向框結束

                    else:
                        move.Fallow_Goal( view.basket_X, view.basket_Y, 200)
                        # View_Goal_X, View_Goal_Y, speed

                        move.Go_to_Goal( 2150, 1950,   500, 0, 9, -7,   1500, 1, 0)
                        # x_Max, x_Min,   X, Y, left_small_theta, right_small_theta,
                        #                 forword_X, forword_Y, forword_theta
                        time.sleep(0.1)

                if move.stage == "Start dunk":
                    view.imageinfor()
                    print("\nView_Basket_X = ", view.basket_X)
                    print("View_Basket_Y = ", view.basket_Y)

                    if view.basket_X > 158 and view.basket_X < 162:

                        time.sleep(1)                                       #延遲
                        send.sendBodySector(105)                            #手爪鬆開
                        time.sleep(3)                                       #延遲

                        move.stage = "End"
                        print("\nstage = ", move.stage)         #灌籃結束

                    else:                                                   #轉腰
                        view.imageinfor()
                        move.Turn_Waist_to_Goal( view.basket_X, 9, 1, -1, 300)
                        # Goal_x, Big_move,left_Waist_Amount, Right_Waist_Amount, speed
                        print("Now_Waist_Position = ", move.now_waist_Position)
                        time.sleep(0.05)

                # if move.stage == "Back to line":
                #     view.imageinfor()
                #     print("\nbasket_size = ", view.basket_size)

                #     if ((view.basket_size < 1500 and view.basket_size > 1450 and move.change_point == 1) or (view.basket_size < 2950 and view.basket_size > 2900 and move.change_point == 2)):
                #         move.now_sendContinuousValue(0, 0, 0, 0, 0)
                #         print("No Headway")                                 #原地踏步
                #         time.sleep(1.5)                                       #延遲

                #         move.Body_walk(False)                               #關閉連續步態
                #         time.sleep(3)

                #         move.stage = "Find basket"              #再次進入階段 4 :確認框
                #         print("\nstage = ", move.stage)         #退至線後結束

                #     else:
                #         move.Fallow_Goal( view.basket_X, view.basket_Y, 200)
                #         # View_Goal_X, View_Goal_Y, speed

                #         if move.change_point == 1:                               #退致5分線
                #             move.Go_Back_and_straight( view.basket_size, 5000, 5000,   -2500, 0, 0,   100, 0, 0,   0, 0, 3,   0, 0, -4)
                #             # Goal, Max, Min,   Back_X, Back_Y, Back_theta,   Straight_X, Straight_Y, Straight_theta,
                #             #                   left_X, left_Y, left_theta,   right_X,    right_Y,    right_theta

                #         if move.change_point == 2:                               #退致3分線
                #             move.Go_Back_and_straight( view.basket_size, 2300, 2300,   -2500, 0, 0,   100, 0, 0,   0, 0, 3,   0, 0, -4)
                #             # Goal, Max, Min,   Back_X, Back_Y, Back_theta,   Straight_X, Straight_Y, Straight_theta,
                #             #                   left_X, left_Y, left_theta,   right_X,    right_Y,    right_theta

                #         time.sleep(0.1)

                # if move.stage == "Turn waist to basket":
                #     view.imageinfor()
                #     print("\nView_Basket_X = ", view.basket_X)

                #     if view.basket_X > 158 and view.basket_X < 162:

                #         if view.basket_size < 5000 +200 and view.basket_size > 5000 -200:
                #             print("start shoot 5 point")

                #             time.sleep(2)                                   #延遲

                #             move.stage = 100
                #             print("\nstage = ", move.stage)     #投籃結束

                #         if view.basket_size < 2300 +200 and view.basket_size > 2300 -200:
                #             print("start shoot 3 point")

                #             time.sleep(2)                                   #延遲

                #             move.stage = "End"
                #             print("\nstage = ", move.stage)     #投籃結束

                #     else:                                                   #轉腰
                #         view.imageinfor()
                #         move.Turn_Waist_to_Goal( view.basket_X, 4, 1, -1, 300)
                #         # Goal_x, Big_move,left_Waist_Amount, Right_Waist_Amount, speed
                #         print("Now_Waist_Position = ", move.now_waist_Position)
                #         time.sleep(0.05)

    except rospy.ROSInterruptException:
        pass


"""
Function that finds the cut containing a galaxy's data employing Cutout2D.

Libraries: import numpy
           import pandas / from astropy.table import Table
           from astropy.wcs import WCS
           from astropy.nddata import Cutout2D
           from astropy.coordinates import SkyCoord
           import astropy.units as u

Inputs: hdu -> contains all info from file. hdu[1] has the data we are after
        names -> string array containing the names of the bodies contained in the region object
        ind -> index of the galaxy inside the region file
        ra,dec (deg) -> coordinates of the centre of the cut
        lim_bot,lim_top,lim_left,lim_right -> number of pixels in each direction from the centre

Outputs: cutout2D -> cutout object of the area

To improve: -> Give the choice to use ind or not
            -> Give the choice to employ pixels or celestial coordinates. Or any combination of both.
"""
def frame_auto(ind,hdu,names,ra,dec,lim_bot,lim_top,lim_left,lim_right):

    #convert coordinates to pixels
    ra_c = ra[ind]
    dec_c = dec[ind]
    wcs = WCS(hdu_r[1].header)
    c = SkyCoord(ra_c,dec_c, unit="deg")
    x,y = astropy.wcs.utils.skycoord_to_pixel(c,wcs)

    #estimate size of cutout
    position = c
    size_y = (int(y)+int(lim_top[ind]))-(int(y)-int(lim_bot[ind]))
    size_x = (int(x)+int(lim_right[ind]))-(int(x)-int(lim_left[ind]))
    size = (size_y, size_x)     # pixels
    #cutout
    cutout = Cutout2D(hdu_r[1].data, position, size,wcs=wcs)

    return(cutout)


"""An example implementation of an ASTReward for an AV validation scenario."""
import numpy as np  # useful packages for math
import csv

from ast_toolbox.rewards import ASTReward  # import base class

# Define the class, inherit from the base
class ExampleAVReward(ASTReward):
    """An example implementation of an ASTReward for an AV validation scenario.

    Parameters
    ----------
    num_peds : int
        The number of pedestrians in the scenario.
    cov_x : float
        Covariance of the x-acceleration.
    cov_y : float
        Covariance of the y-acceleration.
    cov_sensor_noise : float
        Covariance of the sensor noise.
    use_heuristic : bool
        Whether to include a heuristic in the reward based on how close the pedestrian is to the vehicle
        at the end of the trajectory.
    """

    def __init__(self,
                 num_peds=1,
                 cov_x=0.1,
                 cov_y=0.01,
                 cov_sensor_noise=0.1,
                 use_heuristic=True):

        self.c_num_peds = num_peds
        self.c_cov_x = cov_x
        self.c_cov_y = cov_y
        self.c_cov_sensor_noise = cov_sensor_noise
        self.use_heuristic = use_heuristic
        super().__init__()

    def give_reward(self, action, **kwargs):
        """Returns the reward for a given time step.

        Parameters
        ----------
        action : array_like
            Action taken by the AST solver.
        kwargs :
            Accepts relevant info for computing the reward.
        Returns
        -------
        reward : float
            Reward based on the previous action.
        """
        # get the info from the simulator
        info = kwargs['info']
        peds = info["peds"]
        car = info["car"]
        is_goal = info["is_goal"]
        is_terminal = info["is_terminal"]
        dist = peds[:, 2:4] - car[2:4]

        # Write to output file the car/ped information
        car_x = car[2:3]
        car_y = car[3:4]
        ped_x = peds[0][2:3]
        ped_y = peds[0][3:4]
        car_xv = car[0:1]
        car_yv = car[1:2]
        ped_xv = peds[0][0:1]
        ped_yv = peds[0][1:2]
        data = [car_x[0], car_y[0], car_xv[0], car_yv[0], ped_x[0], ped_y[0], ped_xv[0], ped_yv[0]]
        with open("ga_paths.txt", "a") as file:
            writer = csv.writer(file)
            writer.writerow(data)

        with open("mcts_paths.txt", "a") as file:
            writer = csv.writer(file)
            writer.writerow(data)

        ga_crash_file = open("ga_crashes.txt", "a")
        mcts_crash_file = open("mcts_crashes.txt", "a")

        # update reward and done bool

        if (is_goal):  # We found a crash
            reward = 0
            ga_crash_file.writelines(str(data)[1:-1] + "\n")
            mcts_crash_file.writelines(str(data)[1:-1] + "\n")
            # file.writelines(str(dist) + "\n")
        elif (is_terminal):
            # reward = 0
            # Heuristic reward based on distance between car and ped at end
            if self.use_heuristic:
                heuristic_reward = np.min(np.linalg.norm(dist, axis=1))
            else:
                # No Herusitic
                heuristic_reward = 0
            reward = -100000 - 10000 * heuristic_reward  # We reached
            # the horizon with no crash
        else:
            reward = -self.mahalanobis_d(action)  # No crash or horizon yet

        # GA reward file
        reward_file = open("ga_rewards.txt", "a")
        reward_file.writelines(str(reward) + "\n")
        reward_file.close()
        # GA crash file
        ga_crash_file.close()

        # MCTS reward file
        reward_file = open("mcts_rewards.txt", "a")
        reward_file.writelines(str(reward) + "\n")
        reward_file.close()
        # MCTS crash file
        mcts_crash_file.close()

        return reward

    def mahalanobis_d(self, action):
        """Calculate the Mahalanobis distance [1]_ between the action and the mean action.

        Parameters
        ----------
        action : array_like
            Action taken by the AST solver.

        Returns
        -------
        float
            The Mahalanobis distance between the action and the mean action.

        References
        ----------
        .. [1] Mahalanobis, Prasanta Chandra. "On the generalized distance in statistics." National Institute of
            Science of India, 1936.
            `<http://library.isical.ac.in:8080/jspui/bitstream/10263/6765/1/Vol02_1936_1_Art05-pcm.pdf>`_
        """
        # Mean action is 0
        mean = np.zeros((6 * self.c_num_peds, 1))
        # Assemble the diagonal covariance matrix
        cov = np.zeros((self.c_num_peds, 6))
        cov[:, 0:6] = np.array([self.c_cov_x, self.c_cov_y,
                                self.c_cov_sensor_noise, self.c_cov_sensor_noise,
                                self.c_cov_sensor_noise, self.c_cov_sensor_noise])
        big_cov = np.diagflat(cov)

        # subtract the mean from our actions
        dif = np.copy(action)
        dif[::2] -= mean[0, 0]
        dif[1::2] -= mean[1, 0]

        # calculate the Mahalanobis distance
        dist = np.dot(np.dot(dif.T, np.linalg.inv(big_cov)), dif)

        return np.sqrt(dist)


# TUTORIAT 4 (SORTARI + TUPLURI)
# ex5 (Tutoriat 3)
# m = int(input("m="))
# n = int(input("n="))
# x = int(input("x="))
# matrice = [[0 for j in range(n)] for i in range(m)]
# for i in range(m):
#     for j in range(n):
#         print(matrice[i][j], end=" ")
#     print()
# a)
#
# b)
# suma_maxima = -1
# indice = -1
# for j in range(n):
#     suma = 0
#     for i in range(m):
#         suma += matrice[i][j]
#     if suma > suma_maxima:
#         suma_maxima = suma
#         indice = j
# print(suma_maxima, j)

# c)
# diagonala principala => i = j
# diagonala secundara => i + j = n - 1 => i = n - j - 1
# deasupra diagonalei principale => i < j
# sub diagonala principala => i > j
# deasupra diagonalei secundare => i + j < n - 1
# sub diagonala secundara => i + j > n - 1
#
# suma = 0
# for i in range(m):
#     suma += matrice[i][i]
# print(f"Suma elementelor de pe diagonala principala: {suma}")
#
# produs = 1
# for j in range(n):
#     produs *= matrice[n-j-1][j]
# print(f"Produsul elementelor de pe diagonala secundara: {produs}")
#
# suma_impare = 0
# for i in range(m):
#     for j in range(n):
#         if i > j and i + j < n - 1 and matrice[i][j] % 2 == 1:
#             suma_impare += matrice[i][j]
# print(f"Suma elementelor din zona data: {suma_impare}")

# citire elemente matrice, fiecare linie pe un rand
# 0 5 10 15
# m = int(input("m="))
# matrice1 = []
# for i in range(m):
#     linie = [int(x) for x in input().split()]
#     matrice1.append(linie)
#
# for i in range(m):
#     for elem in matrice1[i]:
#         print(elem, end=" ")
#     print()

# citire matrice cu m linii, n coloane, element cu element
# m = int(input("m="))
# n = int(input("n="))
# matrice2 = []
# for i in range(m):
#     linie = []
#     for j in range(n):
#         linie.append(int(input("elem=")))
#     matrice2.append(linie)
#
# for i in range(m):
#     for elem in matrice2[i]:
#         print(elem, end=" ")
#     print()

# ex1
import functools

def numar_cifre(a):
    cifre = 0
    while a:
        cifre += 1
        a //= 10
    return cifre

def comparare(a, b):
    if numar_cifre(a) < numar_cifre(b):
        return -1
    if numar_cifre(a) == numar_cifre(b):
        return 0
    if numar_cifre(a) > numar_cifre(b):
        return 1

n = int(input("n="))
lista = []
for i in range(n):
    lista.append(int(input("elem=")))
lista.sort(key=functools.cmp_to_key(comparare))
print(lista)

Anul I/Semestrul I/PA/Tutoriat/Tutoriat Teorie/tutoriat4.py


import pyodbc

dados_conexao = (
    "Driver={SQL Server};"
    "Server=DESKTOP-E9ARPQB;"
    "Database=PythonSQL;"
)

conexao = pyodbc.connect(dados_conexao)
if conexao:
    print('Conexao bem sucedida')
else:
    print('Erro')

cursor = conexao.cursor()

while True:
    acao = input('Qual ação você quer fazer? ')
    if acao == 'cadastro':
        nome = input('Nome: ')
        idade = int(input('Idade: '))
        email = input('Digite seu e-mail: ')
        comando = f"""INSERT INTO USUARIO (NOME, IDADE, EMAIL)
                    VALUES
                    ('{nome}', {idade}, '{email}')"""
        cursor.execute(comando)
        cursor.commit()
        print('Cadastro efetuado com sucesso')
    elif acao == 'buscar':
        user = input('Qual é o nome do usuario que você quer consultar: ')
        cursor.execute(f" SELECT NOME, IDADE FROM USUARIO WHERE NOME LIKE '%{user}%' ")
        for nome in cursor:
            print(f'Usúario:{nome}')
    else:
        cursor.execute("SELECT * FROM USUARIO")
        for user in cursor:
            print(user)


# day1
floor = 0
position = 0

f = open("day1.txt", "r")
for x in f:
    for i in x:
        position += 1
        if i == "(":
            floor += 1
        elif i == ")":
            floor -= 1
        if floor == -1:
            print(position)
            break

print(floor)


# coding: utf-8
"""HirshfeldCharges"."""
from __future__ import print_function, division, unicode_literals, absolute_import

from abipy.core.mixins import Has_Structure

import logging
logger = logging.getLogger(__name__)

__all__ = [
    "HirshfeldCharges",
]

class HirshfeldCharges(Has_Structure, object):

    def __init__(self, charges, structure):
        self.charges = charges
        self._structure = structure

    @property
    def structure(self):
        return self._structure

    @classmethod
    def from_cut3d_outfile(cls, filepath, structure):
        charges = []
        with open(filepath, 'rt') as f:
            while True:
                l = f.readline()

                if l is None:
                    raise RuntimeError('The file does not contain Hirshfeld harges')
                elif "Hirshfeld Charge" in l:
                    break

            #skip one line
            f.readline()

            for i in range(len(structure)):
                l = f.readline()
                charges.append(float(l.split()[2]))

        return cls(charges, structure)


n = input().lower()
a = ','.join(n).split(',')
unique = list(set(a))

asdf = {}
for x in a:
    if x not in asdf:
        asdf[x] = 1
    else:
        asdf[x] += 1

lst = []
for k in asdf:
    lst.append(asdf[k])

new = []
for j in asdf:
    q = max(lst)
    if q == asdf[j]:
        new.append(j)
    else:
        pass

if len(new) > 1:
    print('?')
else:
    print(new[0].upper())


import sys

from fastapi import HTTPException
sys.path.append('/Users/anirudh.chawla/python_fast_api_projects/hospital-management-fastapi')
"""Controller file for writing db queries"""
from typing import Optional
import sys
from sqlalchemy.orm import Session
from models import models,schemas
from response import Response as ResponseData
from supplier.app.error_handling import Error

# Python code to merge dict using update() method
def Merge(dict1, dict2):
    """Function to merge dict using update method"""
    return dict2.update(dict1)

def add_new_supplier(database: Session, supplier: schemas.SupplierBase):
    """Function to return query based data while creating new supplier creation api"""
    for key,value in supplier.dict().items():
        if key == "company" or key == "contact_number" or key == "address":
            is_error = Error.if_param_is_null_or_empty(supplier.dict()[key],key)
            if is_error:
                return ResponseData.success_without_data(f"{key} cannot be empty")
    db_supplier = models.Supplier(**supplier.__dict__)
    database.add(db_supplier)
    database.commit()
    database.refresh(db_supplier)
    return ResponseData.success(db_supplier.__dict__,"New Supplier added successfully")

def get_supplier_by_id(database: Session, id : Optional[int] = None):
    """Function to get room details based on room id generated while adding new supplier"""
    db_supplier = database.query(models.Supplier).filter(models.Supplier.id == id).first()
    if db_supplier is None:
        return ResponseData.success([],"Supplier id is invalid")
    db_supplier_details = database.query(models.Supplier).filter(models.Supplier.id == id).first()
    return ResponseData.success(db_supplier_details.__dict__,"Supplier details fetched successfully")

def delete_supplier_details(database: Session, id : Optional[int] = None):
    """Function to delete single or all Supplier details if needed"""
    if id is None:
        database.query(models.Supplier).delete()
        database.commit()
        return ResponseData.success([],"All Supplier details deleted successfully")
    database.query(models.Supplier).filter_by(id = id).delete()
    database.commit()
    return ResponseData.success([],"Supplier details deleted successfully")

def update_supplier_details(database: Session, supplier: schemas.AddNewSupplier):
    """Function to update Supplier details"""
    data = database.query(models.Supplier).filter(models.Supplier.id == supplier.id).all()
    dict1 = data[0]
    if supplier.dict()["company"] is not None :
        dict1.__dict__["company"] = supplier.dict()["company"]
    if supplier.dict()["contact_number"] is not None :
        dict1.__dict__["contact_number"] = supplier.dict()["contact_number"]
    if supplier.dict()["email_id"] is not None :
        dict1.__dict__["email_id"] = supplier.dict()["email_id"]
    if supplier.dict()["address"] is not None :
        dict1.__dict__["address"] = supplier.dict()["address"]
    database.query(models.Supplier).filter(models.Supplier.id == supplier.id).update({ models.Supplier.id : supplier.id,
        models.Supplier.company: dict1.__dict__["company"],
        models.Supplier.contact_number : dict1.__dict__["contact_number"],
        models.Supplier.email_id : dict1.__dict__["email_id"],
        models.Supplier.address : dict1.__dict__["address"],
    })
    database.flush()
    database.commit()
    return ResponseData.success(dict1.__dict__,"Supplier details updated successfully")


#!/usr/bin/env python3

import time
import rg_telnet_cmd
import map_clients
import device_ref

class LogRSSI:
    def __init__(self, clients):
        # Constructor based on RG Telnet
        self._rg_telnet = rg_telnet_cmd.RGTelnetCmd('linux', '')
        self._client_mapper = map_clients.MapClients(clients)
        self._client_map = None
        #self._mode = 'linux'
        self.client_ip_list = clients
        self.duration = 10
        self.interval = 1
        self.rssi_output = None

    def format_cmd(self, client_mac, radio):
        # Format shell command values based on:
        # wl -i wl[radio] sta_info [MAC of client] | grep smoothed
        return ''.join(['wl -i ', radio, ' sta_info ', client_mac, ' | grep smoothed'])

    def map_client_list(self):
        #time.sleep(1)
        while self._client_map is None:
            try:
                self._client_mapper.map()
                #time.sleep(.1)
                self._client_map = self._client_mapper.client_map
                print(self._client_map)
            except:
                pass

    def rssi_cmd(self, option, hw, client):
        self.rssi_output = None
        if not self._client_map:
            self.map_client_list()
            time.sleep(.1)
        try:
            mac = self._client_map[client]['mac']
            radio = device_ref.radio_ref[hw][self._client_map[client]['port']]
            #print(mac, radio)
            if option == 'single':
                raw = self._rg_telnet.run_cmd(self.format_cmd(mac, radio))
                self.rssi_output = self._rg_telnet.parse_single_output(raw).split(' ')[-1]
            else:
                raw = self._rg_telnet.run_duration(self.interval, self.duration, self.format_cmd(mac, radio))
                parsed = self._rg_telnet.parse_duration_output(raw)
                self.rssi_output = [int(parsed[i].split(' ')[-1]) for i in range(len(parsed)) if i%2 == 1]
            return self.rssi_output
        except:
            print('ERROR RUNNING COMMAND')

    def rssi_multi_clients(self, option, hw):
        self.rssi_output = None
        if len(self.client_ip_list) > 1:
            rssi_list = []
            for client in self.client_ip_list:
                rssi_list.append(self.rssi_cmd(option, hw, client))
            return rssi_list
        else:
            try:
                self.rssi_cmd(option, hw, self.client_ip_list[0])
            except:
                print('NO CLIENTS IN LIST')

    def print_ref(self):
        print(device_ref.radio_ref)

if __name__ == '__main__':
    #test = LogRSSI(['192.168.1.202'])
    #test = LogRSSI(['192.168.1.205', '192.168.1.67'])
    #print(test.format_cmd('7e:c3:79:a7:0c:bd', 'wl1'))
    #print(test.rssi_cmd('', 'nokia', '192.168.1.202'))
    #test.test()
    #for client in test.client_ip_list:
        #print(test.rssi_cmd('', 'nokia', client))
    print(test.rssi_multi_clients('', 'nokia'))


from gpytranslate import Translator
from pyrogram import Client, filters
from pyrogram.types import Message
from pyrobot import COMMAND_HAND_LER

gpytrl = Translator()

@Client.on_message(filters.command("trg", COMMAND_HAND_LER))
async def translate(_, message: Message) -> None:
    reply_msg = message.reply_to_message
    if not reply_msg:
        await message.reply_text("Reply to a message to translate it!")
        return
    if reply_msg.caption:
        to_translate = reply_msg.caption
    elif reply_msg.text:
        to_translate = reply_msg.text
    try:
        args = message.text.split()[1].lower()
        if "//" in args:
            source = args.split("//")[0]
            dest = args.split("//")[1]
        else:
            source = await gpytrl.detect(to_translate)
            dest = args
    except IndexError:
        source = await gpytrl.detect(to_translate)
        dest = "en"
    translation = await gpytrl(to_translate,
                              sourcelang=source, targetlang=dest)
    reply = f"**Translated from** `{source}` **to** `{dest}`:\n```{translation.text}```"

    await message.reply_text(reply, parse_mode="markdown")


import pickle
from commons.util import *
from tqdm import tqdm

def split_triple():
    with open("convert_hownet.pkl","rb") as f:
        hownet = pickle.load(f)

    aligment = []
    with open("conceptnet.hownet/HasSubevent_match_result.txt","r") as f:
        for d in tqdm(parse_alignment_noxiaoqi(f,context_f=True)):
            if d["start_id"] is not None:
                start_ids = d["start_id"].split("@@@@")
                for si,sid in enumerate(start_ids):
                    if sid == "":
                        continue
                    start_content = hownet[sid]
                    if si == 0:
                        d["start_synset"] = [start_content["triples"]]
                        d["start"] = start_content["label"]
                    else:
                        if "start_synset" not in d:
                            d["start_synset"] = []
                        d["start_synset"].append(start_content["triples"])
                        d["start"] = d["start"] +"@@@@"+ start_content["label"]
            if d["end_id"] is not None:
                end_ids = d["end_id"].split("@@@@")
                for ei,eid in enumerate(end_ids):
                    if eid == "":
                        continue
                    end_content = hownet[eid]
                    if ei == 0:
                        d["end_synset"] = [end_content["triples"]]
                        d["end"] = end_content["label"]
                    else:
                        if "end_synset" not in d:
                            d["end_synset"] = []
                        d["end_synset"].append(end_content["triples"])
                        d["end"] = d["end"] +"@@@@"+ end_content["label"]
            # d["subject"] =
            aligment.append(d)

    with open("conceptnet.hownet/convert_aligment_HasSubevent_match_result.pkl", 'wb') as fpkl:
        pickle.dump(aligment, fpkl)

if __name__ == "__main__":
	split_triple()


import cProfile
import csv
import re
from betacode import decode

ketiv = 0
qere = 0
rafe = 0
line = ""
tf_content = []
print("Reading tfdata ...")
# RecordId, HebrewText, HebLemma, SDBH, LexDomain, GLemma
verses = {}
recordid_map = {}
with open('tfdata.csv') as csvfile:
	reader = csv.DictReader(csvfile)
	for row in reader:
		tf_content.append(row)
		v = re.match(r'(^.*),', row["RecordId"])
		if v:
			vid = v.group(1)
			if vid not in verses:
				verses[vid] = []
			verses[vid].append(row["RecordId"])
			recordid_map[row["RecordId"]] = len(tf_content) - 1
		# to_decode = re.sub(r'[\d\/]', '', row['HebrewText'])
		# to_decode = re.sub(r'~', ' ', to_decode)
		# if re.search(r'\*\*', to_decode):
		# 	qere += 1
		# 	# continue
		# if re.search(r'\*', to_decode):
		# 	ketiv += 1
		# 	to_decode = re.sub(r'\*', '', to_decode)
		# if re.search(r',', to_decode):
		# 	to_decode = re.sub(r'\,', '', to_decode)
		# 	rafe += 1
		# decoded = decode(to_decode) if to_decode != "_" else "_"
		# tf_content.append({
		# 	"id": row["RecordId"],
		# 	"betacode": row["HebrewText"],
		# 	"hebrew": decoded,
		# 	"lemma": row["HebLemma"],
		# 	"sdbh": row["SDBH"],
		# 	"domain": row["LexDomain"],
		# 	"glemma": row["GLemma"],
		# })
		if len(tf_content) % 50000 == 0:
			print(" |", len(tf_content), "lines processed")
print(" ^", len(tf_content), "lines processed")
print("Completed tfdata prep\n")

# HebLemma, MTVerseID, MTSTartSequence, MTEndSequence, GrkLemma, LXXVerseID, LXXPhrase
og_content = []
emptylemma = 0
print("Reading ogdata ...")
with open('parallelsearch.csv') as csvfile:
	reader = csv.DictReader(csvfile)
	for row in reader:
		og_content.append(row)
		if row["GrkLemma"] == "":
			emptylemma += 1
		if len(og_content) % 50000 == 0:
			print(" |", len(og_content), "lines processed")
print(" ^", len(og_content), "lines processed")
print("Completed ogdata prep ({} empty lemmas)\n".format(emptylemma))

def id_in_range(rid, lower, upper):
	m = re.search("(^\w+ \d+:\d+,)(\d+.\d+)", rid)
	pos_float = float(m.group(2))
	return pos_float >= lower and pos_float <= upper

def partial_match_id_range(abbreviated_map_ids, id_partial_start, id_partial_end):
	lower = float(id_partial_start)
	upper = float(id_partial_end)
	return list(filter(lambda x: id_in_range(x,lower,upper), abbreviated_map_ids))

def process_everything():
	# inject greek stuff...
	failures = 0
	oldid = ""
	ids_done = 0
	print("Processing parallels ({})".format(len(og_content)))
	for i, og in enumerate(og_content):
		if i % 50000 == 0:
			print(" |", i, "matched rows")

		if og["MTSTartSequence"] == "" or og["MTSTartSequence"] == "MTSTartSequence":
			continue

		if og["MTSTartSequence"] == og["MTEndSequence"]:
			rid = og["MTVerseID"] + "," + og["MTSTartSequence"]
			tf_content[ recordid_map[rid] ]["GLemma"] = og["GrkLemma"]
		else:
			success = False
			rr = partial_match_id_range(verses[og["MTVerseID"]], og["MTSTartSequence"], og["MTEndSequence"])
			if rr is None:
				print("None?", og["MTVerseID"], og["MTSTartSequence"], og["MTEndSequence"])

			for j, rid in enumerate(rr):
				tfid = recordid_map[rid]
				if tf_content[tfid]["HebLemma"] == og["HebLemma"]:
					success = True
					tf_content[tfid]["GLemma"] = og["GrkLemma"]

			if not success:
				failures += 1

	print(" ^ DONE:", failures, "words without greek lemmas\n")

# cProfile.run('process_everything()')
process_everything()

print ("Writing csv file...")
filename = "processed_tfdata.csv"
with open(filename, mode='wt', encoding='utf-8') as out:
	csvout = csv.DictWriter(out, ["RecordId", "HebrewText", "HebLemma", "SDBH", "LexDomain", "GLemma"])
	csvout.writeheader()
	csvout.writerows(tf_content)
print ("done")


import pytest
import tempfile
import os.path
from src.wt_tools import blk_unpack

test_data_folder = "data_for_tests"
test_data_output_folder = os.path.join(test_data_folder, 'out')

def read_and_unpack(blk_file, blkx_file, out_type):
    """Prepare files: unpack and return"""
    with open(os.path.join(test_data_folder, blk_file), 'rb') as f:
        data = f.read()
    blk = blk_unpack.BLK(data)
    tempfile_path = tempfile.mkstemp(prefix=blkx_file, dir=test_data_output_folder)
    with open(tempfile_path[1], 'w') as f:
        f.write(blk.unpack(out_type))

    expected_data = open(os.path.join(test_data_folder, blkx_file), 'r').read()
    result_data = open(tempfile_path[1], 'r').read()
    return expected_data, result_data

@pytest.mark.skip(reason="cant find old files now")
class TestOldBlk:
    def test_old_blk_in_strict_blk_mode(self):
        expected_data, result_data = read_and_unpack('camera.old.blk', 'camera.old.blkx',
                                                     blk_unpack.BLK.output_type['strict_blk'])
        assert result_data == expected_data, "Wrong output blkx"

    def test_old_blk_in_json_mode(self):
        expected_data, result_data = read_and_unpack('camera.old.blk', 'camera.old.json.blkx',
                                                     blk_unpack.BLK.output_type['json'])
        assert result_data == expected_data, "Wrong output blkx"

class TestNewBlk:
    def test_new_blk_in_strict_blk_mode(self):
        expected_data, result_data = read_and_unpack('camera.new.blk', 'camera.new.blkx',
                                                     blk_unpack.BLK.output_type['strict_blk'])
        assert result_data == expected_data, "Wrong output blkx"

    def test_new_blk_in_json_mode(self):
        expected_data, result_data = read_and_unpack('camera.new.blk', 'camera.new.json.blkx',
                                                     blk_unpack.BLK.output_type['json'])
        assert result_data == expected_data, "Wrong output blkx"

    def test_new_blk_with_big_num_of_units_and_subunits(self):
        """
        To trigger units_length_type = 0x81 and
        sub_units_block_type = 0x80
        """
        expected_data, result_data = read_and_unpack('gui.blk', 'gui.blkx',
                                                     blk_unpack.BLK.output_type['strict_blk'])
        assert result_data == expected_data, "Wrong output blkx"

    def test_new_blk_with_zero_subunits(self):
        """
        To trigger sub_units_block_length == 0 and
        total_sub_units = 0
        """
        expected_data, result_data = read_and_unpack('situationconst.blk', 'situationconst.blkx',
                                                     blk_unpack.BLK.output_type['strict_blk'])
        assert result_data == expected_data, "Wrong output blkx"

    @pytest.mark.skip(reason="cant find files now")
    def test_new_blk_with_spaces_in_key(self):
        """
        Check case, when key contain spaces:
            "random from":i=0
        and check type_list[int]
        """
        expected_data, result_data = read_and_unpack('assaults_template.blk', 'assaults_template.blkx',
                                                     blk_unpack.BLK.output_type['strict_blk'])
        assert result_data == expected_data, "Wrong output blkx"

    @pytest.mark.skip(reason="cant find files now")
    def test_new_blk_with_array_type(self):
        """
        Check type_list[m4x3f]
        """
        expected_data, result_data = read_and_unpack('bzt_part.blk', 'bzt_part.blkx',
                                                     blk_unpack.BLK.output_type['strict_blk'])
        assert result_data == expected_data, "Wrong output blkx"

    @pytest.mark.skip(reason="cant find files now")
    def test_new_blk_with_big_unit_length(self):
        """
        Check long unit values strings:
            unit_length >= 0x80:
        """
        expected_data, result_data = read_and_unpack('ct_test.blk', 'ct_test.blkx',
                                                     blk_unpack.BLK.output_type['strict_blk'])
        assert result_data == expected_data, "Wrong output blkx"

    @pytest.mark.skip(reason="cant find files now")
    def test_new_blk_with_utf8_strings(self):
        """
        Check with russian comment lines
        """
        expected_data, result_data = read_and_unpack('lpt_part.blk', 'lpt_part.blkx',
                                                     blk_unpack.BLK.output_type['json'])
        assert result_data == expected_data, "Wrong output blkx"


import cv2
import numpy as np
#Resimlere morfoloji işlemlerinin uygulanması
cekirdek = np.ones((7,7),np.uint8)
resim = cv2.imread(r"opencv\video_ve_resimler\j.png")
gri_resim = cv2.cvtColor(resim,cv2.COLOR_BGR2GRAY)
resim2 = cv2.imread(r"opencv\video_ve_resimler\acma.JPG",0)
resim3 = cv2.imread(r"opencv\video_ve_resimler\kapama.JPG",0)

#Aşındırma(erozyon) işleminin yapılması, beyaz noktalar azalır.

# iteration : tekrarlama, yapılacak aşındırma işlemi sayısı
asındırma = cv2.erode(resim,cekirdek,iterations=1)

#Yayma işleminin yapılması, beyaz noktalar artar.
yayma = cv2.dilate(gri_resim,cekirdek,iterations=1)

#Gradyan işleminin yapılması, yayma ve aşındırmanın farkı(görüntünün iskeletini bulur.)
gradyan = cv2.morphologyEx(gri_resim,cv2.MORPH_GRADIENT,cekirdek)

#Açma ve kapama işlemlerinin yapılması
acma = cv2.morphologyEx(resim2,cv2.MORPH_OPEN,cekirdek)
kapama = cv2.morphologyEx(resim3,cv2.MORPH_CLOSE,cekirdek)

#Top-hat ve black-hat işlemlerinin yapılması ,
#top-hat:açma işleminden orjinali çıkarmak(beyaz fazla kalır) , black-hat: kapatma işleminden orjinali çıkarmak(beyaz az kalır)
top_hat = cv2.morphologyEx(gri_resim,cv2.MORPH_TOPHAT,cekirdek)
black_hat = cv2.morphologyEx(gri_resim,cv2.MORPH_BLACKHAT,cekirdek)

while True:
    print("1-Asindirma\n2-Yayma\n3-Gradyan\n4-Acma ve Kapama\n5-Top Hat ve Black Hat\n6-Cikis")
    secim = input("Yapmak istediginiz islemi seciniz:")

    if secim == '1':
        cv2.imshow("Orjinal",resim)
        cv2.imshow("Erozyon",asındırma)
        cv2.waitKey(5000)
        cv2.destroyAllWindows()

    if secim == '2':
        cv2.imshow("Orjinal",resim)
        cv2.imshow("Yayma",yayma)
        cv2.waitKey(5000)
        cv2.destroyAllWindows()

    if secim == '3':
        cv2.imshow("Orjinal",resim)
        cv2.imshow("Gradyan",gradyan)
        cv2.waitKey(5000)
        cv2.destroyAllWindows()

    if secim == '4':
        cv2.imshow("Orjinal Acma",resim2)
        cv2.imshow("Orjinal Kapama",resim3)
        cv2.imshow("Acma",acma)
        cv2.imshow("Kapama",kapama)
        cv2.waitKey(7000)
        cv2.destroyAllWindows()

    if secim == '5':
        cv2.imshow("Orjinal",resim)
        cv2.imshow("Top Hat",top_hat)
        cv2.imshow("Black Hat",black_hat)
        cv2.waitKey(5000)
        cv2.destroyAllWindows()

    if secim == '6':
        break


import xml.etree.ElementTree as ET
import xml.dom.minidom as minidom
from graphviz import Digraph

class Node:
    def __init__(self, data):
        self.data = data
        self.next = None

class LinkedList:
    def __init__(self):
        self.head = None
        self.length = 0

    def insert(self, data):
        new_node = Node(data)
        if not self.head:
            self.head = new_node
        else:
            current = self.head
            while current.next:
                current = current.next
            current.next = new_node
        self.length += 1

    def exists(self, data):
        current = self.head
        while current:
            if current.data == data:
                return True
            current = current.next
        return False

    def __getitem__(self, index):
        current = self.head
        count = 0
        while current:
            if count == index:
                return current.data
            count += 1
            current = current.next
        raise IndexError("Index out of range")

    def __setitem__(self, index, data):
        current = self.head
        count = 0
        while current:
            if count == index:
                current.data = data
                return
            count += 1
            current = current.next
        raise IndexError("Index out of range")

    def __len__(self):
        return self.length

def imprimir_matriz(matriz):
    for fila in matriz:
        fila_str = ' '.join(map(str, fila))
        print(fila_str)

def imprimir_grupos(grupos):
    for grupo_num, filas in grupos.items():
        filas_str = ', '.join(map(str, filas))
        print(f"Grupo {grupo_num}: Filas [{filas_str}]")

def cargar_archivo():
    tree = ET.parse('prueba.xml')
    root = tree.getroot()

    max_amplitud = 0
    max_tiempo = 0

    for elemento in root.findall('senal'):
        for item in elemento.findall('dato'):
            tiempo = int(item.get('t'))
            amplitud = int(item.get('A'))

            max_amplitud = max(max_amplitud, amplitud)
            max_tiempo = max(max_tiempo, tiempo)

    matriz = LinkedList()
    for _ in range(max_tiempo):
        fila = LinkedList()
        for _ in range(max_amplitud):
            fila.insert(0)
        matriz.insert(fila)

    for elemento in root.findall('senal'):
        for item in elemento.findall('dato'):
            tiempo = int(item.get('t')) - 1
            amplitud = int(item.get('A')) - 1
            valor = int(item.text)
            fila = matriz[tiempo]
            fila[amplitud] = valor

    return matriz

def aplicar_umbral(matriz):
    matriz_umbral = LinkedList()
    for fila in matriz:
        fila_umbral = LinkedList()
        for valor in fila:
            fila_umbral.insert(1 if valor > 0 else 0)
        matriz_umbral.insert(fila_umbral)
    print(matriz_umbral)
    return matriz_umbral

def agrupar_filas(matriz_umbral):
    grupos = {}
    fila_indices = {}

    for fila_num, fila in enumerate(matriz_umbral):
        fila_str = ''.join(map(str, fila))
        if fila_str in fila_indices:
            grupo_id = fila_indices[fila_str]
            grupos[grupo_id].append(fila_num)
        else:
            nuevo_grupo_id = len(grupos) + 1
            grupos[nuevo_grupo_id] = [fila_num]
            fila_indices[fila_str] = nuevo_grupo_id

    return grupos

def sumar_valores_por_grupo(matriz_valores, grupos):
    valores_agrupados = LinkedList()
    num_columnas = len(matriz_valores[0])

    for grupo_num, filas in grupos.items():
        suma_grupo = [0] * num_columnas
        for fila_num in filas:
            suma_grupo = [a + b for a, b in zip(suma_grupo, matriz_valores[fila_num])]
        valores_agrupados.insert(suma_grupo)

    return valores_agrupados

def guardar_en_xml(filename, matriz_valores, grupos, valores_agrupados):
    root = ET.Element('senalesReducidas')

    for grupo_num, filas in grupos.items():
        atributos_grupo = {'nombre': f'Grupo {grupo_num + 1}'}
        grupo = ET.SubElement(root, 'senal', atributos_grupo)
        grupo.set('A', str(len(matriz_valores[0])))
        grupo.set('a', str(grupo_num + 1))

        grupo_element = ET.SubElement(grupo, 'grupo', g=str(grupo_num + 1))
        tiempos_element = ET.SubElement(grupo_element, 'tiempos')
        tiempos_element.text = ','.join(str(fila + 1) for fila in filas)

        datos_grupo_element = ET.SubElement(grupo_element, 'datosGrupo')
        for amplitud, valor in enumerate(valores_agrupados[grupo_num - 1]):
            dato_element = ET.SubElement(datos_grupo_element, 'dato', A=str(amplitud + 1))
            dato_element.text = str(valor)

    rough_string = ET.tostring(root, 'utf-8')
    reparsed = minidom.parseString(rough_string)
    pretty_xml = reparsed.toprettyxml(indent="  ")

    with open(filename, "w", encoding="utf-8") as xml_file:
        xml_file.write(pretty_xml)

def generar_grafica_matriz_original(matriz, titulo):
    dot = Digraph(titulo)
    dot.attr(rankdir='TB')

    dot.node('inicio', titulo, shape='ellipse')

    t_filas = LinkedList()
    t_filas.insert(len(matriz))
    dot.node('t_filas', label=f't={t_filas.head.data}', shape='ellipse')
    dot.edge('inicio', 't_filas')

    A_columnas = LinkedList()
    A_columnas.insert(len(matriz[0]))
    dot.node('A_columnas', label=f'A={A_columnas.head.data}', shape='ellipse')
    dot.edge('inicio', 'A_columnas')

    for i in range(A_columnas.head.data):
        columna_node_ids = LinkedList()
        for j in range(t_filas.head.data):
            node_id = f'fila_{j}_col_{i}'
            label = LinkedList()
            label.insert(str(matriz[j][i]))
            dot.node(node_id, label=label.head.data, shape='ellipse', style='filled', fillcolor='white')
            columna_node_ids.insert(node_id)

        dot.edge('inicio', columna_node_ids.head.data)

        current_node = columna_node_ids.head
        while current_node.next:
            dot.edge(current_node.data, current_node.next.data)
            current_node = current_node.next

    dot.view()

def generar_grafica_valores_agrupados(valores_agrupados, titulo):
    dot = Digraph(titulo)
    dot.attr(rankdir='TB')

    dot.node('inicio', titulo, shape='ellipse')

    t_grupos = LinkedList()
    t_grupos.insert(len(valores_agrupados))
    dot.node('t_grupos', label=f'Grupos={t_grupos.head.data}', shape='ellipse')
    dot.edge('inicio', 't_grupos')

    A_columnas = LinkedList()
    A_columnas.insert(len(valores_agrupados[0]))
    dot.node('A_columnas', label=f'A={A_columnas.head.data}', shape='ellipse')
    dot.edge('inicio', 'A_columnas')

    for i in range(A_columnas.head.data):
        columna_node_ids = LinkedList()
        for j in range(t_grupos.head.data):
            node_id = f'grupo_{j}_col_{i}'
            label = LinkedList()
            label.insert(str(valores_agrupados[j][i]))
            dot.node(node_id, label=label.head.data, shape='ellipse', style='filled', fillcolor='white')
            columna_node_ids.insert(node_id)

        dot.edge('inicio', columna_node_ids.head.data)

        current_node = columna_node_ids.head
        while current_node.next:
            dot.edge(current_node.data, current_node.next.data)
            current_node = current_node.next

    dot.view()

def procesar_archivo():
    print("Procesando archivo...")

def escribir_archivo_salida():
    print("Escribiendo archivo de salida...")

def mostrar_datos_estudiante():
    print("Nombre: Rodrigo Sebastian Castro Aguilar")
    print("Carné: 202204496")
    print("Curso: Introduccion a la Computacion y Programacion 2")
    print("Carrera: Ingenieria en Ciencias y Sistemas")
    print("Semestre: Cuarto Semestre")

def generar_grafica():
    print("Generando gráfica...")

signal_list = LinkedList()

while True:
    print("Menú principal:")
    print("1. Cargar archivo")
    print("2. Procesar archivo")
    print("3. Escribir archivo salida")
    print("4. Mostrar datos del estudiante")
    print("5. Generar gráfica")
    print("6. Salida")

    opcion = input("Selecciona una opción: ")

    if opcion == "1":
        cargar_archivo()
        print("Archivo cargado exitosamente...")
    elif opcion == "2":
        procesar_archivo()
        matriz_valores = cargar_archivo()
        matriz_umbral = aplicar_umbral(matriz_valores)
        grupos = agrupar_filas(matriz_umbral)
        valores_agrupados = sumar_valores_por_grupo(matriz_valores, grupos)
        print("Matriz de valores original:")
        imprimir_matriz(matriz_valores)
        print("______________________________________________________________")
        print("\nMatriz umbral:")
        imprimir_matriz(matriz_umbral)
        print("______________________________________________________________")
        print("\nGrupos:")
        imprimir_grupos(grupos)
        print("\nValores agrupados:")
        imprimir_matriz(valores_agrupados)
        print("______________________________________________________________")
    elif opcion == "3":
        escribir_archivo_salida()
        xml_filename = 'senales_reducidas.xml'
        guardar_en_xml(xml_filename, matriz_valores, grupos, valores_agrupados)
        print(f"Archivo XML '{xml_filename}' guardado exitosamente.")
    elif opcion == "4":
        mostrar_datos_estudiante()
    elif opcion == "5":
        print("Generar gráficas:")
        print("1. Matriz Valores")
        print("2. Valores Agrupados")
        opcion_grafica = input("Selecciona una opción de gráfica: ")

        if opcion_grafica == "1":
            generar_grafica_matriz_original(matriz_valores, "Matriz Valores")
        elif opcion_grafica == "2":
            generar_grafica_valores_agrupados(valores_agrupados, "Valores Agrupados")
        else:
            print("Opción no válida. Selecciona una opción válida.")
    elif opcion == "6":
        print("Saliendo del programa.")
        break
    else:
        print("Opción no válida. Por favor, selecciona una opción válida.")


file = open('9_1')
count = 0

for i in file:
    nums = [int(j) for j in i.split()]
    if len(nums) == len(set(nums)):
        ch = [j for j in nums if j % 2 == 0]
        nech = [j for j in nums if j % 2 != 0]
        if len(ch) > len(nech) and sum(ch) < sum(nech):
            count += 1
print(count)


"""Add customizable_text

Revision ID: 58d61f975f05
Revises: 45e46ee4911f
Create Date: 2020-04-27 22:13:48.837415

"""
from alembic import op
import sqlalchemy as sa

# revision identifiers, used by Alembic.
revision = '58d61f975f05'
down_revision = '45e46ee4911f'
branch_labels = None
depends_on = None

def upgrade():
    op.create_table(
        'customizable_text', sa.Column('name', sa.String(length=255), nullable=False),
        sa.Column('lang', sa.String(length=16), nullable=False), sa.Column('text', sa.Text(), nullable=True),
        sa.Column('permissions', sa.JSON(), nullable=True), sa.PrimaryKeyConstraint('name', 'lang'))

def downgrade():
    op.drop_table('customizable_text')