from django.utils.translation import gettext as _
from django.db import transaction
from rest_framework.response import Response

from core import errors as exceptions
from api.viewsets import AsRoleGenericViewSet
from api.serializers import ticket as ticket_serializers
from api.paginations import FollowUpMarkerCursorPagination
from ticket.models import Ticket, TicketChange, TicketRating
from ticket.managers import TicketManager
from ticket.notifiers import TicketEmailNotifier
from users.managers import get_user_by_name

from .handlers import serializer_error_msg

class TicketHandler:
    @staticmethod
    def create_ticket(view: AsRoleGenericViewSet, request, kwargs):
        try:
            params = TicketHandler._ticket_create_validate_params(view=view, request=request)
        except exceptions.Error as exc:
            return view.exception_response(exc)

        title = params['title']
        description = params['description']
        service_type = params['service_type']
        contact = params['contact']
        user = request.user

        count = TicketManager.not_result_ticket_count(user_id=user.id)
        if count >= 5:
            return view.exception_response(exceptions.TooManyTicket())

        try:
            ticket = TicketManager.create_ticket(
                title=title, description=description, service_type=service_type, contact=contact, submitter=user
            )
        except Exception as exc:
            return view.exception_response(exceptions.Error(message=_('创建工单错误。') + str(exc)))

        try:
            TicketEmailNotifier.new_ticket_notice(ticket=ticket)
        except Exception as exc:
            pass

        return Response(data=ticket_serializers.TicketSerializer(instance=ticket).data)

    @staticmethod
    def _ticket_create_validate_params(view, request):
        """
        :raises: Error
        """
        serializer = view.get_serializer(data=request.data)
        if not serializer.is_valid(raise_exception=False):
            s_errors = serializer.errors
            if 'title' in s_errors:
                exc = exceptions.BadRequest(message=_('无效的标题。') + s_errors['title'][0], code='InvalidTitle')
            elif 'description' in s_errors:
                exc = exceptions.BadRequest(
                    message=_('无效的问题描述。') + s_errors['description'][0], code='InvalidDescription')
            elif 'service_type' in s_errors:
                exc = exceptions.BadRequest(
                    message=_('问题相关的服务无效。') + s_errors['service_type'][0], code='InvalidServiceType')
            else:
                msg = serializer_error_msg(serializer.errors)
                exc = exceptions.BadRequest(message=msg)

            raise exc

        data = serializer.validated_data
        title = data['title']
        description = data['description']
        service_type = data['service_type']

        if len(title) < 10:
            raise exceptions.BadRequest(message=_('标题长度不能少于10个字符'), code='InvalidTitle')
        elif len(description) < 10:
            raise exceptions.BadRequest(message=_('问题描述不能少于10个字符'), code='InvalidDescription')
        elif service_type not in Ticket.ServiceType.values:
            raise exceptions.BadRequest(message=_('问题相关的服务无效'), code='InvalidServiceType')

        return data

    @staticmethod
    def update_ticket(view: AsRoleGenericViewSet, request, kwargs):
        ticket_id = kwargs[view.lookup_field]

        try:
            params = TicketHandler._ticket_create_validate_params(view=view, request=request)
            ticket = TicketManager.get_ticket(ticket_id=ticket_id)
        except exceptions.Error as exc:
            return view.exception_response(exc)

        new_title = params['title']
        new_description = params['description']
        new_service_type = params['service_type']
        new_contact = params['contact']

        if ticket.submitter_id != request.user.id:
            return view.exception_response(exceptions.AccessDenied(message=_('你没有此工单的访问权限')))

        if ticket.status not in [Ticket.Status.OPEN.value, Ticket.Status.PROGRESS.value]:
            return view.exception_response(
                exceptions.ConflictTicketStatus(message=_('只允许更改状态为“打开”和“处理中”的工单')))

        no_changes = all([
            new_title == ticket.title,
            new_description == ticket.description,
            new_service_type == ticket.service_type,
            new_contact == ticket.contact
        ])
        if no_changes:
            return Response(data=ticket_serializers.TicketSerializer(instance=ticket).data)

        update_fields = ['modified_time']
        ticket_chenges = []
        if new_title != ticket.title:
            update_fields.append('title')
            ticket_chenges.append([TicketChange.TicketField.TITLE.value, ticket.title, new_title])
            ticket.title = new_title

        if new_description != ticket.description:
            update_fields.append('description')
            ticket_chenges.append([TicketChange.TicketField.DESCRIPTION.value, ticket.description, new_description])
            ticket.description = new_description

        if new_service_type != ticket.service_type:
            update_fields.append('service_type')
            ticket.service_type = new_service_type

        if new_contact != ticket.contact:
            update_fields.append('contact')
            ticket.contact = new_contact

        try:
            with transaction.atomic():
                ticket.save(update_fields=update_fields)
                # open状态的工单（已指派处理人的工单除外）更改不产生 更改记录
                if (ticket.status != Ticket.Status.OPEN.value or ticket.assigned_to_id) and ticket_chenges:
                    for field, old_value, new_value in ticket_chenges:
                        TicketManager.create_followup_action(
                            user=request.user, ticket_id=ticket.id, field_name=field,
                            old_value=old_value, new_value=new_value, atomic=False
                        )
        except Exception as exc:
            return view.exception_response(exceptions.Error(message=_('更改工单失败。') + str(exc)))

        return Response(data=ticket_serializers.TicketSerializer(instance=ticket).data)

    @staticmethod
    def list_tickets(view: AsRoleGenericViewSet, request, kwargs):
        try:
            params = TicketHandler._list_tickets_validate_params(view=view, request=request)
        except exceptions.Error as exc:
            return view.exception_response(exc)

        user = request.user
        has_role = params['has_role']
        role = params['role']
        if has_role:
            if role == view.AS_ROLE_ADMIN and user.is_federal_admin():
                queryset = TicketManager().get_tickets_queryset(
                    submitter_id=params['submitter_id'], status=params['status'],
                    service_type=params['service_type'], severity=params['severity'],
                    assigned_to_id=params['assigned_to_user_id']
                )
            else:
                return view.exception_response(exceptions.AccessDenied(message='你没有联邦管理员权限'))
        else:
            queryset = TicketManager().get_user_tickets_queryset(
                user=user, status=params['status'],
                service_type=params['service_type'], severity=params['severity']
            )

        try:
            tickets = view.paginate_queryset(queryset=queryset)
            serializer = view.get_serializer(tickets, many=True)
            return view.get_paginated_response(data=serializer.data)
        except Exception as exc:
            return view.exception_response(exc)

    @staticmethod
    def _list_tickets_validate_params(view: AsRoleGenericViewSet, request):
        """
        :raises: Error
        """
        status_ = request.query_params.get('status', None)
        service_type = request.query_params.get('service_type', None)
        submitter_id = request.query_params.get('submitter_id', None)
        severity = request.query_params.get('severity', None)
        assigned_to = request.query_params.get('assigned_to', None)

        if status_ is not None and status_ not in Ticket.Status.values:
            raise exceptions.InvalidArgument(message=_('指定的工单状态无效'), code='InvalidStatus')

        if service_type is not None and service_type not in Ticket.ServiceType.values:
            raise exceptions.InvalidArgument(message=_('指定的相关服务类型无效'), code='InvalidServiceType')

        if severity is not None and severity not in Ticket.Severity.values:
            raise exceptions.InvalidArgument(message=_('指定的问题严重程度值无效'), code='InvalidSeverity')

        has_role, role = view.check_as_role_request(request=request)
        if submitter_id is not None and not has_role:
            raise exceptions.ParameterConflict(
                message=_('查询指定提交人的工单参数“submitter_id”，只允许与参数“as_role”一起提交。'))

        if assigned_to is not None:
            if not has_role:
                raise exceptions.ParameterConflict(
                    message=_('查询分配给自己的工单参数“assigned_to”，只允许与参数“as_role”一起提交。'))

            if assigned_to:
                if assigned_to == request.user.username:
                    assigned_to_user_id = request.user.id
                else:   # UserNotExist
                    user = get_user_by_name(username=assigned_to)
                    assigned_to_user_id = user.id
            else:       # 值为空时，查询自己
                assigned_to_user_id = request.user.id
        else:
            assigned_to_user_id = None

        return {
            'status': status_,
            'service_type': service_type,
            'severity': severity,
            'submitter_id': submitter_id,
            'has_role': has_role,
            'role': role,
            'assigned_to_user_id': assigned_to_user_id
        }

    @staticmethod
    def ticket_detial(view: AsRoleGenericViewSet, request, kwargs):
        ticket_id = kwargs[view.lookup_field]
        try:
            has_role, role = view.check_as_role_request(request=request)
            ticket = TicketManager.get_ticket(ticket_id=ticket_id)
        except exceptions.Error as exc:
            return view.exception_response(exc)

        user = request.user
        if has_role:
            if role == view.AS_ROLE_ADMIN and user.is_federal_admin():
                pass
            else:
                return view.exception_response(exceptions.AccessDenied(message=_('你没有联邦管理员权限')))
        elif ticket.submitter_id != request.user.id:
            return view.exception_response(exceptions.AccessDenied(message=_('你没有此工单的访问权限')))

        try:
            serializer = view.get_serializer(instance=ticket)
            return Response(data=serializer.data)
        except Exception as exc:
            return view.exception_response(exc)

    @staticmethod
    def ticket_severity_change(view: AsRoleGenericViewSet, request, kwargs):
        ticket_id = kwargs[view.lookup_field]
        new_severity = kwargs.get('severity', '')

        if new_severity not in Ticket.Severity.values:
            return view.exception_response(
                exceptions.InvalidArgument(message=_('指定的工单严重程度无效。'), code='InvalidSeverity'))

        if not request.user.is_federal_admin():
            return view.exception_response(exceptions.AccessDenied(message=_('你没有此工单的访问权限。')))

        try:
            ticket = TicketManager.get_ticket(ticket_id=ticket_id)
        except exceptions.Error as exc:
            return view.exception_response(exc)

        if ticket.assigned_to_id != request.user.id:
            return view.exception_response(exceptions.AccessDenied(message=_('你不是此工单的指派处理人。')))

        if ticket.status == Ticket.Status.CLOSED.value:
            return view.exception_response(exceptions.ConflictTicketStatus(message=_('工单已关闭。')))

        if new_severity == ticket.severity:
            return Response(data={'severity': new_severity})

        try:
            with transaction.atomic():
                old_severity = ticket.severity
                ticket.severity = new_severity
                ticket.save(update_fields=['severity', 'modified_time'])
                TicketManager.create_followup_action(
                    user=request.user, ticket_id=ticket.id,
                    field_name=TicketChange.TicketField.SEVERITY.value,
                    old_value=old_severity, new_value=new_severity, atomic=False
                )
        except Exception as exc:
            return view.exception_response(exceptions.Error(message=_('更改工单严重程度失败。') + str(exc)))

        return Response(data={'severity': new_severity})

    @staticmethod
    def ticket_status_change(view: AsRoleGenericViewSet, request, kwargs):
        ticket_id = kwargs[view.lookup_field]
        new_status = kwargs.get('status', '')

        if new_status not in Ticket.Status.values:
            return view.exception_response(
                exceptions.InvalidArgument(message=_('指定的工单状态无效。'), code='InvalidStatus'))

        try:
            has_role, role = view.check_as_role_request(request=request)
            ticket = TicketManager.get_ticket(ticket_id=ticket_id)
        except exceptions.Error as exc:
            return view.exception_response(exc)

        if ticket.status == Ticket.Status.CLOSED.value:
            return view.exception_response(
                exceptions.ConflictTicketStatus(message=_('您不允许更改“已关闭”状态的工单。')))

        user = request.user
        if has_role:
            if role == view.AS_ROLE_ADMIN and user.is_federal_admin():
                if ticket.assigned_to_id != request.user.id:
                    return view.exception_response(exceptions.AccessDenied(message=_('你不是此工单的指派处理人。')))
            else:
                return view.exception_response(exceptions.AccessDenied(message=_('你没有联邦管理员权限')))
        else:
            if ticket.submitter_id != request.user.id:
                return view.exception_response(exceptions.AccessDenied(message=_('你没有此工单的访问权限')))

            if new_status != Ticket.Status.CLOSED.value:
                return view.exception_response(
                    exceptions.ConflictTicketStatus(message=_('您只允许关闭工单。')))

        if new_status == ticket.status:
            return Response(data={'status': new_status})

        try:
            with transaction.atomic():
                old_status = ticket.status
                ticket.status = new_status
                ticket.save(update_fields=['status', 'modified_time'])
                TicketManager.create_followup_action(
                    user=request.user, ticket_id=ticket.id,
                    field_name=TicketChange.TicketField.STATUS.value,
                    old_value=old_status, new_value=new_status, atomic=False
                )
        except Exception as exc:
            return view.exception_response(exceptions.Error(message=_('更改工单状态失败。') + str(exc)))

        return Response(data={'status': new_status})

    @staticmethod
    def add_followup(view: AsRoleGenericViewSet, request, kwargs):
        ticket_id = kwargs[view.lookup_field]
        try:
            params = TicketHandler._add_followup_validate_params(view=view, request=request)
        except exceptions.Error as exc:
            return view.exception_response(exc)

        try:
            has_role, role = view.check_as_role_request(request=request)
            ticket = TicketManager.get_ticket(ticket_id=ticket_id)
        except exceptions.Error as exc:
            return view.exception_response(exc)

        comment = params['comment']
        user = request.user
        if has_role:
            if role == view.AS_ROLE_ADMIN and user.is_federal_admin():
                if ticket.assigned_to_id != request.user.id:
                    return view.exception_response(exceptions.AccessDenied(message=_('你不是此工单的指派处理人。')))
            else:
                return view.exception_response(exceptions.AccessDenied(message=_('你没有联邦管理员权限')))
        elif ticket.submitter_id != request.user.id:
            return view.exception_response(exceptions.AccessDenied(message=_('你没有此工单的访问权限')))

        if ticket.status == Ticket.Status.CLOSED.value:
            return view.exception_response(
                exceptions.ConflictTicketStatus(message=_('”已关闭“状态的工单不允许提交回复。')))

        try:
            folowup = TicketManager.create_followup_reply(
                ticket_id=ticket.id, user=user, comment=comment
            )
        except Exception as exc:
            return view.exception_response(exceptions.Error(message=_('添加工单回复错误。') + str(exc)))

        try:
            if user.id == ticket.submitter_id:
                receivers = [ticket.assigned_to.username] if ticket.assigned_to else []
            else:
                receivers = [ticket.username]

            if receivers:
                TicketEmailNotifier.new_followup_notice(receivers=receivers, ticket=ticket, folowup=folowup)
        except Exception as exc:
            pass

        return Response(data=ticket_serializers.FollowUpSerializer(instance=folowup).data)

    @staticmethod
    def _add_followup_validate_params(view, request):
        """
        :raises: Error
        """
        serializer = view.get_serializer(data=request.data)
        if not serializer.is_valid(raise_exception=False):
            s_errors = serializer.errors
            if 'comment' in s_errors:
                exc = exceptions.BadRequest(message=_('无效的回复。') + s_errors['comment'][0], code='InvalidComment')
            else:
                msg = serializer_error_msg(serializer.errors)
                exc = exceptions.BadRequest(message=msg)

            raise exc

        data = serializer.validated_data
        comment = data['comment']

        if not comment:
            raise exceptions.BadRequest(message=_('回复内容不能为空。'), code='InvalidComment')

        return data

    @staticmethod
    def list_followup(view: AsRoleGenericViewSet, request, kwargs):
        ticket_id = kwargs[view.lookup_field]

        try:
            has_role, role = view.check_as_role_request(request=request)
            ticket = TicketManager.get_ticket(ticket_id=ticket_id)
        except exceptions.Error as exc:
            return view.exception_response(exc)

        user = request.user
        if has_role:
            if role == view.AS_ROLE_ADMIN and user.is_federal_admin():
                pass
            else:
                return view.exception_response(exceptions.AccessDenied(message=_('你没有联邦管理员权限')))
        elif ticket.submitter_id != request.user.id:
            return view.exception_response(exceptions.AccessDenied(message=_('你没有此工单的访问权限')))

        queryset = TicketManager.get_ticket_followup_queryset(ticket_id=ticket.id, is_only_replay=not has_role)
        paginator = FollowUpMarkerCursorPagination()
        try:
            followups = paginator.paginate_queryset(queryset=queryset, request=request, view=view)
            serializer = ticket_serializers.FollowUpSerializer(followups, many=True)
            return paginator.get_paginated_response(data=serializer.data)
        except Exception as exc:
            return view.exception_response(exc)

    @staticmethod
    def take_ticket(view: AsRoleGenericViewSet, request, kwargs):
        """
        领取一个待处理的工单
        """
        ticket_id = kwargs[view.lookup_field]

        if not request.user.is_federal_admin():
            return view.exception_response(exceptions.AccessDenied(message=_('你没有联邦管理员权限')))

        try:
            ticket = TicketManager.get_ticket(ticket_id=ticket_id)
        except exceptions.Error as exc:
            return view.exception_response(exc)

        if ticket.assigned_to_id:
            return view.exception_response(
                exceptions.AccessDenied(message=_('工单已指派了处理人。')))

        if ticket.status not in [Ticket.Status.OPEN.value, Ticket.Status.PROGRESS.value]:
            return view.exception_response(
                exceptions.ConflictTicketStatus(message=_('只能领取“打开”和“处理中”的工单')))

        try:
            TicketManager.ticket_assigned_to_user(user=request.user, ticket=ticket, assigned_to=request.user)
        except Exception as exc:
            return view.exception_response(exc)

        return Response(data={})

    @staticmethod
    def ticket_assigned_to(view: AsRoleGenericViewSet, request, kwargs):
        ticket_id = kwargs[view.lookup_field]
        username = kwargs.get('username', '')

        try:
            ticket = TicketManager.get_ticket(ticket_id=ticket_id)
            if ticket.status == Ticket.Status.CLOSED.value:
                return view.exception_response(exceptions.ConflictTicketStatus(message=_('工单已关闭。')))

            if not request.user.is_federal_admin():
                return view.exception_response(
                    exceptions.AccessDenied(message=_('你没有此工单的分配权限。')))

            # UserNotExist
            assigned_to_user = get_user_by_name(username=username)
            if not assigned_to_user.is_federal_admin():
                return view.exception_response(
                    exceptions.ConflictError(message=_('工单只允许转交给联邦管理员。')))
        except exceptions.Error as exc:
            return view.exception_response(exc)

        if ticket.assigned_to_id == assigned_to_user.id:
            return Response(data={})

        try:
            TicketManager.ticket_assigned_to_user(
                user=request.user, ticket=ticket, assigned_to=assigned_to_user
            )
        except Exception as exc:
            return view.exception_response(exceptions.Error(message=_('更改工单处理人失败。') + str(exc)))

        return Response(data={})

    @staticmethod
    def add_ticket_rating(view: AsRoleGenericViewSet, request, kwargs):
        """
        提交工单评价
        """
        ticket_id = kwargs[view.lookup_field]
        user = request.user

        try:
            serializer = view.get_serializer(data=request.data)
            if not serializer.is_valid(raise_exception=False):
                s_errors = serializer.errors
                if 'comment' in s_errors:
                    exc = exceptions.BadRequest(message=_('无效的评论。') + s_errors['comment'][0], code='InvalidComment')
                elif 'score' in s_errors:
                    exc = exceptions.BadRequest(
                        message=_('无效评分，评分只允许1-5。') + s_errors['score'][0], code='InvalidScore')
                else:
                    msg = serializer_error_msg(serializer.errors)
                    exc = exceptions.BadRequest(message=msg)

                raise exc
        except exceptions.Error as exc:
            return view.exception_response(exc)

        data = serializer.validated_data
        comment = data['comment']
        score = data['score']

        try:
            ticket = TicketManager.get_ticket(ticket_id=ticket_id)
        except exceptions.Error as exc:
            return view.exception_response(exc)

        if ticket.submitter_id != user.id:
            return view.exception_response(exceptions.AccessDenied(message=_('你没有此工单的访问权限')))

        if ticket.status != Ticket.Status.CLOSED.value:
            return view.exception_response(
                exceptions.ConflictTicketStatus(message=_('只允许评价”已关闭“状态的工单。')))

        rat = TicketRating.objects.filter(ticket_id=ticket.id).first()
        if rat is not None:
            return view.exception_response(
                exceptions.TargetAlreadyExists(message=_('工单已评价。')))

        try:
            rating = TicketManager.create_ticket_rating(
                ticket=ticket, score=score, comment=comment, user=user
            )
        except Exception as exc:
            return view.exception_response(exceptions.Error(message=_('添加工单评价错误。') + str(exc)))

        return Response(data=ticket_serializers.TicketRatingSerializer(instance=rating).data)

    @staticmethod
    def query_ticket_rating(view: AsRoleGenericViewSet, request, kwargs):
        """
        提交工单评价

            * 登录用户都有权限查询
        """
        ticket_id = kwargs[view.lookup_field]
        rating = TicketRating.objects.filter(ticket_id=ticket_id).first()

        ratings = []
        if rating is not None:
            rat = ticket_serializers.TicketRatingSerializer(instance=rating).data
            ratings.append(rat)

        return Response(data={'ratings': ratings})


import inspect
from typing import Optional

from ..dispatcher import Dispatcher

class State:
    """
    State object
    """

    def __init__(self, state: Optional[str] = None, group_name: Optional[str] = None):
        self._state = state
        self._group_name = group_name
        self._group = None

    @property
    def group(self):
        if not self._group:
            raise RuntimeError('This state is not in any group.')
        return self._group

    def get_root(self):
        return self.group.get_root()

    @property
    def state(self):
        if self._state is None or self._state == '*':
            return self._state

        if self._group_name is None and self._group:
            group = self._group.__full_group_name__
        elif self._group_name:
            group = self._group_name
        else:
            group = '@'

        return f'{group}:{self._state}'

    def set_parent(self, group):
        if not issubclass(group, StatesGroup):
            raise ValueError('Group must be subclass of StatesGroup')
        self._group = group

    def __set_name__(self, owner, name):
        if self._state is None:
            self._state = name
        self.set_parent(owner)

    def __str__(self):
        return f"<State '{self.state or ''}'>"

    __repr__ = __str__

    async def set(self):
        state = Dispatcher.get_current().current_state()
        await state.set_state(self.state)

class StatesGroupMeta(type):
    def __new__(mcs, name, bases, namespace, **kwargs):
        cls = super(StatesGroupMeta, mcs).__new__(mcs, name, bases, namespace)

        states = []
        childs = []

        cls._group_name = name

        for name, prop in namespace.items():

            if isinstance(prop, State):
                states.append(prop)
            elif inspect.isclass(prop) and issubclass(prop, StatesGroup):
                childs.append(prop)
                prop._parent = cls

        cls._parent = None
        cls._childs = tuple(childs)
        cls._states = tuple(states)
        cls._state_names = tuple(state.state for state in states)

        return cls

    @property
    def __group_name__(cls) -> str:
        return cls._group_name

    @property
    def __full_group_name__(cls) -> str:
        if cls._parent:
            return '.'.join((cls._parent.__full_group_name__, cls._group_name))
        return cls._group_name

    @property
    def states(cls) -> tuple:
        return cls._states

    @property
    def childs(cls) -> tuple:
        return cls._childs

    @property
    def all_childs(cls):
        result = cls.childs
        for child in cls.childs:
            result += child.childs
        return result

    @property
    def all_states(cls):
        result = cls.states
        for group in cls.childs:
            result += group.all_states
        return result

    @property
    def all_states_names(cls):
        return tuple(state.state for state in cls.all_states)

    @property
    def states_names(cls) -> tuple:
        return tuple(state.state for state in cls.states)

    def get_root(cls):
        if cls._parent is None:
            return cls
        return cls._parent.get_root()

    def __contains__(cls, item):
        if isinstance(item, str):
            return item in cls.all_states_names
        if isinstance(item, State):
            return item in cls.all_states
        if isinstance(item, StatesGroup):
            return item in cls.all_childs
        return False

    def __str__(self):
        return f"<StatesGroup '{self.__full_group_name__}'>"

class StatesGroup(metaclass=StatesGroupMeta):
    @classmethod
    async def next(cls) -> str:
        state = Dispatcher.get_current().current_state()
        state_name = await state.get_state()

        try:
            next_step = cls.states_names.index(state_name) + 1
        except ValueError:
            next_step = 0

        try:
            next_state_name = cls.states[next_step].state
        except IndexError:
            next_state_name = None

        await state.set_state(next_state_name)
        return next_state_name

    @classmethod
    async def previous(cls) -> str:
        state = Dispatcher.get_current().current_state()
        state_name = await state.get_state()

        try:
            previous_step = cls.states_names.index(state_name) - 1
        except ValueError:
            previous_step = 0

        if previous_step < 0:
            previous_state_name = None
        else:
            previous_state_name = cls.states[previous_step].state

        await state.set_state(previous_state_name)
        return previous_state_name

    @classmethod
    async def first(cls) -> str:
        state = Dispatcher.get_current().current_state()
        first_step_name = cls.states_names[0]

        await state.set_state(first_step_name)
        return first_step_name

    @classmethod
    async def last(cls) -> str:
        state = Dispatcher.get_current().current_state()
        last_step_name = cls.states_names[-1]

        await state.set_state(last_step_name)
        return last_step_name

default_state = State()
any_state = State(state='*')


from __future__ import division
import cmath

def Euclidean(list1,list2):
    dist = 0
    for i in range(len(list1)):
        dist += (list1[i]-list2[i])**2
    return cmath.sqrt(dist).real

def Jaccard_like(list1,list2):
    molecular = 0
    denominator = 0
    for i in range(len(list1)):
        if list1[i] < list2[i]:
            molecular += list1[i]
            denominator += list2[i]
        else:
            molecular += list2[i]
            denominator += list1[i]

    if molecular==0 or denominator ==0:
        return 0
    else:
        e = molecular/denominator
        return e.real

def Consin(list1,list2):
    molecular = 0
    factor1 = 0
    factor2 = 0
    for i in range(len(list1)):
        molecular += list1[i]*list2[i]
        factor1 += list1[i]**2
        factor2 += list2[i]**2

    if molecular==0 or (factor1==0 and factor2==0):
        return 0
    else:
        denominator = cmath.sqrt(factor1)*cmath.sqrt(factor2)
        e = molecular/denominator
        return e.real


"""
1. range()
    syntax: range([start],stop, [increment])
2. Mutability (list), Immutability (Strings an
3. for loops within for loops (nested loops)
4. list of lists
    a. Indexing embedded lists common between string, list , tuple indexing
5. References and list mutability
6. Strings as iterables or sequences
7. Negative indices
8. Slicing
    x[[start] : [stop] ]
    x[[start] : [stop] : [increment]]
9. string functions
    lower(),upper(),capitalize(),title(), swapcase(), count(), strip(), lstrip(),
    rstrip(), find(), index(), replace(), split(), join()

[] -> list
() -> tuple
"", '' -> string
{} -> dictionary
"""
# x = [1, 2, 3, 4]
# print(type(x))

# x[0] = 10
# # x = [10, 2, 3, 4]

# x[-1]

# for i in range(7): # loops from 0 to 6
#     for j in range(1, i + 2):
#         print(j, end="")
#     print()

# for i in range(3):
#     for j in range(5):
#         print("i=", i, "j=", j)

#basic
# for i in range(7):
#     for j in range(1, i + 2):
#         print("#", end="")
#     print()

#python
# for i in range(7, 0):
#     print("#" * (i - 1))

# for i in range(7):
#     print("#" * (7 - i))

# for i in range(7):
#     print("#" * (7 - i), end="")
#     for j in range(1, i + 2):
#         print(j, end="")
#     print()

# for i in range(7):
#     print(" " * (7 - i), end="")
#     for j in range(1, i + 2):
#         print(j, end="")
#     for k in range(i, 0, -1):
#         print(k, end="")
#     print()

# xlist = [1, 2, 3]
# ylist = xlist #aliasing -> ylist is an alias of xlist
# xlist[0] = 35
# print(xlist, ylist)
# ylist[1] = 35
# print(xlist, ylist)
# ylist = []

# xlist = [1, 2, 3]
# ylist = xlist
# print(ylist is xlist)
# ylist[]
# print(ylist is xlist)

# xlist = [1, 2, 3]
# ylist = xlist
# print(ylist is xlist)
# ylist = xlist.copy()
# print(ylist is xlist)
# print(ylist)

# myStr = "Binus International"
# myStr[::-1] #reverse
# myStr[-1:len(myStr)-1:-1] #reverse

"""
functions
syntax: def <functionName> (<parameterlist>):
            <body>
1. void functions
2. non-void functions
"""
#declaration / definition
# def sayHi():
#     print("Hello")
#     print("My first user defined function")

# def greetUser(name):
#     sayHi()
#     print("Oops, you are", name)

# def getAge(age):    #non-void function
#     return age + 10
# #invocation
# # greetUser("Alysha")
# myName = input("Enter name: ")
# greetUser(myName)
# # print(type(greetUser("a")))
# myAge = int(input("Enter age: "))
# myNewAge = getAge(myAge)
# print(myNewAge)

#import functino from another file
#from myFunctions import *
#greetUser("Vincent")
#print("Your age: ", getAge(40))

"""
Create a function that accepts a parameter the number of lines to display in Pascals Triangle
"""
def generatePascalTriangle(numLines):
    for i in range(numLines):
        print(" " * (numLines - i), end="")
        for j in range(1, i + 2):
            print(j, end="")
        for k in range(i, 0, -1):
            print(k, end="")
        print()

# num = int(input("Enter number of lines: "))
# generatePascalTriangle(num)

"""
Function that returns the square of a number
"""
def square(num):
    return num*num

def main():
    num = int(input("Enter number of lines: "))
    generatePascalTriangle(num)

    s = square(num)
    print(s)

main()

Algorithm and Programming LEC COMP6047001/Week 4.py


import sys
from cnnModelBuilder.src.cnnModelBuilder import CNNModelBuilder
import sys
import logging
import numpy as np

class CNNModelPrediction:
  def __init__(self, cnn_config_file=None, batch_size=128):
    self.cnn_config_file = cnn_config_file
    self.batch_size = batch_size

    self.__loadCNNModel()

  def __loadCNNModel(self):
    self.model = CNNModelBuilder()

    try:
      self.model.loadJSONConfigFile(self.cnn_config_file)
    except FileNotFoundError as e:
      logging.error(("FileNotFoundError in CNNModelPrediction. CNN config file not found, please check both path and filename: %s" % e), exc_info=True)
      raise e

    try:
      self.model.loadModel()
    except FileNotFoundError as e:
      logging.error(("FileNotFoundError in CNNModelPrediction. CNN model file not found, please check both path and filename in configuration file: %s" % e), exc_info=True)
      raise e

  def runPrediction(self, x_batch=None):
    if x_batch is None:
        logging.warning("Warning: x_batch param cannot be 'None' for model prediction. Please check it!")
        return None

    return self.model.cnn_model.predict(np.array(x_batch).astype(np.float32), self.batch_size)


import collections
import itertools
from copy import copy, deepcopy
from math import sqrt
import sys
from collections import defaultdict, deque
from itertools import combinations, permutations
import heapq
import bisect
import math

dr, dc = [-1, 1, 0, 0], [0, 0, -1, 1]

input = sys.stdin.readline
INF = sys.maxsize

# ==========================================================

q1, q2, q3, q4 = ["R", "T"], ["C", "F"], ["J", "M"], ["A", "N"]

def solution(survey, choices):
    answer = ""

    dic = {("R", "T"): [0, 0], ("C", "F"): [0, 0], ("J", "M"): [0, 0], ("A", "N"): [0, 0]}

    def makeChoice(s, choice):
        a, b = s
        pointA = 0
        pointB = 0

        if choice == 1:
            pointA += 3
        elif choice == 2:
            pointA += 2
        elif choice == 3:
            pointA += 1
        elif choice == 4:
            pass
        elif choice == 5:
            pointB += 1
        elif choice == 6:
            pointB += 2
        else:
            pointB += 3

        if (a, b) in dic.keys():
            dic[(a, b)][0] += pointA
            dic[(a, b)][1] += pointB
        if (b, a) in dic.keys():
            dic[(b, a)][1] += pointA
            dic[(b, a)][0] += pointB

    for i, s in enumerate(survey):
        a, b = s

        makeChoice(s, choices[i])

    for d in dic:
        a, b = d

        if dic[(a, b)][0] < dic[(a, b)][1]:
            answer += b
        else:
            answer += a
    return answer

프로그래머스/lv1/118666. 성격 유형 검사하기/성격 유형 검사하기.py

성격 유형 검사하기.py


import os
from os import path
from pathlib import Path
import json
from google.cloud import translate_v2 as translate
import six

home = str(Path.home())
pron_fold = home+'/pronunciations'
cwd = os.getcwd()

def add_translation_to_local_dictionary(src_text, dest_text, src_lang, dest_lang):
	local_dict_file = src_lang+'_'+dest_lang+'.json'
	local_dict = {}
	if path.exists(cwd+'/local_dictionaries/'+local_dict_file):
		with open(cwd+'/local_dictionaries/'+local_dict_file) as json_file:
			local_dict = json.load(json_file)
	first_text = src_text
	second_text = dest_text
	if not first_text in local_dict:
		local_dict[first_text] = second_text
		my_json = json.dumps(local_dict, ensure_ascii=False, indent=1, sort_keys=True)
		f = open(cwd+'/local_dictionaries/'+local_dict_file,"w")
		f.write(my_json)
		f.close()

def get_translation_from_local_library(src_text, first_lang, second_lang):
	local_dict_file = first_lang+'_'+second_lang+'.json'
	dest_text = ''
	if path.exists(cwd+'/local_dictionaries/'+local_dict_file):
		with open(cwd+'/local_dictionaries/'+local_dict_file) as json_file:
			local_dict = json.load(json_file)
			if src_text in local_dict:
				dest_text = local_dict[src_text]

	return dest_text

def get_translation(src_text, first_lang, second_lang, should_print):
	dest_text = get_translation_from_local_library(src_text, first_lang, second_lang).replace(''', "'")
	if dest_text == '':
		dest_text = translate_text(second_lang, src_text).lower().replace(''', "'")
		if should_print:
			print('got from google', src_text,'=', dest_text)
	else:
		if should_print:
			print(' '*20+'got from local dict', src_text.strip(),'=', dest_text.strip())
	#UNCOMMENTTHIS IF NOT USING GOOGLE CLOUD TRANSLATE
	# if dest_text == '':
	# 	translation_attempt = 1
	# 	while translation_attempt < 15:
	# 		time.sleep(translation_attempt)
	# 		dest_text = translate_text(second_lang, src_text)
	# 		if src_text == dest_text or dest_text == '':
	# 			translation_attempt += translation_attempt
	# 		else:
	# 			translation_attempt = 16
	if dest_text != '' and dest_text != "None":
		add_translation_to_local_dictionary(src_text, dest_text, first_lang, second_lang)
		add_translation_to_local_dictionary(dest_text, src_text, second_lang, first_lang)
	return dest_text

def get_local_dictionary(first_lang, second_lang):
	langs = [first_lang, second_lang]
	aplhabetized_langs = langs.sort()
	swapped = True
	if langs == aplhabetized_langs:
		swapped = False
	local_dict_file = langs[0]+'_'+langs[1]+'.json'
	return local_dict_file, swapped

def translate_text(target, text):
	translate_client = translate.Client()
	if isinstance(text, six.binary_type):
		text = text.decode("utf-8")
	result = translate_client.translate(text, target_language=target)
	return(format(result["translatedText"]))


import discord
import json
from discord.ext import commands
from wordnik import *
import urbandictionary as urbdic

class Dictionary:
    def __init__(self, bot):
        self.bot = bot

    # Load API key
    with open('data/apikeys.json') as f:
        apiKeys = json.load(f)

    # Init wordnik objects
    wordnikKey = apiKeys['wordnik']
    WordClient = swagger.ApiClient(wordnikKey, 'http://api.wordnik.com/v4')

    # Returns the most common definition of a word
    @commands.command(name='define', aliases=['d'])
    async def wordnik_define(self, ctx, *, word):
        """ Provides the definition of a word """
        wordApi = WordApi.WordApi(Dictionary.WordClient)

        parts_of_speech = {'noun': 'n.', 'verb': 'v.', 'adjective': 'adj.', 'adverb': 'adv.',
                           'interjection': 'interj.', 'conjunction': 'conj.', 'preposition': 'prep.', 'pronoun': 'pron.'}

        result = wordApi.getDefinitions(word)

        if not result:
            return await ctx.send("Sorry, couldn't find that one.")

        final_result = result[0]

        for pos in parts_of_speech:
            if pos in final_result.partOfSpeech.split('-'):
                word_pos = parts_of_speech[pos]
                break
            else:
                word_pos = final_result.partOfSpeech

        await ctx.send('{} _{}_ `{}`'.format(word.title(), word_pos, final_result.text))

    # Urban dictionary
    @commands.command(name='ud')
    async def get_urban_def(self, ctx, *, word):
        """ Consult the world's leading dictionary """
        result = urbdic.define(word)

        if not result:
            return await ctx.send("Sorry, couldn't find that one.")

        await ctx.send('{}: `{}`'.format(word.title(), result[0].definition))

def setup(bot):
    bot.add_cog(Dictionary(bot))


class Solution:
    def lengthOfLastWord(self, s: str) -> int:
        isWord = False
        index = len(s) - 1
        length = 0
        while index >= 0:
            if not isWord and s[index] != " ":
                isWord = True
            if isWord:
                if s[index] != " ":
                    length += 1
                else:
                    return length
            index -= 1
        return length

if __name__ == '__main__':
    s = "this is leet code"
    res = Solution().lengthOfLastWord(s)
    print(res)


"""
After a migration has run, this can be used to publish all open revision for migrated collections.

$ aws batch submit-job --job-name publish-revisions \
  \ --job-queue <your_job_queue_ARN>
  \ --job-definition <your_job_definition_ARN>

"""
import logging
import os
from typing import Dict, List

from backend.layers.business.business import BusinessLogic
from backend.layers.business.entities import CollectionQueryFilter
from backend.layers.common.entities import (
    CollectionVersionWithDatasets,
    DatasetProcessingStatus,
)
from backend.layers.persistence.persistence import DatabaseProvider
from backend.layers.processing.logger import configure_logging
from backend.layers.processing.process_logic import ProcessingLogic
from backend.layers.thirdparty.s3_provider import S3Provider
from backend.layers.thirdparty.schema_validator_provider import SchemaValidatorProvider
from backend.layers.thirdparty.uri_provider import UriProvider

configure_logging(level=logging.INFO)

class PublishRevisions(ProcessingLogic):
    def __init__(self, business_logic: BusinessLogic) -> None:
        super().__init__()
        self.business_logic = business_logic
        self.s3_provider = business_logic.s3_provider
        self.schema_validator = SchemaValidatorProvider()
        self.artifact_bucket = os.environ.get("ARTIFACT_BUCKET", "test-bucket")
        self.schema_version = self.schema_validator.get_current_schema_version()

    def check_datasets(self, collection_version: CollectionVersionWithDatasets) -> List[Dict]:
        """Check that all datasets have been migrated and are in a success state"""
        errors = []
        for dataset in collection_version.datasets:
            dataset_id = dataset.dataset_id.id
            dataset_version_id = dataset.version_id.id
            if not self.check_dataset_is_latest_schema_version(dataset):
                errors.append(
                    {
                        "message": "Dataset is not the latest schema version.",
                        "dataset_version_id": dataset_version_id,
                        "dataset_id": dataset_id,
                    }
                )
            elif dataset.status.processing_status != DatasetProcessingStatus.SUCCESS:
                errors.append(
                    {
                        "message": dataset.status.validation_message,
                        "dataset_status": dataset.status.to_dict(),
                        "dataset_version_id": dataset_version_id,
                        "dataset_id": dataset_id,
                    }
                )
        return errors

    def run(self):
        for collection_version in self.business_logic.get_collections(CollectionQueryFilter(is_published=False)):
            if collection_version.is_unpublished_version():
                _collection_version = self.business_logic.get_collection_version(collection_version.version_id)
                errors = self.check_datasets(_collection_version)
                if errors:
                    self.logger.error(
                        "Unable to publish collection version.",
                        extra={
                            "collection_id": collection_version.collection_id.id,
                            "collection_version_id": collection_version.version_id.id,
                            "errors": errors,
                        },
                    )
                else:
                    self.logger.info(
                        "Publishing collection version.",
                        extra={"collection_version_id": collection_version.version_id.id},
                    )
                    try:
                        self.business_logic.publish_collection_version(collection_version.version_id)
                    except Exception:
                        logging.exception("Failed to publish collection version.")

if __name__ == "__main__":
    business_logic = BusinessLogic(
        DatabaseProvider(),
        None,  # Not required - decide if we should pass for safety
        None,  # Not required - decide if we should pass for safety
        S3Provider(),
        UriProvider(),
    )

    PublishRevisions(business_logic).run()


import pytest

def validate_card(card_code: list) -> bool:
    code = card_code
    for n in range(len(card_code)):
        if n % 2 == 0:
            multiplicator = 2
        else:
            multiplicator = 1

        if code[n] * multiplicator < 10:
            code[n] *= multiplicator
        else:
            temp = code[n] * multiplicator
            temp = str(temp)
            code[n] = int(temp[0]) + int(temp[1])

    if sum(code) % 10 == 0:
        return True
    else:
        return False

def test_validate_card():
    # given
    card = [3, 3, 7, 9, 5, 1, 3, 5, 6, 1, 1, 0, 8, 7, 9, 5]

    # when
    result = validate_card(card)

    # then
    assert result


from setuptools import setup, find_packages

with open('README.md', 'r') as f:
    long_description = f.read()

setup(
    name='python-fastrand',
    version='1.1',
    packages=find_packages(),
    author='Mukundan Senthil',
    author_email='mukundan314@gmail.com',
    description='Pure Python clone of fastrand',
    long_description=long_description,
    long_description_content_type='text/markdown',
    license='MIT',
    keywords='random pcg',
    classifiers=[
        'Programming Language :: Python :: 2',
        'Programming Language :: Python :: 3',
        'Intended Audience :: Developers',
        'License :: OSI Approved :: MIT License',
        'Topic :: Software Development :: Libraries',
    ],
    url='https://github.com/mukundan314/python-fastrand.git')


""" TensorMONK :: layers :: Detail-Preserving Pooling """

__all__ = ["DetailPooling", ]

import torch
import torch.nn as nn
import torch.nn.functional as F

class DetailPooling(nn.Module):
    """ Implemented - https://arxiv.org/pdf/1804.04076.pdf """
    def __init__(self, tensor_size, asymmetric=False, lite=True,
                 *args, **kwargs):
        super(DetailPooling, self).__init__()

        # Notes: A user study in [31] showed that on average people preferred
        # DPID (0.5 <= lambda <= 1) over all considered downscaling techniques.
        self._lambda = nn.Parameter(torch.Tensor(1))
        self._lambda.data.mul_(0).add_(.6)

        self._alpha = nn.Parameter(torch.Tensor(1))
        self._alpha.data.mul_(0).add_(.1)

        self.asymmetric = asymmetric
        self.lite = lite

        if self.lite:
            # non trainable
            self.weight = torch.FloatTensor([[[[1, 2, 1]]]])
            self.weight = self.weight.expand((tensor_size[1], 1, 1, 3))
        else:
            # trainable
            self.weight = nn.Parameter(torch.rand(*(tensor_size[1], 1, 3, 3)))
            self.weight = nn.init.xavier_normal_(self.weight, gain=0.01)

        # Computing tensor_size
        self.tensor_size = tensor_size[:2] + \
            F.avg_pool2d(torch.rand(1, 1, tensor_size[2],
                                    tensor_size[3]), (2, 2)).size()[2:]

    def forward(self, tensor):

        # non-negative alpha and lambda - requires update
        self._alpha.data.pow_(2).pow_(.5)
        self._lambda.data.pow_(2).pow_(.5)

        # equation 2 - linearly downscaled image
        padded_tensor = F.pad(tensor, (1, 1, 1, 1), mode="replicate")
        if self.lite:
            if tensor.is_cuda and not self.weight.is_cuda:
                self.weight = self.weight.cuda()
            equation2 = F.conv2d(F.conv2d(padded_tensor, self.weight,
                                          groups=tensor.size(1)),
                                 self.weight.transpose(2, 3),
                                 groups=tensor.size(1)).div(16)
        else:
            equation2 = F.conv2d(padded_tensor, self.weight,
                                 groups=tensor.size(1))

        eps = 1e-6
        if self.asymmetric:
            # equation 6 -  asymmetric variant
            equation56 = equation2.mul(-1).add(tensor).clamp(0).pow(2)
            equation56 = equation56.add(eps**2).pow(2).pow(self._lambda)
        else:
            # equation 5 -  charbonnier penalty
            equation56 = equation2.mul(-1).add(tensor).pow(2).add(eps**2)
            equation56 = equation56.pow(2).pow(self._lambda)

        # equation 4 - adding alpha - trainable parameter
        equation4 = equation56.add(self._alpha)
        # equation 7 - normalizing
        equation7 = equation4.div(F.avg_pool2d(F.pad(equation4, (0, 1, 0, 1),
                                                     mode="replicate"),
                                               (2, 2), (1, 1)).add(1e-8))
        # equation 8 - final DPP
        equation8 = F.avg_pool2d(tensor.mul(equation7), (2, 2))
        return equation8

# tensor_size = (3,3,10,10)
# x = torch.rand(*tensor_size)
# test = DetailPooling(tensor_size)
# test(x).size()
# import numpy as np
# from PIL import Image as ImPIL
# image = ImPIL.open("../data/test.jpeg")
# tensor = np.array(image).astype(np.float32).transpose(2, 0, 1)[np.newaxis]
# tensor = torch.from_numpy(tensor / 255.)
# test = DetailPooling((1, 3, 256, 256), True, False)
# ImPIL.fromarray((test(tensor)).clamp(0, 1).mul(255.)[0,].data.numpy()
#                 .transpose(1, 2, 0).astype(np.uint8))


import logging

BASE_DIRECTORY_MISSING = "Base directory {base_directory} does not exist."

def raise_required_keys_missing(keys: list, logger: logging.Logger = None):
    """
    Raise an error if the required keys are missing.
    """
    msg = "The following required keys are missing from the dataset description: {}".format(
        keys
    )
    if logger is not None:
        logger.error(msg)
    raise ValueError(msg)

def warn_recommended_keys_missing(keys: list, logger: logging.Logger = None):
    """
    Warn if the recommended keys are missing.
    """
    msg = "The following recommended keys are missing from the dataset description: {}".format(
        keys
    )
    if logger is None:
        logging.warning(msg)
    else:
        logger.warning(msg)

def notify_optional_keys_missing(keys: list, logger: logging.Logger = None):
    """
    Warn if the recommended keys are missing.
    """
    msg = "The following optional keys are missing from the dataset description: {}".format(
        keys
    )
    if logger is None:
        logging.debug(msg)
    else:
        logger.debug(msg)

DATASET_DESCRIPTION_MESSAGES = {
    "required": raise_required_keys_missing,
    "recommended": warn_recommended_keys_missing,
    "optional": notify_optional_keys_missing,
}


file = open("./input", "r")
input = file.read()

def overlap(assignmentPairs: str):
	assignments = assignmentPairs.split(',')
	assignmentOne = assignments[0].split('-')
	assignmentTwo = assignments[1].split('-')
	assignmentOneArray = range(int(assignmentOne[0]), int(assignmentOne[1]) + 1)
	assignmentTwoArray = range(int(assignmentTwo[0]), int(assignmentTwo[1]) + 1)
	if int(assignmentTwo[0]) in assignmentOneArray:
		return True
	elif int(assignmentTwo[1]) in assignmentOneArray:
		return True
	elif int(assignmentOne[0]) in assignmentTwoArray:
		return True
	elif int(assignmentOne[1]) in assignmentTwoArray:
		return True
	return False

def solution(input: str):
	fullyContainedAssignmentPairs = []
	assignmentPairsList = input.split('\n')
	for assignmentPairs in assignmentPairsList:
		if overlap(assignmentPairs):
			fullyContainedAssignmentPairs.append(assignmentPairs)
	return fullyContainedAssignmentPairs

print("In how many assignment pairs do the ranges overlap?")
print(len(solution(input)))


# -*- coding: utf-8 -*-
"""
Created on Thu Oct 02 16:19:21 2014

@author: Juda
"""

import socket
import record
import random

class server:
    '''
    network communication by using socket
    '''
    def __init__(self,log):
        host=socket.gethostbyname(socket.gethostname())
        port=12345
        self.log=log
        self.spy=socket.socket()
        self.spy.bind((host,port))
        self.spy.listen(2)

        self.log.logging("wating to connect ...",'SHOWALL')
        self.log.logging("The PC's host is %s"%host,'SHOWALL')

        self.AI=[None,None]
        self.AIname=[None,None]

        #determine which player is first player
        first=0
        if random.random()<0.5:
            first=1

        self.AI[first],addr=self.spy.accept()
        self.log.logging("%s connected"%addr[0],'SHOWALL')
        self.AI[1-first],addr=self.spy.accept()
        self.log.logging("%s connected"%addr[0],'SHOWALL')

        self.AI[0].settimeout(2)
        self.AI[1].settimeout(2)

        self.send(self.AI[0],'0')
        self.AIname[0]=self.recieve(self.AI[0]).strip()
        self.send(self.AI[1],'1')
        self.AIname[1]=self.recieve(self.AI[1]).strip()
        self.log.logging("%s is the first player"%self.AIname[0],'SHOWALL')
        self.log.logging("%s is the second player"%self.AIname[1],'SHOWALL')

    def send(self,client,message):
        client.send('%s\n'%message)

    def recieve(self,client):
        res=''
        while True:
            ch=client.recv(1)
            res+=ch
            if ch=='\n':
                break
        return res.strip()

    def __del__(self):
        self.AI[0].close()
        self.AI[1].close()


import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.utils.data import DataLoader
import torchvision
from tqdm import tqdm
from torch.utils.tensorboard import SummaryWriter
import warnings
warnings.simplefilter("ignore", UserWarning)
torch.manual_seed(100)

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

class AN(nn.Module):
    def __init__(self, input_size, out_feature):
        super(AN, self).__init__()
        self.fc1 = nn.Linear(in_features=input_size, out_features=128)
        self.fc2 = nn.Linear(in_features=128, out_features=out_feature)
        self.flatten = nn.Flatten()
        self.sigmoid = nn.Sigmoid()
        self.leakyrelu = nn.LeakyReLU(0.1)

    def forward(self, x):
        x = self.flatten(x)
        x = F.relu(self.fc1(x))
        x = self.fc2(x)
        return x

class MSELoss(nn.Module):
    def __init__(self, feature, num_classes):
        super(MSELoss, self).__init__()
        self.fc = nn.Linear(in_features=feature, out_features=num_classes)

    def forward(self, X, ground_truth):
        # in_feature = 4
        # ground_truth = 10
        X = self.fc(X)
        ground_truth_ohe = torch.zeros(X.shape[0], 10).to(device)
        ground_truth_ohe[range(X.shape[0]), ground_truth] = 1
        loss = torch.sqrt(torch.sum((X - ground_truth_ohe) ** 2, dim=1))
        loss = loss.mean()
        return loss

class LossWrapper(nn.Module):
    def __init__(self):
        super(LossWrapper, self).__init__()
        num_feature = 1
        self.feature = AN(input_size=28*28, out_feature=num_feature)
        self.loss = MSELoss(feature=num_feature, num_classes=10)

    def forward(self, X, label, embed=False):
        X = self.feature(X)  # X.shape: num_feature = 3
        if embed:
            return X
        loss = self.loss(X, label)
        return loss

batch_size = 64
learning_rate = 3e-4
epochs = 10

train_dataset = torchvision.datasets.MNIST(root="data", train=True, transform=torchvision.transforms.ToTensor(), download=True)
train_dataloader = DataLoader(dataset=train_dataset, batch_size=batch_size, shuffle=True)
test_dataset = torchvision.datasets.MNIST(root="data", train=False, transform=torchvision.transforms.ToTensor(), download=True)
test_dataloader = DataLoader(dataset=test_dataset, batch_size=batch_size, shuffle=True)

model = LossWrapper().to(device)
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)

for epoch in range(epochs):
    loop = tqdm(enumerate(train_dataloader))
    for batch_idx, (X, label) in loop:
        X, label = X.to(device), label.to(device)

        loss = model(X, label)

        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        loop.set_description(f"Epochs: {epoch + 1} / {epochs}")
        loop.set_postfix(loss=loss.item())

for X, label in test_dataloader:
    X, label = X.to(device), label.to(device)

    inference = model(X, None, embed=True)
    print(inference)
    print(label)
    break


import os.path

import pandas as pd
import xgboost as xgb
from sklearn.externals import joblib
from xgboost import Booster

from analyzer_result import get_df_prediction
from dataset_preprocessing import replace_na

class datasetTester:

    @classmethod
    def run(cls, task: str, test_path: str, algorithm_name: str, model_path: str, output_path: str, analyzer_path: str,
            description: str=None):
        test = pd.read_csv(test_path, dtype=str)
        algorithm_name = algorithm_name.lower()
        if algorithm_name in ['adaboost', 'gausnb', 'decisiontree', 'gradientboost', 'logregression', 'linear_sgd',
                              'xgboost']:
            test = cls.test_dataset(test, algorithm_name, model_path, output_path)
        else:
            raise BaseException("Model {}  does not support .\n".format(algorithm_name))
        if task == 'Tester':
            if not description:
                description = model_path.split('/')[-1]
            df_statistic = get_df_prediction(test, description=description)
            df_statistic.to_csv(analyzer_path, index=False)
            compare_path = output_path.rsplit('/', maxsplit=1)[0] + "/compare-reslults.csv"
            if os.path.exists(compare_path):
                df_comapare = pd.read_csv(compare_path)
                df_comapare = pd.concat([df_comapare, df_statistic], ignore_index=False)
            else:
                df_comapare = df_statistic
            df_comapare.to_csv(compare_path, index=False)
        else:
            cls.show_single_order_info(test)

    @classmethod
    def get_model(cls, algorithm_name: str, model_path: str):
        if algorithm_name == 'xgboost':
            model = xgb.XGBClassifier()
            booster = Booster()
            booster.load_model(model_path)
            model._Booster = booster
        else:
            model = joblib.load(model_path)
        return model

    @classmethod
    def test_dataset(cls, test: pd.DataFrame, algorithm_name: str, model_path: str, output_path: str) -> pd.DataFrame:
        test = test.copy()
        test_modified = test.apply(pd.to_numeric, errors="coerce")
        drop_columns = ['status']
        test_modified = test_modified.drop(drop_columns, axis=1, errors="ignore")
        if algorithm_name != 'xgboost':
            test_modified = replace_na(test_modified)
        test_matrix = test_modified.as_matrix()
        loaded_model = cls.get_model(algorithm_name, model_path)
        test_pred = loaded_model.predict_proba(test_matrix)
        test["probability"] = test_pred[:, 1]
        test.to_csv(output_path, index=False, quoting=1)
        return test

    @classmethod
    def set_threshold(cls, threshold: float):
        cls.threshold = threshold

    @classmethod
    def show_single_order_info(cls, test: pd.DataFrame):
        print("Order probability = ", test.probability.values[0])
        if cls.threshold:
            prediction_status = 1 if test.probability.values[0] >= float(cls.threshold) else 0
            print("Prediction status = ", prediction_status, '\n')


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

import math

class model_flow:  # flow model

    def __init__(self, string_eas_p1='', string_eas_p2='', string_eas_rk=''):
        self.string_eas_rk = string_eas_rk
        self.string_eas_p1 = string_eas_p1
        self.string_eas_p2 = string_eas_p2
        self.eas_rk = 0.0
        self.eas_p1 = 0.0
        self.eas_p2 = 0.0
        self.density = 1000.0

        self.current_f = 0.0
        self.kv = 130.0  # максимальная пропускная способность запорного устройства, м3/ч

    def get_current_f(self, k=1):
        eas_rk = self.eas_rk
        eas_p1 = self.eas_p1
        eas_p2 = self.eas_p2
        kv = self.kv
        density = self.density / 1000
        maximum_f = kv * self.density / 3600

        if eas_p1 - eas_p2 >= 0.0:
            f = k * (eas_rk * kv / 100) * math.sqrt(density * (eas_p1 - eas_p2))
            if f >= maximum_f:
                self.current_f = maximum_f
            else:
                self.current_f = f
            return self.current_f
        else:
            return 0.0


from smart_plan import utils
from smart_plan.function import Function

class Solver:

    def __init__(self, functions, uids=None, relations=None):
        self.functions = functions
        linear_paths = utils.get_all_linear_paths(functions)
        self.uids = uids
        if self.uids is None:
            self.uids = utils.get_full_nicoleta_assumption_uids(linear_paths)
        self.relations = relations
        if self.relations is None:
            self.relations = sorted(utils.get_all_relations(functions))
        self.fst = utils.get_transducer_parser(functions)
        self.prev_cfg = None
        self.prev_relation = None

    def solve(self, query_relation, max_length=-1):
        if query_relation not in self.relations:
            return None
        if self.prev_relation == query_relation:
            cfg = self.prev_cfg
        else:
            query = Function()
            query.add_atom(query_relation, "x", "y")
            deter = utils.get_dfa_from_functions(self.functions, query_relation)
            cfg = query.get_longest_query_grammar(self.relations, self.uids)
            cfg = cfg.intersection(deter)
            self.prev_relation = query_relation
            self.prev_cfg = cfg
        if not cfg.is_empty():
            for word in cfg.get_words(max_length=max_length):
                return utils.get_translation(self.fst, word)
            raise ExplorationNotDeepEnough("The depth " + str(max_length) +
                                           " given was not high enough.")
        return None

class ExplorationNotDeepEnough(Exception):
    pass


from __future__ import print_function
import sys
import os
import argparse
import torch
import torch.nn as nn
import torch.backends.cudnn as cudnn
import torchvision.transforms as transforms
from torch.autograd import Variable
from data import WIDERFace_ROOT , WIDERFace_CLASSES as labelmap
from PIL import Image
from data import WIDERFaceDetection, WIDERFaceAnnotationTransform, WIDERFace_CLASSES, WIDERFace_ROOT, BaseTransform , TestBaseTransform
from data import *
import torch.utils.data as data
from light_face_ssd import build_ssd
import pdb
import numpy as np
import cv2
import math
import matplotlib.pyplot as plt
import time
from layers.box_utils import nms
import torchvision
#from torchscope import scope

plt.switch_backend('agg')

parser = argparse.ArgumentParser(description='Single Shot MultiBox Detection')
parser.add_argument('--trained_model', default='weights/light_DSFD.pth',
                    type=str, help='Trained state_dict file path to open')
#parser.add_argument('--save_folder', default='eval_tools/WIDERFace_SSD_F_RES152_FPN_MIO_CPM_PA0.70.3_DAS_Anchor1.5_IOU0.4_DeepClsRelu_6W_16bs_pyramidtest_testset/', type=str,
#                    help='Dir to save results')
parser.add_argument('--visual_threshold', default=0.01, type=float,
                    help='Final confidence threshold')
parser.add_argument('--cuda', default=False, type=bool,
                    help='Use cuda to train model')
parser.add_argument('--widerface_root', default=WIDERFace_ROOT, help='Location of VOC root directory')
args = parser.parse_args()

if args.cuda and torch.cuda.is_available():
    torch.set_default_tensor_type('torch.cuda.FloatTensor')
else:
    torch.set_default_tensor_type('torch.FloatTensor')
#if not os.path.exists(args.save_folder):
#    os.mkdir(args.save_folder)

def detect_face(image, shrink):
    x = image
    if shrink != 1:
        x = cv2.resize(image, None, None, fx=shrink, fy=shrink, interpolation=cv2.INTER_LINEAR)
    print('shrink:{}'.format(shrink))
    width = x.shape[1]
    height = x.shape[0]
    print (width , height)
    x = x.astype(np.float32)
    x -= np.array([104, 117, 123],dtype=np.float32)

    x = torch.from_numpy(x).permute(2, 0, 1)
    x = x.unsqueeze(0)
    if args.cuda:
        x = Variable(x.cuda(), volatile=True)
    else:
        #with torch.no_grad():
        #    x = Variable(x)
        x = Variable(x, volatile=True)

    #net.priorbox = PriorBoxLayer(width,height)
    #model = torchvision.models.resnet18(pretrained=True)
    time0 = time.time()
    #model(x)
    #time01 = time.time()
    #print ( time01 - time0)
    y = net(x)
    time1 = time.time()
    print ( "infer time: %.4f " % (time1-time0) )
    detections = y.data
    scale = torch.Tensor([width, height, width, height])

    boxes=[]
    scores = []
    for i in range(detections.size(1)):
        j = 0
        while detections[0,i,j,0] >= 0.01:
            score = detections[0,i,j,0]
            pt = (detections[0, i, j, 1:]*scale).cpu().numpy()
            boxes.append([pt[0],pt[1],pt[2],pt[3]])
            scores.append(score)
            j += 1
            if j >= detections.size(2):
                break

    det_conf = np.array(scores)
    boxes = np.array(boxes)

    if boxes.shape[0] == 0:
        return np.array([[0,0,0,0,0.001]])

    det_xmin = boxes[:,0] / shrink
    det_ymin = boxes[:,1] / shrink
    det_xmax = boxes[:,2] / shrink
    det_ymax = boxes[:,3] / shrink
    det = np.column_stack((det_xmin, det_ymin, det_xmax, det_ymax, det_conf))

    keep_index = np.where(det[:, 4] >= 0)[0]
    det = det[keep_index, :]
    return det

# load net
cfg = widerface_640
num_classes = len(WIDERFace_CLASSES) + 1 # +1 background
net = build_ssd('test', cfg['min_dim'], num_classes) # initialize SSD
#net = nn.DataParallel(net)
net.load_state_dict(torch.load(args.trained_model))
if args.cuda:
    net.cuda()
net.eval()
print('Finished loading model!')

#scope( net, input_size=( 3, 720, 1280) , batch_size=1 , device='cpu')

path = './data/yuebing.jpg'
image = cv2.imread(path, cv2.IMREAD_COLOR)
image = cv2.resize(image, (720, 1280), interpolation=cv2.INTER_LINEAR)
#(720,1280)
shrink=1
time1 = time.time()
for i in range(100):
  det = detect_face(image, shrink)  # origin test
time2 = time.time()
print( (time2-time1)/100 )


import os
import pytest
import fparser
from fparser import api as fpapi
from psyclone.dynamo0p3 import (DynKernMetadata, LFRicMeshProperties,
                                MeshProperty)
from psyclone.errors import InternalError
from psyclone.f2pygen import ModuleGen
from psyclone.parse.algorithm import parse
from psyclone.parse.utils import ParseError
from psyclone.psyGen import PSyFactory, Kern
from psyclone.tests.lfric_build import LFRicBuild

# Constants
BASE_PATH = os.path.join(
    os.path.dirname(os.path.dirname(os.path.dirname(
        os.path.abspath(__file__)))),
    "test_files", "dynamo0p3")
TEST_API = "dynamo0.3"

MESH_PROPS_MDATA = '''
module testkern_mesh_mod
  type, extends(kernel_type) :: testkern_mesh_type
    type(arg_type), dimension(2) :: meta_args =      &
        (/ arg_type(gh_field, gh_real, gh_read, w1), &
           arg_type(gh_field, gh_real, gh_inc,  w0) /)
    type(mesh_data_type), dimension(1) :: meta_mesh = &
        (/ mesh_data_type(adjacent_face) /)
     integer :: operates_on = cell_column
   contains
     procedure, nopass :: code => testkern_mesh_code
  end type testkern_mesh_type
contains
  subroutine testkern_mesh_code(a, b)
  end subroutine testkern_mesh_code
end module testkern_mesh_mod
'''

# Tests for parsing the metadata

def test_mdata_parse():
    ''' Check that we get the correct list of mesh properties. '''
    fparser.logging.disable(fparser.logging.CRITICAL)
    code = MESH_PROPS_MDATA
    ast = fpapi.parse(code, ignore_comments=False)
    name = "testkern_mesh_type"
    dkm = DynKernMetadata(ast, name=name)
    assert dkm.mesh.properties == [MeshProperty.ADJACENT_FACE]

@pytest.mark.parametrize("property_name", ["not_a_property", "ncell_2d"])
def test_mdata_invalid_property(property_name):
    ''' Check that we raise the expected error if an unrecognised mesh
    property is requested. Also test with a value that *is* a valid mesh
    property but is not supported in kernel metadata. '''
    code = MESH_PROPS_MDATA.replace("adjacent_face", property_name)
    ast = fpapi.parse(code, ignore_comments=False)
    name = "testkern_mesh_type"
    with pytest.raises(ParseError) as err:
        DynKernMetadata(ast, name=name)
    assert (f"in metadata: '{property_name}'. Supported values are: "
            f"['ADJACENT_FACE'" in str(err.value))

def test_mdata_wrong_arg_count():
    ''' Check that we raise the expected error if the wrong dimension value
    is specified for the mesh_data_type array. '''
    code = MESH_PROPS_MDATA.replace("mesh_data_type), dimension(1)",
                                    "mesh_data_type), dimension(4)")
    ast = fpapi.parse(code, ignore_comments=False)
    name = "testkern_mesh_type"
    with pytest.raises(ParseError) as err:
        DynKernMetadata(ast, name=name)
    assert ("'meta_mesh' metadata, the number of items in the array "
            "constructor (1) does not match the extent of the array (4)"
            in str(err.value))

def test_mdata_wrong_name():
    ''' Check that we raise the expected error if the array holding properties
    of the mesh is given the wrong name. '''
    code = MESH_PROPS_MDATA.replace("meta_mesh =", "meta_meshes =")
    ast = fpapi.parse(code, ignore_comments=False)
    name = "testkern_mesh_type"
    with pytest.raises(ParseError) as err:
        DynKernMetadata(ast, name=name)
    assert ("No variable named 'meta_mesh' found in the metadata for"
            in str(err.value))

def test_mdata_wrong_type_var():
    ''' Check that we raise the expected error if the array holding properties
    of the mesh contains an item of the wrong type. '''
    code = MESH_PROPS_MDATA.replace(
        "mesh_data_type(adjacent_face",
        "ref_element_data_type(adjacent_face")
    ast = fpapi.parse(code, ignore_comments=False)
    name = "testkern_mesh_type"
    with pytest.raises(ParseError) as err:
        DynKernMetadata(ast, name=name)
    assert ("'meta_mesh' metadata must consist of an array of "
            "structure constructors, all of type 'mesh_data_type'"
            " but found: ['ref_element_data_type']" in str(err.value))

def test_mdata_duplicate_var():
    ''' Check that we raise the expected error if the array holding properties
    of the mesh contains a duplicate item. '''
    code = MESH_PROPS_MDATA.replace("mesh_data_type), dimension(1)",
                                    "mesh_data_type), dimension(2)")
    code = code.replace("adjacent_face) ",
                        "adjacent_face), mesh_data_type(adjacent_face) ")

    ast = fpapi.parse(code, ignore_comments=False)
    name = "testkern_mesh_type"
    with pytest.raises(ParseError) as err:
        DynKernMetadata(ast, name=name)
    assert ("Duplicate mesh property found: "
            "'MeshProperty.ADJACENT_FACE'." in str(err.value))

def test_mesh_properties():
    ''' Tests the various checks in the methods of the LFRicMeshProperties
    class. '''
    _, invoke_info = parse(
        os.path.join(BASE_PATH, "24.1_mesh_prop_invoke.f90"),
        api=TEST_API)
    psy = PSyFactory(TEST_API, distributed_memory=False).create(invoke_info)
    invoke = psy.invokes.invoke_list[0]
    # Check that the kern_args() and _stub_declarations() methods raise the
    # expected error if the LFRicMeshProperties class has been created for
    # an Invoke.
    with pytest.raises(InternalError) as err:
        invoke.mesh_properties.kern_args()
    assert ("only be called when LFRicMeshProperties has been instantiated "
            "for a kernel" in str(err.value))
    with pytest.raises(InternalError) as err:
        invoke.mesh_properties._stub_declarations(None)
    assert ("cannot be called because LFRicMeshProperties has been "
            "instantiated for an invoke and not a kernel" in str(err.value))
    # Break the list of mesh properties
    invoke.mesh_properties._properties.append("not-a-property")
    with pytest.raises(InternalError) as err:
        invoke.mesh_properties._invoke_declarations(ModuleGen("test_mod"))
    assert ("Found unsupported mesh property 'not-a-property' when "
            "generating invoke declarations. Only " in str(err.value))
    with pytest.raises(InternalError) as err:
        invoke.mesh_properties.initialise(ModuleGen("test_mod"))
    assert ("Found unsupported mesh property 'not-a-property' when generating"
            " initialisation code" in str(err.value))
    sched = invoke.schedule
    # Get hold of the Kernel object
    kernel = sched.walk(Kern)[0]
    # Create an LFRicMeshProperties object just for this kernel
    mesh_props = LFRicMeshProperties(kernel)
    args = mesh_props.kern_args()
    # Check correct operation
    assert args == ["nfaces_re_h", "adjacent_face(:,cell)"]
    # Break the list of mesh properties
    mesh_props._properties.append("not-a-property")
    with pytest.raises(InternalError) as err:
        mesh_props.kern_args()
    assert ("found unsupported mesh property 'not-a-property' when "
            "generating arguments for kernel 'testkern_mesh_prop_code'. "
            "Only members of the MeshProperty Enum are"
            in str(err.value))
    with pytest.raises(InternalError) as err:
        mesh_props._invoke_declarations(ModuleGen("test_mod"))
    assert ("cannot be called because LFRicMeshProperties has been "
            "instantiated for a kernel and not an invoke." in str(err.value))
    with pytest.raises(InternalError) as err:
        mesh_props._stub_declarations(ModuleGen("test_mod"))
    assert ("Found unsupported mesh property 'not-a-property' when "
            "generating declarations for kernel stub. Only " in str(err.value))

# Tests for generating the PSy-layer code

def test_mesh_gen(tmpdir):
    ''' Basic test for code-generation for an invoke containing a single
    kernel requiring reference-element properties. '''
    _, invoke_info = parse(os.path.join(BASE_PATH,
                                        "24.1_mesh_prop_invoke.f90"),
                           api=TEST_API)
    psy = PSyFactory(TEST_API, distributed_memory=False).create(invoke_info)

    assert LFRicBuild(tmpdir).code_compiles(psy)
    gen = str(psy.gen).lower()
    # In order to provide the mesh property we need the reference element
    assert "use reference_element_mod, only: reference_element_type" in gen
    assert "integer(kind=i_def) nfaces_re_h" in gen
    assert ("integer(kind=i_def), pointer :: adjacent_face(:,:) => null()"
            in gen)
    assert ("class(reference_element_type), pointer :: reference_element "
            "=> null()" in gen)
    # We need a mesh object in order to get a reference_element object
    assert "mesh => f1_proxy%vspace%get_mesh()" in gen
    assert "reference_element => mesh%get_reference_element()" in gen
    assert ("nfaces_re_h = reference_element%get_number_horizontal_faces()"
            in gen)
    assert "adjacent_face => mesh%get_adjacent_face()" in gen
    assert "nfaces_re_v" not in gen
    # The kernel call
    assert ("call testkern_mesh_prop_code(nlayers, a, f1_data, "
            "ndf_w1, undf_w1, map_w1(:,cell), nfaces_re_h, "
            "adjacent_face(:,cell))" in gen)

def test_duplicate_mesh_gen(tmpdir):
    ''' Test for code-generation for an invoke containing two kernels that
    require the same property of the mesh. '''
    _, invoke_info = parse(os.path.join(BASE_PATH,
                                        "24.2_duplicate_mesh_prop_invoke.f90"),
                           api=TEST_API)
    psy = PSyFactory(TEST_API, distributed_memory=False).create(invoke_info)

    assert LFRicBuild(tmpdir).code_compiles(psy)
    gen = str(psy.gen).lower()
    assert gen.count(
        "integer(kind=i_def), pointer :: adjacent_face(:,:) => null()") == 1
    assert gen.count(
        "reference_element => mesh%get_reference_element") == 1
    assert gen.count(
        "nfaces_re_h = reference_element%get_number_horizontal_faces()") == 1
    assert "nfaces_re_v" not in gen
    assert gen.count("adjacent_face => mesh%get_adjacent_face()") == 1
    assert ("call testkern_mesh_prop_code(nlayers, a, f1_data, "
            "ndf_w1, undf_w1, map_w1(:,cell), nfaces_re_h, "
            "adjacent_face(:,cell)" in gen)
    assert ("call testkern_mesh_prop_code(nlayers, b, f2_data, "
            "ndf_w1, undf_w1, map_w1(:,cell), nfaces_re_h, "
            "adjacent_face(:,cell))" in gen)

def test_mesh_prop_plus_ref_elem_gen(tmpdir):
    ''' Check that code generation works for an invoke with a kernel that
    requires properties of both the reference element and the mesh. '''
    _, invoke_info = parse(os.path.join(BASE_PATH,
                                        "24.3_mesh_plus_ref_elem_invoke.f90"),
                           api=TEST_API)
    psy = PSyFactory(TEST_API, distributed_memory=False).create(invoke_info)

    assert LFRicBuild(tmpdir).code_compiles(psy)
    gen = str(psy.gen).lower()

    assert (
        "      reference_element => mesh%get_reference_element()\n"
        "      nfaces_re_h = reference_element%get_number_horizontal_faces()\n"
        "      nfaces_re_v = reference_element%get_number_vertical_faces()\n"
        "      call reference_element%get_normals_to_horizontal_faces("
        "normals_to_horiz_faces)\n"
        "      call reference_element%get_normals_to_vertical_faces("
        "normals_to_vert_faces)\n" in gen)
    assert ("call testkern_mesh_ref_elem_props_code(nlayers, a, "
            "f1_data, ndf_w1, undf_w1, map_w1(:,cell), nfaces_re_h, "
            "nfaces_re_v, normals_to_horiz_faces, normals_to_vert_faces, "
            "adjacent_face(:,cell))" in gen)

def test_mesh_plus_face_quad_gen(tmpdir):
    ''' Test that we generate correct code when a kernel requires both a
    mesh property and face quadrature. '''
    _, invoke_info = parse(os.path.join(BASE_PATH,
                                        "24.4_mesh_plus_face_qr_invoke.f90"),
                           api=TEST_API)
    psy = PSyFactory(TEST_API, distributed_memory=False).create(invoke_info)

    assert LFRicBuild(tmpdir).code_compiles(psy)
    gen = str(psy.gen).lower()

    assert ("      qr_proxy = qr%get_quadrature_proxy()\n"
            "      np_xyz_qr = qr_proxy%np_xyz\n"
            "      nfaces_qr = qr_proxy%nfaces\n"
            "      weights_xyz_qr => qr_proxy%weights_xyz\n"
            "      !\n"
            "      ! allocate basis/diff-basis arrays\n"
            "      !\n"
            "      dim_w1 = f1_proxy%vspace%get_dim_space()\n"
            "      allocate (basis_w1_qr(dim_w1, ndf_w1, np_xyz_qr, "
            "nfaces_qr))" in gen)

    assert ("      reference_element => mesh%get_reference_element()\n"
            "      nfaces_re_h = reference_element%"
            "get_number_horizontal_faces()\n"
            "      !\n"
            "      ! initialise mesh properties\n"
            "      !\n"
            "      adjacent_face => mesh%get_adjacent_face()" in gen)

    assert ("call testkern_mesh_prop_face_qr_code(nlayers, a, f1_data, "
            "ndf_w1, undf_w1, map_w1(:,cell), basis_w1_qr, "
            "nfaces_re_h, adjacent_face(:,cell), "
            "nfaces_qr, np_xyz_qr, weights_xyz_qr)" in gen)

def test_multi_kernel_mesh_props(tmpdir):
    ''' Test code generation when an invoke contains multiple kernels that
    require properties of the mesh, the reference element and face quadrature.
    '''
    _, invoke_info = parse(
        os.path.join(BASE_PATH, "24.5_mesh_plus_ref_elem_plus_qr_invoke.f90"),
        api=TEST_API)
    psy = PSyFactory(TEST_API, distributed_memory=False).create(invoke_info)

    assert LFRicBuild(tmpdir).code_compiles(psy)
    gen = str(psy.gen).lower()

    # Declarations
    assert (
        "      real(kind=r_def), pointer :: weights_xyz_qr(:,:) => null()\n"
        "      integer(kind=i_def) np_xyz_qr, nfaces_qr\n"
        "      integer(kind=i_def), pointer :: adjacent_face(:,:) => null()\n"
        "      real(kind=r_def), allocatable :: normals_to_horiz_faces(:,:), "
        "normals_to_vert_faces(:,:)\n"
        "      integer(kind=i_def) nfaces_re_h, nfaces_re_v\n"
        "      class(reference_element_type), pointer :: reference_element => "
        "null()\n" in gen)
    # Initialisations
    assert "type(mesh_type), pointer :: mesh => null()" in gen
    assert "nfaces_qr = qr_proxy%nfaces" in gen
    assert (
        "      reference_element => mesh%get_reference_element()\n"
        "      nfaces_re_h = reference_element%get_number_horizontal_faces()\n"
        "      nfaces_re_v = reference_element%get_number_vertical_faces()"
        in gen)
    assert "adjacent_face => mesh%get_adjacent_face()" in gen
    # Call to kernel requiring props of the reference element & adjacent faces
    assert ("call testkern_mesh_ref_elem_props_code(nlayers, a, f1_data,"
            " ndf_w1, undf_w1, map_w1(:,cell), nfaces_re_h, nfaces_re_v, "
            "normals_to_horiz_faces, normals_to_vert_faces, "
            "adjacent_face(:,cell))" in gen)
    # Call to kernel requiring adjacent faces and face quadrature
    assert ("call testkern_mesh_prop_face_qr_code(nlayers, a, f2_data, "
            "ndf_w1, undf_w1, map_w1(:,cell), basis_w1_qr, nfaces_re_h, "
            "adjacent_face(:,cell), nfaces_qr, np_xyz_qr, weights_xyz_qr)"
            in gen)


import os
import json
import requests
import pandas as pd

try:
    import websocket

except ImportError:
    print("websocket-client 설치중입니다.")
    os.system('python3 -m pip3 install websocket-client')

# 웹소켓 접속키 발급
def get_approval(key, secret):
    # url = https://openapivts.koreainvestment.com:29443' # 모의투자계좌
    url = 'https://openapi.koreainvestment.com:9443' # 실전투자계좌
    headers = {"content-type": "application/json"}
    body = {"grant_type": "client_credentials",
            "appkey": key,
            "secretkey": secret}
    PATH = "oauth2/Approval"
    URL = f"{url}/{PATH}"
    res = requests.post(URL, headers=headers, data=json.dumps(body))
    approval_key = res.json()["approval_key"]
    return approval_key

i_stock = ["005930","011700","000270"]
i_appkey    = "API신청시 발급 앱키"
i_appsecret = "API신청시 발급 앱시크리트"

i_approval_key = get_approval(i_appkey, i_appsecret)
print("approval_key [%s]" % (i_approval_key))

b = {
    "header": {"approval_key": i_approval_key, "custtype": "P", "tr_type": "1", "content-type": "utf-8"},
    "body": { "input": {"tr_id": "H0STCNT0",  # API명
                        "tr_key": i_stock[0]  # 종목번호
                       }
            }
}
b2 = {
    "header": {"approval_key": i_approval_key, "custtype": "P", "tr_type": "1", "content-type": "utf-8"},
    "body": { "input": {"tr_id": "H0STCNT0",  # API명
                        "tr_key": i_stock[1]  # 종목번호
                       }
            }
}
b3 = {
    "header": {"approval_key": i_approval_key, "custtype": "P", "tr_type": "1", "content-type": "utf-8"},
    "body": { "input": {"tr_id": "H0STCNT0",  # API명
                        "tr_key": i_stock[2]  # 종목번호
                       }
            }
}

# Pandas DataFrame 이용
def pdbind(result):

     if i_stock[0] == result[0]:
        print("종목코드1:",result[0], " 체결시간:", result[1], " 현재가:", result[2])
     if i_stock[1] == result[0]:
        print("종목코드2:",result[0], " 체결시간:", result[1], " 현재가:", result[2])
     if i_stock[2] == result[0]:
        print("종목코드3:",result[0], " 체결시간:", result[1], " 현재가:", result[2])

def on_message(ws, data):
    #print('type=', type(data), '\ndata=', data)

    if data[0] in ['0', '1']:  # 시세데이터가 아닌경우
        d1 = data.split("|")
        if len(d1) >= 4:
            isEncrypt = d1[0]
            tr_id = d1[1]
            tr_cnt = d1[2]
            recvData = d1[3]
            result = recvData.split("^")
            #print("start time=", result[1])
            pdbind(result)  # pandas dataframe 이용 변경
        else:
            print('Data Size Error=', len(d1))
    else:
        recv_dic = json.loads(data)
        tr_id = recv_dic['header']['tr_id']

        if tr_id == 'PINGPONG':
            send_ping = recv_dic
            ws.send(data, websocket.ABNF.OPCODE_PING)
        else:  # parser data
            print('tr_id=', tr_id, '\nmsg=', data)

def on_error(ws, error):
    print('error=', error)

def on_close(ws, status_code, close_msg):
    print('on_close close_status_code=', status_code, " close_msg=", close_msg)

def on_open(ws):
    print('on_open send data=', json.dumps(b))
    ws.send(json.dumps(b), websocket.ABNF.OPCODE_TEXT) #종목코드 1
    ws.send(json.dumps(b2), websocket.ABNF.OPCODE_TEXT) #종목코드 2
    ws.send(json.dumps(b3), websocket.ABNF.OPCODE_TEXT)  # 종목코드 3

# 모의투자
# ws = websocket.WebSocketApp("ws://ops.koreainvestment.com:31000",
#                             on_open=on_open, on_message=on_message, on_error=on_error)

ws = websocket.WebSocketApp("ws://ops.koreainvestment.com:21000",
                            on_open=on_open, on_message=on_message, on_error=on_error)

ws.run_forever()


filepath = 'C:/Users/chait/Desktop/Casestudy/Audio/'
output_filepath = 'C:/Users/chait/Desktop/Casestudy/minutesOM/'

bucketname = "sapstudy"
from google.oauth2 import service_account

#import libraries
from pydub import AudioSegment
import io
import os
from google.cloud import speech_v1p1beta1 as speech #Changed
#from google.cloud.speech_v1p1beta1 import enums #Changed
#from google.cloud.speech_v1p1beta1 import types #Changed
import wave
from google.cloud import storage

os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = "C:/Users/chait/Desktop/Casestudy/My Project-673fa5216bd1 (1).json"

def mp3_to_wav(audio_file_name):
    if audio_file_name.split('.')[1] == 'mp3':
        sound = AudioSegment.from_mp3(audio_file_name)
        audio_file_name = audio_file_name.split('.')[0] + '.wav'
        sound.export(audio_file_name, format="wav")

def stereo_to_mono(audio_file_name):
    sound = AudioSegment.from_wav(audio_file_name)
    sound = sound.set_channels(1)
    sound.export(audio_file_name, format="wav")

def frame_rate_channel(audio_file_name):
    with wave.open(audio_file_name, "rb") as wave_file:
        frame_rate = wave_file.getframerate()
        channels = wave_file.getnchannels()
        return frame_rate,channels

def upload_blob(bucket_name, source_file_name, destination_blob_name):
    """Uploads a file to the bucket."""
    storage_client = storage.Client()
    bucket = storage_client.get_bucket(bucket_name)
    blob = bucket.blob(destination_blob_name)
    blob.upload_from_filename(source_file_name)

def delete_blob(bucket_name, blob_name):
    """Deletes a blob from the bucket."""
    storage_client = storage.Client()
    bucket = storage_client.get_bucket(bucket_name)
    blob = bucket.blob(blob_name)
    blob.delete()

def google_transcribe(audio_file_name):

    file_name = filepath + audio_file_name

    # The name of the audio file to transcribe

    frame_rate, channels = frame_rate_channel(file_name)

    if channels > 1:
        stereo_to_mono(file_name)

    bucket_name = bucketname
    source_file_name = filepath + audio_file_name
    destination_blob_name = audio_file_name

    upload_blob(bucket_name, source_file_name, destination_blob_name)

    gcs_uri = 'gs://' + bucketname + '/' + audio_file_name
    transcript = ''

    client = speech.SpeechClient()
    audio = speech.RecognitionAudio(uri=gcs_uri)

    config = speech.RecognitionConfig(
    encoding = speech.RecognitionConfig.AudioEncoding.LINEAR16,
    sample_rate_hertz = frame_rate,
    language_code = 'en-US',
    enable_speaker_diarization=True,
    diarization_speaker_count = 3)

    # Detects speech in the audio file
    operation = client.long_running_recognize(config = config,audio = audio)
    response = operation.result(timeout=1000000000)
    result = response.results[-1] #Changed
    words_info = result.alternatives[0].words #Changed

    tag=1 #Changed
    speaker="" #Changed

    for word_info in words_info: #Changed
        if word_info.speaker_tag==tag: #Changed
            speaker=speaker+" "+word_info.word #Changed
        else: #Changed
            transcript += "speaker {}: {}".format(tag,speaker) + '\n' #Changed
            tag=word_info.speaker_tag #Changed
            speaker=""+word_info.word #Changed

    transcript += "speaker {}: {}".format(tag,speaker) #Changed

    delete_blob(bucket_name, destination_blob_name)
    return transcript

def write_transcripts(transcript_filename,transcript):
    f= open(output_filepath + transcript_filename,"w+")
    f.write(transcript)
    f.close()

def getOriginalText():
    for audio_file_name in os.listdir(filepath):
        #print(audio_file_name)
        transcript = google_transcribe(audio_file_name)
        transcript_filename = audio_file_name.split('.')[0] + 'Text.txt'
        write_transcripts(transcript_filename,transcript)
        #print(transcript)
        #print(type(transcript))
        return transcript

if __name__=='__main__':
    getOriginalText()


import torch
import torch.nn as nn
import numpy as np
from utils.train_utils import get_labels, dtw_loss
from utils.softdtw import SoftDTW
from utils.data_utils import dct_2d
import random

seed = 42
torch.manual_seed(seed)
torch.cuda.manual_seed(seed)
np.random.seed(seed)
random.seed(seed)
torch.backends.cudnn.deterministic = True
torch.backends.cudnn.benchmark = False

class AccumLoss(object):
    def __init__(self):
        self.val = 0
        self.avg = 0
        self.sum = 0
        self.count = 0

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

def test_cnn(test_loader, model, is_cuda=False, level=0):
    te_l = AccumLoss()
    if level == 0:
        criterion = nn.NLLLoss(weight=torch.tensor([1, 0.5, 1, 0.5, 1, 0.5]))
    else:
        criterion = nn.NLLLoss()
    # Set the model to evaluation mode
    model.eval()

    correct = 0
    total = 0

    preds = {'gt': [], 'preds': []}
    for i, (batch_id, inputs) in enumerate(test_loader):
        if inputs.shape[1] > 3:
            inputs = inputs.permute(0, 3, 2, 1)
        if is_cuda:
            inputs = inputs.float().cuda()
        else:
            inputs = inputs.float()

        labels = get_labels([test_loader.dataset.inputs_label[int(i)] for i in batch_id], level=level).cuda()
        batch_size = inputs.size(0)

        # Forward
        outputs = model(inputs)
        _, predicted = torch.max(outputs.data, 1)

        total += labels.size(0)
        correct += (predicted == labels).sum().item()

        # calculate loss using loss function
        loss = criterion(outputs, labels)

        # update the training loss
        te_l.update(loss.cpu().data.numpy() * batch_size, batch_size)
        # Log the test accuracy to TensorBoard (if enabled)

        preds['gt'] = labels
        preds['preds'] = predicted.tolist()
    return te_l.avg, 100 * correct / total, preds

def test_class(test_loader, model, is_cuda=False, level=0):
    te_l = AccumLoss()

    if level == 0:
        criterion = nn.NLLLoss(weight=torch.tensor([1, 0.5, 1, 0.5, 1, 0.5]))
    else:
        criterion = nn.NLLLoss()
    model.eval()

    correct = 0
    total = 0
    for i, (batch_id, inputs) in enumerate(test_loader):
        if is_cuda:
            inputs = inputs.float().cuda()
        else:
            inputs = inputs.float()
        if test_loader.dataset.name == 'EC3D':
            # import pdb; pdb.set_trace()
            labels = get_labels([test_loader.dataset.inputs_label[int(i)] for i in batch_id], level=level).cuda()
        elif test_loader.dataset.name == 'NTU60':
            labels = torch.from_numpy(np.array([test_loader.dataset.labels[int(i)] for i in batch_id])).long().cuda()
        batch_size = inputs.shape[0]

        outputs = model(inputs)
        _, predicted = torch.max(outputs.data, 1)

        total += labels.size(0)
        # import pdb
        # pdb.set_trace()
        correct += (predicted == labels).sum().item()

        # calculate loss and backward
        loss = criterion(outputs, labels)

        # update the training loss
        te_l.update(loss.cpu().data.numpy() * batch_size, batch_size)

        # summary = np.vstack((labels.numpy(), predicted.numpy()))
        summary = torch.stack((labels, predicted), dim=1)
        if level == 0:
            cmt = torch.zeros(6, 6, dtype=torch.int64)
        elif level == 1:
            cmt = torch.zeros(12, 12, dtype=torch.int64)
        else:
            cmt = torch.zeros(60, 60, dtype=torch.int64)
        # pdb.set_trace()
        for pp in summary:
            tl, pl = pp.tolist()
            cmt[tl, pl] = cmt[tl, pl] + 1

    return te_l.avg, 100 * correct / total, summary, cmt

def test_corr(test_loader, model, fact=None, is_cuda=False, level=0, attn=None):
    test_l = AccumLoss()
    preds = {'in': [], 'out': [], 'targ': [], 'labels': []}
    criterion = SoftDTW(use_cuda=is_cuda, gamma=0.01)
    model.eval()
    for i, (batch_id, inputs) in enumerate(test_loader):

        if is_cuda:
            inputs = inputs.cuda().float()
        else:
            inputs = inputs.float()

        labels = get_labels([test_loader.dataset.inputs_label[int(i)] for i in batch_id], level=level).cuda()
        targets = [test_loader.dataset.targets[int(i)] for i in batch_id]
        originals = [test_loader.dataset.inputs_raw[int(i)] for i in batch_id]
        batch_size = inputs.shape[0]

        if attn is not None:
            deltas = model(inputs)
        else:
            deltas, att = model(inputs)

        # calculate loss and backward
        if fact is None:
            dtw, out, _, _ = dtw_loss(originals, deltas, targets, criterion, is_cuda=is_cuda, test=True)
            loss = dtw
        else:
            dtw, out, _, _ = dtw_loss(originals, deltas, targets, criterion, attentions=att, is_cuda=is_cuda, test=True)
            l1 = fact * torch.sum(torch.abs(att))
            loss = (dtw + l1)

        preds['in'] = preds['in'] + originals
        preds['out'] = preds['out'] + out
        preds['targ'] = preds['targ'] + targets
        preds['labels'] = preds['labels'] + labels.cpu().detach().numpy().tolist()
        test_l.update(loss.cpu().data.numpy(), batch_size)

    return test_l.avg, preds

def test_GAT(test_loader, model, use_adj=False, is_cuda=False, level=0):
    test_l = AccumLoss()
    preds = {'in': [], 'out': [], 'targ': [], 'labels': []}
    criterion = SoftDTW(use_cuda=is_cuda, gamma=0.01)
    model.eval()
    with torch.no_grad():
        for i, (batch_id, inputs) in enumerate(test_loader):
            if is_cuda:
                inputs = inputs.cuda().float()
            else:
                inputs = inputs.float()
            labels = get_labels([test_loader.dataset.inputs_label[int(i)] for i in batch_id], level=level).cuda()
            targets = [test_loader.dataset.targets[int(i)] for i in batch_id]
            originals = [test_loader.dataset.inputs_raw[int(i)] for i in batch_id]
            batch_size = inputs.shape[0]

            # Forward
            if use_adj:
                # Create fully connected adjacency matrix
                batch_size = inputs.shape[0]
                nodes_n = inputs.shape[1]
                adj_mat = np.ones((batch_size, nodes_n, nodes_n))
                for i in range(batch_size):
                    np.fill_diagonal(adj_mat[i], 0)
                adj_mat = torch.from_numpy(adj_mat).float().unsqueeze(-1).to(inputs.device)
                deltas = model(inputs, adj_mat)
            else:
                deltas = model(inputs)

            dtw, out, _, _ = dtw_loss(originals, deltas, targets, criterion, is_cuda=is_cuda, test=True)
            loss = dtw
            preds['in'] = preds['in'] + originals
            preds['out'] = preds['out'] + out
            preds['targ'] = preds['targ'] + targets
            preds['labels'] = preds['labels'] + labels.cpu().detach().numpy().tolist()
            test_l.update(loss.cpu().data.numpy(), batch_size)
            print(test_l.avg)

            torch.cuda.empty_cache()
    return test_l.avg, preds

def test_transformerV2(test_loader, model, use_mask=True, is_cuda=False):
    test_l = AccumLoss()
    preds = {'in': [], 'out': [], 'targ': []}
    criterion = SoftDTW(use_cuda=is_cuda, gamma=0.01)
    model.eval()
    for i, (batch_id, inputs) in enumerate(test_loader):
        targets = [test_loader.dataset.targets[int(i)] for i in batch_id]
        originals = [test_loader.dataset.inputs_raw[int(i)] for i in batch_id]
        if is_cuda:
            inputs = inputs.float().cuda()
        else:
            inputs = inputs.float()
        batch_size = inputs.shape[0]

        # Get DCT for targets
        dct_n = 25
        trg = [dct_2d(torch.from_numpy(x))[:, :dct_n].numpy() if x.shape[1] >= dct_n else
               dct_2d(torch.nn.ZeroPad2d((0, dct_n - x.shape[1], 0, 0))(torch.from_numpy(x))).numpy()
               for x in targets]
        trg = np.stack(trg, axis=0)
        trg = torch.from_numpy(trg).float().to(inputs.device)

        seq_len = inputs.shape[1]

        # Generate target mask
        tgt_mask = generate_look_ahead_mask(seq_len).to(inputs.device)

        if use_mask:
            deltas = model(inputs, trg, tgt_mask=tgt_mask)
        else:
            deltas = model(inputs, trg)

        # Calculate loss
        dtw, out, _, _ = dtw_loss(originals, deltas, targets, criterion, is_cuda=is_cuda, test=True)
        loss = dtw
        preds['in'] = preds['in'] + originals
        preds['out'] = preds['out'] + out
        preds['targ'] = preds['targ'] + targets
        test_l.update(loss.cpu().data.numpy(), batch_size)
        print(test_l.avg)
    return test_l.avg, preds

def generate_look_ahead_mask(size):
    mask = torch.triu(torch.ones(size, size), diagonal=1)
    return mask.masked_fill(mask == 1, float('-inf'))