from pants.base.exceptions import TargetDefinitionException
from pants.base.payload import Payload
from pants.base.payload_field import PrimitiveField
from pants.fs import archive as archive_lib

from pants.contrib.node.targets.node_package import NodePackage

class NodeBundle(NodePackage):
  """A bundle of node modules."""

  def __init__(self, node_module=None, archive='tgz', address=None, payload=None, **kwargs):
    """
    :param dependencies: a list of node_modules

    :param archive: a string, select from tar, tgz, tbz2, default to tgz
    """
    if archive not in archive_lib.TYPE_NAMES_PRESERVE_SYMLINKS:
      raise TargetDefinitionException(
        self, '{} is not a valid archive type. Allowed archive types are {}'.format(
          archive,
          ', '.join(sorted(list(archive_lib.TYPE_NAMES_PRESERVE_SYMLINKS)))))

    if not node_module:
      raise TargetDefinitionException(self, 'node_module can not be empty.')

    payload = payload or Payload()
    payload.add_fields({
      'archive': PrimitiveField(archive),
      'node_module': PrimitiveField(node_module),
    })
    super().__init__(address=address, payload=payload, **kwargs)

  @classmethod
  def compute_dependency_specs(cls, kwargs=None, payload=None):
    for spec in super().compute_dependency_specs(kwargs, payload):
      yield spec

    target_representation = kwargs or payload.as_dict()
    spec = target_representation.get('node_module')
    if spec:
      yield spec

  @property
  def node_module(self):
    if len(self.dependencies) != 1:
      raise TargetDefinitionException(
        self,
        'A node_bundle must define exactly one node_module dependency, have {}'.format(
          self.dependencies))
    else:
      return self.dependencies[0]


from django.shortcuts import render
from article.models import Article

def HomePage(request):

    articles = Article.objects.all().order_by('-created_date')[:3]
    first_article = None
    second_article = None
    third_article = None

    if len(articles) >= 1:
        first_article = articles[0]
    if len(articles) >= 2:
        second_article = articles[1]
    if len(articles) >= 3:
        third_article = articles[2]

    context = {
        'first_article': first_article,
        'second_article': second_article,
        'third_article': third_article
    }

    return render(request, 'main/home.html', context)


# !/usr/bin/env python3
# -*- coding: utf-8 -*-
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
for data in [b'Bob', b'Mich', b'Sar']:
    # 发送数据
    s.sendto(data, ('127.0.0.1', 9999))
    # 接收数据
    print(s.recv(1024).decode('utf-8'))
s.close()


import itertools

def check_gap(mat, mingap=0, maxgap=0):
    for i, mat_i in enumerate(mat):
        if i == 0:
            pre = mat_i
            continue
        if mat_i <= pre + mingap or mat_i > pre + 1 + maxgap:
            return False
        pre = mat_i
    return True

def sequenceMatching(edgeMatching, mingap=0, maxgap=0):
    all_combinations = list(itertools.product(*edgeMatching))
    all_matchings = []
    for mat in all_combinations:
        if check_gap(mat, mingap, maxgap):
            all_matchings.append(list(mat))
    return all_matchings

def relevant_pattern(pattern, patterns, min_gap=0, max_gap=0):
    for b_pat in patterns:
        if is_subsequence(b_pat, pattern, min_gap, max_gap):
            return True
    return False

def is_subsequence(pat1, pat2, mingap=0, maxgap=0):
    pat1_itemsets = [edge.replace("[","").replace("(","").split(", ") for edge in pat1.split(")")][:-1]
    pat2_itemsets = [edge.replace("[", "").replace("(", "").split(", ") for edge in pat2.split(")")][:-1]
    matching = []
    for itemset1 in pat1_itemsets:
        j = 0
        edge_matching = []
        for itemset2 in pat2_itemsets:
            if all(x in itemset2 for x in itemset1):
                edge_matching.append(j)
            j += 1
        if len(edge_matching) == 0:
            return False
        matching.append(edge_matching)
    matchings = sequenceMatching(matching, mingap, maxgap)
    if len(matchings) == 0:
        return False
    return True

def read_pattern_by_dataset_dic(pat, dataset_dict):
    (path, sup) = pat.split(':')
    p = "["
    elements = str(path).strip().split(" ")
    for ele in elements:
        el = "("
        items = ele.strip().replace('{', "").replace('}', "").split(",")
        items2 = []
        for item in items:
            el += dataset_dict[int(item.strip())] + ", "
            items2.append(dataset_dict[int(item.strip())])
        el = el[:-2]
        el += ")"
        p += el
    p += "]"
    return p, int(sup.strip())

def read_dataset_dictionary(file):
    di = dict()
    with open(file, "r") as f:
        for line in f:
            s, nb = line.strip().split("\t")
            di[int(nb)] = s
    return di


import cv2
from djitellopy import Tello

def initialize():
    drone = Tello()
    drone.connect()
    drone.for_back_velocity = 0
    drone.left_right_velocity = 0
    drone.up_down_velocity = 0
    drone.yaw_velocity = 0
    drone.speed = 0

    print(drone.get_battery())

    drone.streamon()
    return drone

def shutdown(drone):
    drone.streamoff()
    drone.land()
    exit(0)

def detect(drone, mtcnn, width=360, height=240):

    while True:

        # read stream from drone
        got_frame = drone.get_frame_read()
        frame = got_frame.frame
        vid = cv2.resize(frame, (width, height))
        vid = cv2.resize(vid, (width, height))

        box, prob, lms = mtcnn.detect(vid, landmarks=True)
        draw(vid, box, prob, lms)
        cv2.imshow("Drone Feed", vid)

        if cv2.waitKey(1) & 0xFF == ord("q"):
            break

    cv2.destroyAllWindows()

def draw(frame, box, prob, lms):

    if box is not None and prob is not None:
        for b, p, ld in zip(box, prob, lms):
            x, y, w, h = int(b[0]), int(b[1]), int(b[2]), int(b[3])

            # draw box
            cv2.rectangle(frame, (x, y), (w, h), (0, 255, 0), 2)

            # display probability
            cv2.putText(frame, str(p), (w, h), cv2.FONT_HERSHEY_SIMPLEX, 1,
                        (0, 255, 0), 2, cv2.LINE_AA)


# Released under the MIT License. See LICENSE for details.
#
"""Various functionality related to achievements."""
from __future__ import annotations

import logging
from typing import TYPE_CHECKING

import babase
import bascenev1
import bauiv1

if TYPE_CHECKING:
    from typing import Any, Sequence

    import baclassic

# This could use some cleanup.
# We wear the cone of shame.
# pylint: disable=too-many-lines
# pylint: disable=too-many-statements
# pylint: disable=too-many-locals
# pylint: disable=too-many-branches

# FIXME: We should probably point achievements
#  at coop levels instead of hard-coding names.
#  (so level name substitution works right and whatnot).
ACH_LEVEL_NAMES = {
    'Boom Goes the Dynamite': 'Pro Onslaught',
    'Boxer': 'Onslaught Training',
    'Flawless Victory': 'Rookie Onslaught',
    'Gold Miner': 'Uber Onslaught',
    'Got the Moves': 'Uber Football',
    'Last Stand God': 'The Last Stand',
    'Last Stand Master': 'The Last Stand',
    'Last Stand Wizard': 'The Last Stand',
    'Mine Games': 'Rookie Onslaught',
    'Off You Go Then': 'Onslaught Training',
    'Onslaught God': 'Infinite Onslaught',
    'Onslaught Master': 'Infinite Onslaught',
    'Onslaught Training Victory': 'Onslaught Training',
    'Onslaught Wizard': 'Infinite Onslaught',
    'Precision Bombing': 'Pro Runaround',
    'Pro Boxer': 'Pro Onslaught',
    'Pro Football Shutout': 'Pro Football',
    'Pro Football Victory': 'Pro Football',
    'Pro Onslaught Victory': 'Pro Onslaught',
    'Pro Runaround Victory': 'Pro Runaround',
    'Rookie Football Shutout': 'Rookie Football',
    'Rookie Football Victory': 'Rookie Football',
    'Rookie Onslaught Victory': 'Rookie Onslaught',
    'Runaround God': 'Infinite Runaround',
    'Runaround Master': 'Infinite Runaround',
    'Runaround Wizard': 'Infinite Runaround',
    'Stayin\' Alive': 'Uber Runaround',
    'Super Mega Punch': 'Pro Football',
    'Super Punch': 'Rookie Football',
    'TNT Terror': 'Uber Onslaught',
    'The Great Wall': 'Uber Runaround',
    'The Wall': 'Pro Runaround',
    'Uber Football Shutout': 'Uber Football',
    'Uber Football Victory': 'Uber Football',
    'Uber Onslaught Victory': 'Uber Onslaught',
    'Uber Runaround Victory': 'Uber Runaround',
}

class AchievementSubsystem:
    """Subsystem for achievement handling.

    Category: **App Classes**

    Access the single shared instance of this class at 'ba.app.ach'.
    """

    def __init__(self) -> None:
        self.achievements: list[Achievement] = []
        self.achievements_to_display: (
            list[tuple[baclassic.Achievement, bool]]
        ) = []
        self.achievement_display_timer: bascenev1.BaseTimer | None = None
        self.last_achievement_display_time: float = 0.0
        self.achievement_completion_banner_slots: set[int] = set()
        self._init_achievements()

    def _init_achievements(self) -> None:
        """Fill in available achievements."""

        achs = self.achievements

        # 5
        achs.append(
            Achievement('In Control', 'achievementInControl', (1, 1, 1), '', 5)
        )
        # 15
        achs.append(
            Achievement(
                'Sharing is Caring',
                'achievementSharingIsCaring',
                (1, 1, 1),
                '',
                15,
            )
        )
        # 10
        achs.append(
            Achievement(
                'Dual Wielding', 'achievementDualWielding', (1, 1, 1), '', 10
            )
        )

        # 10
        achs.append(
            Achievement(
                'Free Loader', 'achievementFreeLoader', (1, 1, 1), '', 10
            )
        )
        # 20
        achs.append(
            Achievement(
                'Team Player', 'achievementTeamPlayer', (1, 1, 1), '', 20
            )
        )

        # 5
        achs.append(
            Achievement(
                'Onslaught Training Victory',
                'achievementOnslaught',
                (1, 1, 1),
                'Default:Onslaught Training',
                5,
            )
        )
        # 5
        achs.append(
            Achievement(
                'Off You Go Then',
                'achievementOffYouGo',
                (1, 1.1, 1.3),
                'Default:Onslaught Training',
                5,
            )
        )
        # 10
        achs.append(
            Achievement(
                'Boxer',
                'achievementBoxer',
                (1, 0.6, 0.6),
                'Default:Onslaught Training',
                10,
                hard_mode_only=True,
            )
        )

        # 10
        achs.append(
            Achievement(
                'Rookie Onslaught Victory',
                'achievementOnslaught',
                (0.5, 1.4, 0.6),
                'Default:Rookie Onslaught',
                10,
            )
        )
        # 10
        achs.append(
            Achievement(
                'Mine Games',
                'achievementMine',
                (1, 1, 1.4),
                'Default:Rookie Onslaught',
                10,
            )
        )
        # 15
        achs.append(
            Achievement(
                'Flawless Victory',
                'achievementFlawlessVictory',
                (1, 1, 1),
                'Default:Rookie Onslaught',
                15,
                hard_mode_only=True,
            )
        )

        # 10
        achs.append(
            Achievement(
                'Rookie Football Victory',
                'achievementFootballVictory',
                (1.0, 1, 0.6),
                'Default:Rookie Football',
                10,
            )
        )
        # 10
        achs.append(
            Achievement(
                'Super Punch',
                'achievementSuperPunch',
                (1, 1, 1.8),
                'Default:Rookie Football',
                10,
            )
        )
        # 15
        achs.append(
            Achievement(
                'Rookie Football Shutout',
                'achievementFootballShutout',
                (1, 1, 1),
                'Default:Rookie Football',
                15,
                hard_mode_only=True,
            )
        )

        # 15
        achs.append(
            Achievement(
                'Pro Onslaught Victory',
                'achievementOnslaught',
                (0.3, 1, 2.0),
                'Default:Pro Onslaught',
                15,
            )
        )
        # 15
        achs.append(
            Achievement(
                'Boom Goes the Dynamite',
                'achievementTNT',
                (1.4, 1.2, 0.8),
                'Default:Pro Onslaught',
                15,
            )
        )
        # 20
        achs.append(
            Achievement(
                'Pro Boxer',
                'achievementBoxer',
                (2, 2, 0),
                'Default:Pro Onslaught',
                20,
                hard_mode_only=True,
            )
        )

        # 15
        achs.append(
            Achievement(
                'Pro Football Victory',
                'achievementFootballVictory',
                (1.3, 1.3, 2.0),
                'Default:Pro Football',
                15,
            )
        )
        # 15
        achs.append(
            Achievement(
                'Super Mega Punch',
                'achievementSuperPunch',
                (2, 1, 0.6),
                'Default:Pro Football',
                15,
            )
        )
        # 20
        achs.append(
            Achievement(
                'Pro Football Shutout',
                'achievementFootballShutout',
                (0.7, 0.7, 2.0),
                'Default:Pro Football',
                20,
                hard_mode_only=True,
            )
        )

        # 15
        achs.append(
            Achievement(
                'Pro Runaround Victory',
                'achievementRunaround',
                (1, 1, 1),
                'Default:Pro Runaround',
                15,
            )
        )
        # 20
        achs.append(
            Achievement(
                'Precision Bombing',
                'achievementCrossHair',
                (1, 1, 1.3),
                'Default:Pro Runaround',
                20,
                hard_mode_only=True,
            )
        )
        # 25
        achs.append(
            Achievement(
                'The Wall',
                'achievementWall',
                (1, 0.7, 0.7),
                'Default:Pro Runaround',
                25,
                hard_mode_only=True,
            )
        )

        # 30
        achs.append(
            Achievement(
                'Uber Onslaught Victory',
                'achievementOnslaught',
                (2, 2, 1),
                'Default:Uber Onslaught',
                30,
            )
        )
        # 30
        achs.append(
            Achievement(
                'Gold Miner',
                'achievementMine',
                (2, 1.6, 0.2),
                'Default:Uber Onslaught',
                30,
                hard_mode_only=True,
            )
        )
        # 30
        achs.append(
            Achievement(
                'TNT Terror',
                'achievementTNT',
                (2, 1.8, 0.3),
                'Default:Uber Onslaught',
                30,
                hard_mode_only=True,
            )
        )

        # 30
        achs.append(
            Achievement(
                'Uber Football Victory',
                'achievementFootballVictory',
                (1.8, 1.4, 0.3),
                'Default:Uber Football',
                30,
            )
        )
        # 30
        achs.append(
            Achievement(
                'Got the Moves',
                'achievementGotTheMoves',
                (2, 1, 0),
                'Default:Uber Football',
                30,
                hard_mode_only=True,
            )
        )
        # 40
        achs.append(
            Achievement(
                'Uber Football Shutout',
                'achievementFootballShutout',
                (2, 2, 0),
                'Default:Uber Football',
                40,
                hard_mode_only=True,
            )
        )

        # 30
        achs.append(
            Achievement(
                'Uber Runaround Victory',
                'achievementRunaround',
                (1.5, 1.2, 0.2),
                'Default:Uber Runaround',
                30,
            )
        )
        # 40
        achs.append(
            Achievement(
                'The Great Wall',
                'achievementWall',
                (2, 1.7, 0.4),
                'Default:Uber Runaround',
                40,
                hard_mode_only=True,
            )
        )
        # 40
        achs.append(
            Achievement(
                'Stayin\' Alive',
                'achievementStayinAlive',
                (2, 2, 1),
                'Default:Uber Runaround',
                40,
                hard_mode_only=True,
            )
        )

        # 20
        achs.append(
            Achievement(
                'Last Stand Master',
                'achievementMedalSmall',
                (2, 1.5, 0.3),
                'Default:The Last Stand',
                20,
                hard_mode_only=True,
            )
        )
        # 40
        achs.append(
            Achievement(
                'Last Stand Wizard',
                'achievementMedalMedium',
                (2, 1.5, 0.3),
                'Default:The Last Stand',
                40,
                hard_mode_only=True,
            )
        )
        # 60
        achs.append(
            Achievement(
                'Last Stand God',
                'achievementMedalLarge',
                (2, 1.5, 0.3),
                'Default:The Last Stand',
                60,
                hard_mode_only=True,
            )
        )

        # 5
        achs.append(
            Achievement(
                'Onslaught Master',
                'achievementMedalSmall',
                (0.7, 1, 0.7),
                'Challenges:Infinite Onslaught',
                5,
            )
        )
        # 15
        achs.append(
            Achievement(
                'Onslaught Wizard',
                'achievementMedalMedium',
                (0.7, 1.0, 0.7),
                'Challenges:Infinite Onslaught',
                15,
            )
        )
        # 30
        achs.append(
            Achievement(
                'Onslaught God',
                'achievementMedalLarge',
                (0.7, 1.0, 0.7),
                'Challenges:Infinite Onslaught',
                30,
            )
        )

        # 5
        achs.append(
            Achievement(
                'Runaround Master',
                'achievementMedalSmall',
                (1.0, 1.0, 1.2),
                'Challenges:Infinite Runaround',
                5,
            )
        )
        # 15
        achs.append(
            Achievement(
                'Runaround Wizard',
                'achievementMedalMedium',
                (1.0, 1.0, 1.2),
                'Challenges:Infinite Runaround',
                15,
            )
        )
        # 30
        achs.append(
            Achievement(
                'Runaround God',
                'achievementMedalLarge',
                (1.0, 1.0, 1.2),
                'Challenges:Infinite Runaround',
                30,
            )
        )

    def award_local_achievement(self, achname: str) -> None:
        """For non-game-based achievements such as controller-connection."""
        plus = babase.app.plus
        if plus is None:
            logging.warning('achievements require plus feature-set')
            return
        try:
            ach = self.get_achievement(achname)
            if not ach.complete:
                # Report new achievements to the game-service.
                plus.report_achievement(achname)

                # And to our account.
                plus.add_v1_account_transaction(
                    {'type': 'ACHIEVEMENT', 'name': achname}
                )

                # Now attempt to show a banner.
                self.display_achievement_banner(achname)

        except Exception:
            logging.exception('Error in award_local_achievement.')

    def display_achievement_banner(self, achname: str) -> None:
        """Display a completion banner for an achievement.

        (internal)

        Used for server-driven achievements.
        """
        try:
            # FIXME: Need to get these using the UI context or some other
            #  purely local context somehow instead of trying to inject these
            #  into whatever activity happens to be active
            #  (since that won't work while in client mode).
            activity = bascenev1.get_foreground_host_activity()
            if activity is not None:
                with activity.context:
                    self.get_achievement(achname).announce_completion()
        except Exception:
            logging.exception('Error in display_achievement_banner.')

    def set_completed_achievements(self, achs: Sequence[str]) -> None:
        """Set the current state of completed achievements.

        (internal)

        All achievements not included here will be set incomplete.
        """

        # Note: This gets called whenever game-center/game-circle/etc tells
        # us which achievements we currently have.  We always defer to them,
        # even if that means we have to un-set an achievement we think we have.

        cfg = babase.app.config
        cfg['Achievements'] = {}
        for a_name in achs:
            self.get_achievement(a_name).set_complete(True)
        cfg.commit()

    def get_achievement(self, name: str) -> Achievement:
        """Return an Achievement by name."""
        achs = [a for a in self.achievements if a.name == name]
        assert len(achs) < 2
        if not achs:
            raise ValueError("Invalid achievement name: '" + name + "'")
        return achs[0]

    def achievements_for_coop_level(self, level_name: str) -> list[Achievement]:
        """Given a level name, return achievements available for it."""

        # For the Easy campaign we return achievements for the Default
        # campaign too. (want the user to see what achievements are part of the
        # level even if they can't unlock them all on easy mode).
        return [
            a
            for a in self.achievements
            if a.level_name
            in (level_name, level_name.replace('Easy', 'Default'))
        ]

    def _test(self) -> None:
        """For testing achievement animations."""

        def testcall1() -> None:
            self.achievements[0].announce_completion()
            self.achievements[1].announce_completion()
            self.achievements[2].announce_completion()

        def testcall2() -> None:
            self.achievements[3].announce_completion()
            self.achievements[4].announce_completion()
            self.achievements[5].announce_completion()

        bascenev1.basetimer(3.0, testcall1)
        bascenev1.basetimer(7.0, testcall2)

def _get_ach_mult(include_pro_bonus: bool = False) -> int:
    """Return the multiplier for achievement pts.

    (just for display; changing this here won't affect actual rewards)
    """
    plus = babase.app.plus
    classic = babase.app.classic
    if plus is None or classic is None:
        return 5
    val: int = plus.get_v1_account_misc_read_val('achAwardMult', 5)
    assert isinstance(val, int)
    if include_pro_bonus and classic.accounts.have_pro():
        val *= 2
    return val

def _display_next_achievement() -> None:
    # Pull the first achievement off the list and display it, or kill the
    # display-timer if the list is empty.
    app = babase.app
    assert app.classic is not None
    ach_ss = app.classic.ach
    if app.classic.ach.achievements_to_display:
        try:
            ach, sound = ach_ss.achievements_to_display.pop(0)
            ach.show_completion_banner(sound)
        except Exception:
            logging.exception('Error in _display_next_achievement.')
            ach_ss.achievements_to_display = []
            ach_ss.achievement_display_timer = None
    else:
        ach_ss.achievement_display_timer = None

class Achievement:
    """Represents attributes and state for an individual achievement.

    Category: **App Classes**
    """

    def __init__(
        self,
        name: str,
        icon_name: str,
        icon_color: Sequence[float],
        level_name: str,
        award: int,
        hard_mode_only: bool = False,
    ):
        self._name = name
        self._icon_name = icon_name
        self._icon_color: Sequence[float] = list(icon_color) + [1]
        self._level_name = level_name
        self._completion_banner_slot: int | None = None
        self._award = award
        self._hard_mode_only = hard_mode_only

    @property
    def name(self) -> str:
        """The name of this achievement."""
        return self._name

    @property
    def level_name(self) -> str:
        """The name of the level this achievement applies to."""
        return self._level_name

    def get_icon_ui_texture(self, complete: bool) -> bauiv1.Texture:
        """Return the icon texture to display for this achievement"""
        return bauiv1.gettexture(
            self._icon_name if complete else 'achievementEmpty'
        )

    def get_icon_texture(self, complete: bool) -> bascenev1.Texture:
        """Return the icon texture to display for this achievement"""
        return bascenev1.gettexture(
            self._icon_name if complete else 'achievementEmpty'
        )

    def get_icon_color(self, complete: bool) -> Sequence[float]:
        """Return the color tint for this Achievement's icon."""
        if complete:
            return self._icon_color
        return 1.0, 1.0, 1.0, 0.6

    @property
    def hard_mode_only(self) -> bool:
        """Whether this Achievement is only unlockable in hard-mode."""
        return self._hard_mode_only

    @property
    def complete(self) -> bool:
        """Whether this Achievement is currently complete."""
        val: bool = self._getconfig()['Complete']
        assert isinstance(val, bool)
        return val

    def announce_completion(self, sound: bool = True) -> None:
        """Kick off an announcement for this achievement's completion."""

        app = babase.app
        plus = app.plus
        classic = app.classic
        if plus is None or classic is None:
            logging.warning('ach account_completion not available.')
            return

        ach_ss = classic.ach

        # Even though there are technically achievements when we're not
        # signed in, lets not show them (otherwise we tend to get
        # confusing 'controller connected' achievements popping up while
        # waiting to sign in which can be confusing).
        if plus.get_v1_account_state() != 'signed_in':
            return

        # If we're being freshly complete, display/report it and whatnot.
        if (self, sound) not in ach_ss.achievements_to_display:
            ach_ss.achievements_to_display.append((self, sound))

        # If there's no achievement display timer going, kick one off
        # (if one's already running it will pick this up before it dies).

        # Need to check last time too; its possible our timer wasn't able to
        # clear itself if an activity died and took it down with it.
        if (
            ach_ss.achievement_display_timer is None
            or babase.apptime() - ach_ss.last_achievement_display_time > 2.0
        ) and bascenev1.getactivity(doraise=False) is not None:
            ach_ss.achievement_display_timer = bascenev1.BaseTimer(
                1.0, _display_next_achievement, repeat=True
            )

            # Show the first immediately.
            _display_next_achievement()

    def set_complete(self, complete: bool = True) -> None:
        """Set an achievement's completed state.

        note this only sets local state; use a transaction to
        actually award achievements.
        """
        config = self._getconfig()
        if complete != config['Complete']:
            config['Complete'] = complete

    @property
    def display_name(self) -> babase.Lstr:
        """Return a babase.Lstr for this Achievement's name."""
        name: babase.Lstr | str
        try:
            if self._level_name != '':
                campaignname, campaign_level = self._level_name.split(':')
                classic = babase.app.classic
                assert classic is not None
                name = (
                    classic.getcampaign(campaignname)
                    .getlevel(campaign_level)
                    .displayname
                )
            else:
                name = ''
        except Exception:
            name = ''
            logging.exception('Error calcing achievement display-name.')
        return babase.Lstr(
            resource='achievements.' + self._name + '.name',
            subs=[('${LEVEL}', name)],
        )

    @property
    def description(self) -> babase.Lstr:
        """Get a babase.Lstr for the Achievement's brief description."""
        if (
            'description'
            in babase.app.lang.get_resource('achievements')[self._name]
        ):
            return babase.Lstr(
                resource='achievements.' + self._name + '.description'
            )
        return babase.Lstr(
            resource='achievements.' + self._name + '.descriptionFull'
        )

    @property
    def description_complete(self) -> babase.Lstr:
        """Get a babase.Lstr for the Achievement's description when complete."""
        if (
            'descriptionComplete'
            in babase.app.lang.get_resource('achievements')[self._name]
        ):
            return babase.Lstr(
                resource='achievements.' + self._name + '.descriptionComplete'
            )
        return babase.Lstr(
            resource='achievements.' + self._name + '.descriptionFullComplete'
        )

    @property
    def description_full(self) -> babase.Lstr:
        """Get a babase.Lstr for the Achievement's full description."""
        return babase.Lstr(
            resource='achievements.' + self._name + '.descriptionFull',
            subs=[
                (
                    '${LEVEL}',
                    babase.Lstr(
                        translate=(
                            'coopLevelNames',
                            ACH_LEVEL_NAMES.get(self._name, '?'),
                        )
                    ),
                )
            ],
        )

    @property
    def description_full_complete(self) -> babase.Lstr:
        """Get a babase.Lstr for the Achievement's full desc. when completed."""
        return babase.Lstr(
            resource='achievements.' + self._name + '.descriptionFullComplete',
            subs=[
                (
                    '${LEVEL}',
                    babase.Lstr(
                        translate=(
                            'coopLevelNames',
                            ACH_LEVEL_NAMES.get(self._name, '?'),
                        )
                    ),
                )
            ],
        )

    def get_award_ticket_value(self, include_pro_bonus: bool = False) -> int:
        """Get the ticket award value for this achievement."""
        plus = babase.app.plus
        if plus is None:
            return 0
        val: int = plus.get_v1_account_misc_read_val(
            'achAward.' + self._name, self._award
        ) * _get_ach_mult(include_pro_bonus)
        assert isinstance(val, int)
        return val

    @property
    def power_ranking_value(self) -> int:
        """Get the power-ranking award value for this achievement."""
        plus = babase.app.plus
        if plus is None:
            return 0
        val: int = plus.get_v1_account_misc_read_val(
            'achLeaguePoints.' + self._name, self._award
        )
        assert isinstance(val, int)
        return val

    def create_display(
        self,
        x: float,
        y: float,
        delay: float,
        outdelay: float | None = None,
        color: Sequence[float] | None = None,
        style: str = 'post_game',
    ) -> list[bascenev1.Actor]:
        """Create a display for the Achievement.

        Shows the Achievement icon, name, and description.
        """
        # pylint: disable=cyclic-import
        from bascenev1 import CoopSession
        from bascenev1lib.actor.image import Image
        from bascenev1lib.actor.text import Text

        # Yeah this needs cleaning up.
        if style == 'post_game':
            in_game_colors = False
            in_main_menu = False
            h_attach = Text.HAttach.CENTER
            v_attach = Text.VAttach.CENTER
            attach = Image.Attach.CENTER
        elif style == 'in_game':
            in_game_colors = True
            in_main_menu = False
            h_attach = Text.HAttach.LEFT
            v_attach = Text.VAttach.TOP
            attach = Image.Attach.TOP_LEFT
        elif style == 'news':
            in_game_colors = True
            in_main_menu = True
            h_attach = Text.HAttach.CENTER
            v_attach = Text.VAttach.TOP
            attach = Image.Attach.TOP_CENTER
        else:
            raise ValueError('invalid style "' + style + '"')

        # Attempt to determine what campaign we're in
        # (so we know whether to show "hard mode only").
        if in_main_menu:
            hmo = False
        else:
            try:
                session = bascenev1.getsession()
                if isinstance(session, CoopSession):
                    campaign = session.campaign
                    assert campaign is not None
                    hmo = self._hard_mode_only and campaign.name == 'Easy'
                else:
                    hmo = False
            except Exception:
                logging.exception('Error determining campaign.')
                hmo = False

        objs: list[bascenev1.Actor]

        if in_game_colors:
            objs = []
            out_delay_fin = (delay + outdelay) if outdelay is not None else None
            if color is not None:
                cl1 = (2.0 * color[0], 2.0 * color[1], 2.0 * color[2], color[3])
                cl2 = color
            else:
                cl1 = (1.5, 1.5, 2, 1.0)
                cl2 = (0.8, 0.8, 1.0, 1.0)

            if hmo:
                cl1 = (cl1[0], cl1[1], cl1[2], cl1[3] * 0.6)
                cl2 = (cl2[0], cl2[1], cl2[2], cl2[3] * 0.2)

            objs.append(
                Image(
                    self.get_icon_texture(False),
                    host_only=True,
                    color=cl1,
                    position=(x - 25, y + 5),
                    attach=attach,
                    transition=Image.Transition.FADE_IN,
                    transition_delay=delay,
                    vr_depth=4,
                    transition_out_delay=out_delay_fin,
                    scale=(40, 40),
                ).autoretain()
            )
            txt = self.display_name
            txt_s = 0.85
            txt_max_w = 300
            objs.append(
                Text(
                    txt,
                    host_only=True,
                    maxwidth=txt_max_w,
                    position=(x, y + 2),
                    transition=Text.Transition.FADE_IN,
                    scale=txt_s,
                    flatness=0.6,
                    shadow=0.5,
                    h_attach=h_attach,
                    v_attach=v_attach,
                    color=cl2,
                    transition_delay=delay + 0.05,
                    transition_out_delay=out_delay_fin,
                ).autoretain()
            )
            txt2_s = 0.62
            txt2_max_w = 400
            objs.append(
                Text(
                    self.description_full if in_main_menu else self.description,
                    host_only=True,
                    maxwidth=txt2_max_w,
                    position=(x, y - 14),
                    transition=Text.Transition.FADE_IN,
                    vr_depth=-5,
                    h_attach=h_attach,
                    v_attach=v_attach,
                    scale=txt2_s,
                    flatness=1.0,
                    shadow=0.5,
                    color=cl2,
                    transition_delay=delay + 0.1,
                    transition_out_delay=out_delay_fin,
                ).autoretain()
            )

            if hmo:
                txtactor = Text(
                    babase.Lstr(resource='difficultyHardOnlyText'),
                    host_only=True,
                    maxwidth=txt2_max_w * 0.7,
                    position=(x + 60, y + 5),
                    transition=Text.Transition.FADE_IN,
                    vr_depth=-5,
                    h_attach=h_attach,
                    v_attach=v_attach,
                    h_align=Text.HAlign.CENTER,
                    v_align=Text.VAlign.CENTER,
                    scale=txt_s * 0.8,
                    flatness=1.0,
                    shadow=0.5,
                    color=(1, 1, 0.6, 1),
                    transition_delay=delay + 0.1,
                    transition_out_delay=out_delay_fin,
                ).autoretain()
                txtactor.node.rotate = 10
                objs.append(txtactor)

            # Ticket-award.
            award_x = -100
            objs.append(
                Text(
                    babase.charstr(babase.SpecialChar.TICKET),
                    host_only=True,
                    position=(x + award_x + 33, y + 7),
                    transition=Text.Transition.FADE_IN,
                    scale=1.5,
                    h_attach=h_attach,
                    v_attach=v_attach,
                    h_align=Text.HAlign.CENTER,
                    v_align=Text.VAlign.CENTER,
                    color=(1, 1, 1, 0.2 if hmo else 0.4),
                    transition_delay=delay + 0.05,
                    transition_out_delay=out_delay_fin,
                ).autoretain()
            )
            objs.append(
                Text(
                    '+' + str(self.get_award_ticket_value()),
                    host_only=True,
                    position=(x + award_x + 28, y + 16),
                    transition=Text.Transition.FADE_IN,
                    scale=0.7,
                    flatness=1,
                    h_attach=h_attach,
                    v_attach=v_attach,
                    h_align=Text.HAlign.CENTER,
                    v_align=Text.VAlign.CENTER,
                    color=cl2,
                    transition_delay=delay + 0.05,
                    transition_out_delay=out_delay_fin,
                ).autoretain()
            )

        else:
            complete = self.complete
            objs = []
            c_icon = self.get_icon_color(complete)
            if hmo and not complete:
                c_icon = (c_icon[0], c_icon[1], c_icon[2], c_icon[3] * 0.3)
            objs.append(
                Image(
                    self.get_icon_texture(complete),
                    host_only=True,
                    color=c_icon,
                    position=(x - 25, y + 5),
                    attach=attach,
                    vr_depth=4,
                    transition=Image.Transition.IN_RIGHT,
                    transition_delay=delay,
                    transition_out_delay=None,
                    scale=(40, 40),
                ).autoretain()
            )
            if complete:
                objs.append(
                    Image(
                        bascenev1.gettexture('achievementOutline'),
                        host_only=True,
                        mesh_transparent=bascenev1.getmesh(
                            'achievementOutline'
                        ),
                        color=(2, 1.4, 0.4, 1),
                        vr_depth=8,
                        position=(x - 25, y + 5),
                        attach=attach,
                        transition=Image.Transition.IN_RIGHT,
                        transition_delay=delay,
                        transition_out_delay=None,
                        scale=(40, 40),
                    ).autoretain()
                )
            else:
                if not complete:
                    award_x = -100
                    objs.append(
                        Text(
                            babase.charstr(babase.SpecialChar.TICKET),
                            host_only=True,
                            position=(x + award_x + 33, y + 7),
                            transition=Text.Transition.IN_RIGHT,
                            scale=1.5,
                            h_attach=h_attach,
                            v_attach=v_attach,
                            h_align=Text.HAlign.CENTER,
                            v_align=Text.VAlign.CENTER,
                            color=(1, 1, 1, (0.1 if hmo else 0.2)),
                            transition_delay=delay + 0.05,
                            transition_out_delay=None,
                        ).autoretain()
                    )
                    objs.append(
                        Text(
                            '+' + str(self.get_award_ticket_value()),
                            host_only=True,
                            position=(x + award_x + 28, y + 16),
                            transition=Text.Transition.IN_RIGHT,
                            scale=0.7,
                            flatness=1,
                            h_attach=h_attach,
                            v_attach=v_attach,
                            h_align=Text.HAlign.CENTER,
                            v_align=Text.VAlign.CENTER,
                            color=(0.6, 0.6, 0.6, (0.2 if hmo else 0.4)),
                            transition_delay=delay + 0.05,
                            transition_out_delay=None,
                        ).autoretain()
                    )

                    # Show 'hard-mode-only' only over incomplete achievements
                    # when that's the case.
                    if hmo:
                        txtactor = Text(
                            babase.Lstr(resource='difficultyHardOnlyText'),
                            host_only=True,
                            maxwidth=300 * 0.7,
                            position=(x + 60, y + 5),
                            transition=Text.Transition.FADE_IN,
                            vr_depth=-5,
                            h_attach=h_attach,
                            v_attach=v_attach,
                            h_align=Text.HAlign.CENTER,
                            v_align=Text.VAlign.CENTER,
                            scale=0.85 * 0.8,
                            flatness=1.0,
                            shadow=0.5,
                            color=(1, 1, 0.6, 1),
                            transition_delay=delay + 0.05,
                            transition_out_delay=None,
                        ).autoretain()
                        assert txtactor.node
                        txtactor.node.rotate = 10
                        objs.append(txtactor)

            objs.append(
                Text(
                    self.display_name,
                    host_only=True,
                    maxwidth=300,
                    position=(x, y + 2),
                    transition=Text.Transition.IN_RIGHT,
                    scale=0.85,
                    flatness=0.6,
                    h_attach=h_attach,
                    v_attach=v_attach,
                    color=(
                        (0.8, 0.93, 0.8, 1.0)
                        if complete
                        else (0.6, 0.6, 0.6, (0.2 if hmo else 0.4))
                    ),
                    transition_delay=delay + 0.05,
                    transition_out_delay=None,
                ).autoretain()
            )
            objs.append(
                Text(
                    self.description_complete if complete else self.description,
                    host_only=True,
                    maxwidth=400,
                    position=(x, y - 14),
                    transition=Text.Transition.IN_RIGHT,
                    vr_depth=-5,
                    h_attach=h_attach,
                    v_attach=v_attach,
                    scale=0.62,
                    flatness=1.0,
                    color=(
                        (0.6, 0.6, 0.6, 1.0)
                        if complete
                        else (0.6, 0.6, 0.6, (0.2 if hmo else 0.4))
                    ),
                    transition_delay=delay + 0.1,
                    transition_out_delay=None,
                ).autoretain()
            )
        return objs

    def _getconfig(self) -> dict[str, Any]:
        """
        Return the sub-dict in settings where this achievement's
        state is stored, creating it if need be.
        """
        val: dict[str, Any] = babase.app.config.setdefault(
            'Achievements', {}
        ).setdefault(self._name, {'Complete': False})
        assert isinstance(val, dict)
        return val

    def _remove_banner_slot(self) -> None:
        classic = babase.app.classic
        assert classic is not None
        assert self._completion_banner_slot is not None
        classic.ach.achievement_completion_banner_slots.remove(
            self._completion_banner_slot
        )
        self._completion_banner_slot = None

    def show_completion_banner(self, sound: bool = True) -> None:
        """Create the banner/sound for an acquired achievement announcement."""
        from bascenev1lib.actor.text import Text
        from bascenev1lib.actor.image import Image

        app = babase.app
        assert app.classic is not None
        app.classic.ach.last_achievement_display_time = babase.apptime()

        # Just piggy-back onto any current activity
        # (should we use the session instead?..)
        activity = bascenev1.getactivity(doraise=False)

        # If this gets called while this achievement is occupying a slot
        # already, ignore it. (probably should never happen in real
        # life but whatevs).
        if self._completion_banner_slot is not None:
            return

        if activity is None:
            print('show_completion_banner() called with no current activity!')
            return

        if sound:
            bascenev1.getsound('achievement').play(host_only=True)
        else:
            bascenev1.timer(
                0.5, lambda: bascenev1.getsound('ding').play(host_only=True)
            )

        in_time = 0.300
        out_time = 3.5

        base_vr_depth = 200

        # Find the first free slot.
        i = 0
        while True:
            if i not in app.classic.ach.achievement_completion_banner_slots:
                app.classic.ach.achievement_completion_banner_slots.add(i)
                self._completion_banner_slot = i

                # Remove us from that slot when we close.
                # Use an app-timer in an empty context so the removal
                # runs even if our activity/session dies.
                with babase.ContextRef.empty():
                    babase.apptimer(
                        in_time + out_time, self._remove_banner_slot
                    )
                break
            i += 1
        assert self._completion_banner_slot is not None
        y_offs = 110 * self._completion_banner_slot
        objs: list[bascenev1.Actor] = []
        obj = Image(
            bascenev1.gettexture('shadow'),
            position=(-30, 30 + y_offs),
            front=True,
            attach=Image.Attach.BOTTOM_CENTER,
            transition=Image.Transition.IN_BOTTOM,
            vr_depth=base_vr_depth - 100,
            transition_delay=in_time,
            transition_out_delay=out_time,
            color=(0.0, 0.1, 0, 1),
            scale=(1000, 300),
        ).autoretain()
        objs.append(obj)
        assert obj.node
        obj.node.host_only = True
        obj = Image(
            bascenev1.gettexture('light'),
            position=(-180, 60 + y_offs),
            front=True,
            attach=Image.Attach.BOTTOM_CENTER,
            vr_depth=base_vr_depth,
            transition=Image.Transition.IN_BOTTOM,
            transition_delay=in_time,
            transition_out_delay=out_time,
            color=(1.8, 1.8, 1.0, 0.0),
            scale=(40, 300),
        ).autoretain()
        objs.append(obj)
        assert obj.node
        obj.node.host_only = True
        obj.node.premultiplied = True
        combine = bascenev1.newnode(
            'combine', owner=obj.node, attrs={'size': 2}
        )
        bascenev1.animate(
            combine,
            'input0',
            {
                in_time: 0,
                in_time + 0.4: 30,
                in_time + 0.5: 40,
                in_time + 0.6: 30,
                in_time + 2.0: 0,
            },
        )
        bascenev1.animate(
            combine,
            'input1',
            {
                in_time: 0,
                in_time + 0.4: 200,
                in_time + 0.5: 500,
                in_time + 0.6: 200,
                in_time + 2.0: 0,
            },
        )
        combine.connectattr('output', obj.node, 'scale')
        bascenev1.animate(obj.node, 'rotate', {0: 0.0, 0.35: 360.0}, loop=True)
        obj = Image(
            self.get_icon_texture(True),
            position=(-180, 60 + y_offs),
            attach=Image.Attach.BOTTOM_CENTER,
            front=True,
            vr_depth=base_vr_depth - 10,
            transition=Image.Transition.IN_BOTTOM,
            transition_delay=in_time,
            transition_out_delay=out_time,
            scale=(100, 100),
        ).autoretain()
        objs.append(obj)
        assert obj.node
        obj.node.host_only = True

        # Flash.
        color = self.get_icon_color(True)
        combine = bascenev1.newnode(
            'combine', owner=obj.node, attrs={'size': 3}
        )
        keys = {
            in_time: 1.0 * color[0],
            in_time + 0.4: 1.5 * color[0],
            in_time + 0.5: 6.0 * color[0],
            in_time + 0.6: 1.5 * color[0],
            in_time + 2.0: 1.0 * color[0],
        }
        bascenev1.animate(combine, 'input0', keys)
        keys = {
            in_time: 1.0 * color[1],
            in_time + 0.4: 1.5 * color[1],
            in_time + 0.5: 6.0 * color[1],
            in_time + 0.6: 1.5 * color[1],
            in_time + 2.0: 1.0 * color[1],
        }
        bascenev1.animate(combine, 'input1', keys)
        keys = {
            in_time: 1.0 * color[2],
            in_time + 0.4: 1.5 * color[2],
            in_time + 0.5: 6.0 * color[2],
            in_time + 0.6: 1.5 * color[2],
            in_time + 2.0: 1.0 * color[2],
        }
        bascenev1.animate(combine, 'input2', keys)
        combine.connectattr('output', obj.node, 'color')

        obj = Image(
            bascenev1.gettexture('achievementOutline'),
            mesh_transparent=bascenev1.getmesh('achievementOutline'),
            position=(-180, 60 + y_offs),
            front=True,
            attach=Image.Attach.BOTTOM_CENTER,
            vr_depth=base_vr_depth,
            transition=Image.Transition.IN_BOTTOM,
            transition_delay=in_time,
            transition_out_delay=out_time,
            scale=(100, 100),
        ).autoretain()
        assert obj.node
        obj.node.host_only = True

        # Flash.
        color = (2, 1.4, 0.4, 1)
        combine = bascenev1.newnode(
            'combine', owner=obj.node, attrs={'size': 3}
        )
        keys = {
            in_time: 1.0 * color[0],
            in_time + 0.4: 1.5 * color[0],
            in_time + 0.5: 6.0 * color[0],
            in_time + 0.6: 1.5 * color[0],
            in_time + 2.0: 1.0 * color[0],
        }
        bascenev1.animate(combine, 'input0', keys)
        keys = {
            in_time: 1.0 * color[1],
            in_time + 0.4: 1.5 * color[1],
            in_time + 0.5: 6.0 * color[1],
            in_time + 0.6: 1.5 * color[1],
            in_time + 2.0: 1.0 * color[1],
        }
        bascenev1.animate(combine, 'input1', keys)
        keys = {
            in_time: 1.0 * color[2],
            in_time + 0.4: 1.5 * color[2],
            in_time + 0.5: 6.0 * color[2],
            in_time + 0.6: 1.5 * color[2],
            in_time + 2.0: 1.0 * color[2],
        }
        bascenev1.animate(combine, 'input2', keys)
        combine.connectattr('output', obj.node, 'color')
        objs.append(obj)

        objt = Text(
            babase.Lstr(
                value='${A}:',
                subs=[('${A}', babase.Lstr(resource='achievementText'))],
            ),
            position=(-120, 91 + y_offs),
            front=True,
            v_attach=Text.VAttach.BOTTOM,
            vr_depth=base_vr_depth - 10,
            transition=Text.Transition.IN_BOTTOM,
            flatness=0.5,
            transition_delay=in_time,
            transition_out_delay=out_time,
            color=(1, 1, 1, 0.8),
            scale=0.65,
        ).autoretain()
        objs.append(objt)
        assert objt.node
        objt.node.host_only = True

        objt = Text(
            self.display_name,
            position=(-120, 50 + y_offs),
            front=True,
            v_attach=Text.VAttach.BOTTOM,
            transition=Text.Transition.IN_BOTTOM,
            vr_depth=base_vr_depth,
            flatness=0.5,
            transition_delay=in_time,
            transition_out_delay=out_time,
            flash=True,
            color=(1, 0.8, 0, 1.0),
            scale=1.5,
        ).autoretain()
        objs.append(objt)
        assert objt.node
        objt.node.host_only = True

        objt = Text(
            babase.charstr(babase.SpecialChar.TICKET),
            position=(-120 - 170 + 5, 75 + y_offs - 20),
            front=True,
            v_attach=Text.VAttach.BOTTOM,
            h_align=Text.HAlign.CENTER,
            v_align=Text.VAlign.CENTER,
            transition=Text.Transition.IN_BOTTOM,
            vr_depth=base_vr_depth,
            transition_delay=in_time,
            transition_out_delay=out_time,
            flash=True,
            color=(0.5, 0.5, 0.5, 1),
            scale=3.0,
        ).autoretain()
        objs.append(objt)
        assert objt.node
        objt.node.host_only = True

        objt = Text(
            '+' + str(self.get_award_ticket_value()),
            position=(-120 - 180 + 5, 80 + y_offs - 20),
            v_attach=Text.VAttach.BOTTOM,
            front=True,
            h_align=Text.HAlign.CENTER,
            v_align=Text.VAlign.CENTER,
            transition=Text.Transition.IN_BOTTOM,
            vr_depth=base_vr_depth,
            flatness=0.5,
            shadow=1.0,
            transition_delay=in_time,
            transition_out_delay=out_time,
            flash=True,
            color=(0, 1, 0, 1),
            scale=1.5,
        ).autoretain()
        objs.append(objt)
        assert objt.node
        objt.node.host_only = True

        # Add the 'x 2' if we've got pro.
        if app.classic.accounts.have_pro():
            objt = Text(
                'x 2',
                position=(-120 - 180 + 45, 80 + y_offs - 50),
                v_attach=Text.VAttach.BOTTOM,
                front=True,
                h_align=Text.HAlign.CENTER,
                v_align=Text.VAlign.CENTER,
                transition=Text.Transition.IN_BOTTOM,
                vr_depth=base_vr_depth,
                flatness=0.5,
                shadow=1.0,
                transition_delay=in_time,
                transition_out_delay=out_time,
                flash=True,
                color=(0.4, 0, 1, 1),
                scale=0.9,
            ).autoretain()
            objs.append(objt)
            assert objt.node
            objt.node.host_only = True

        objt = Text(
            self.description_complete,
            position=(-120, 30 + y_offs),
            front=True,
            v_attach=Text.VAttach.BOTTOM,
            transition=Text.Transition.IN_BOTTOM,
            vr_depth=base_vr_depth - 10,
            flatness=0.5,
            transition_delay=in_time,
            transition_out_delay=out_time,
            color=(1.0, 0.7, 0.5, 1.0),
            scale=0.8,
        ).autoretain()
        objs.append(objt)
        assert objt.node
        objt.node.host_only = True

        for actor in objs:
            bascenev1.timer(
                out_time + 1.000,
                babase.WeakCall(actor.handlemessage, bascenev1.DieMessage()),
            )


"""Modulo principal.
Le os argumentos do input do usuario.
"""

import Matrix
import Print
import DigitClassifier
import numpy as np
import time
import os
import ctypes

def parte1():
    print("\nParte 1\n----------------------\nRot-givens\n")
    print("item a)")
    n = m = 64
    W = np.zeros((n, m))
    b = np.zeros((n, 1))
    for i in range(n):
        b[i] = 1
        W[i][i] = 2
        for j in range(m):
            if abs(i-j) == 1:
                W[i][j] = 1
            elif abs(i-j) > 1:
                W[i][j] = 0
    x_ref = np.linalg.solve(W, b)
    x = Matrix.solveLinear(W, n, m, b)

    max_err = Matrix.maxError(x_ref, x)
    print("erro absoluto maximo = %e" %max_err)
    print("solucao de referencia: ")
    print(np.transpose(x_ref))
    print("solucao obtida: ")
    Print.okGreen(x)

    print("\nitem b)")
    n = 20
    m = 17
    W = np.zeros((n, m))
    b = np.zeros((n, 1))
    for i in range(n):
        b[i] = i+1
        for j in range(m):
            if abs(i-j) <= 4:
                W[i][j] = 1/(i+1+j)
            else:
                W[i][j] = 0
    x_ref = np.linalg.lstsq(W, b, rcond=None)[0]
    x = Matrix.solveLinear(W, n, m, b)

    max_err = Matrix.maxError(x_ref, x)
    print("erro absoluto maximo = %e" %max_err)
    print("solucao de referencia: ")
    print(x_ref[:,0])
    print("solucao obtida: ")
    Print.okGreen(x)

def parte2():
    print("\nParte 2\n----------------------\nVarios sistemas simultaneos\n")
    print("item a)")
    n = p= 64
    m = 3
    A = np.zeros((n, m))
    W = np.zeros((n, p))
    b1 = np.zeros((n, 1))
    b2 = np.zeros((n, 1))
    b3 = np.zeros((n, 1))

    for i in range(n):
        for j in range(p):
            if abs(i-j) == 1:
                W[i][j] = 1
            elif abs(i-j) > 1:
                W[i][j] = 0
            elif i==j:
                W[i][i] = 2
        for k in range(m):
            if k == 0:
                b1[i] = 1
                A[i][k] = 1
            elif k == 1:
                b2[i] = i+1
                A[i][k] = i+1
            elif k == 2:
                b3[i] = 2*i+1
                A[i][k] = 2*i+1

    x_ref1 = np.linalg.lstsq(W, b1, rcond=None)[0]
    x_ref2 = np.linalg.lstsq(W, b2, rcond=None)[0]
    x_ref3 = np.linalg.lstsq(W, b3, rcond=None)[0]

    x = Matrix.solveMultipleLinear(W, n, m, p, A)
    x1 = x[:,0]
    x2 = x[:,1]
    x3 = x[:,2]

    print("solucao de referencia (sistema 1): ")
    print(x_ref1[:,0])
    print("solucao obtida (sistema 1): ")
    Print.okGreen(x1)
    print("\nsolucao de referencia (sistema 2): ")
    print(x_ref2[:,0])
    print("solucao obtida (sistema 2): ")
    Print.okGreen(x2)
    print("\nsolucao de referencia (sistema 3): ")
    print(x_ref3[:,0])
    print("solucao obtida (sistema 3): ")
    Print.okGreen(x3)

    max_err = Matrix.maxError(x_ref1, x1)
    print("\nerro absoluto maximo 1 = %e" %max_err)
    max_err = Matrix.maxError(x_ref2, x2)
    print("erro absoluto maximo 2 = %e" %max_err)
    max_err = Matrix.maxError(x_ref3, x3)
    print("erro absoluto maximo 3 = %e" %max_err)

    print("\nitem b)")
    n = 20
    p = 17
    m = 3
    A = np.zeros((n, m))
    W = np.zeros((n, p))
    b1 = np.zeros((n, 1))
    b2 = np.zeros((n, 1))
    b3 = np.zeros((n, 1))

    for i in range(n):
        for j in range(p):
            if abs(i-j) <= 4:
                W[i][j] = 1/(i+1+j)
            else:
                W[i][j] = 0
        for k in range(m):
            if k == 0:
                b1[i] = 1
                A[i][k] = 1
            elif k == 1:
                b2[i] = i+1
                A[i][k] = i+1
            elif k == 2:
                b3[i] = 2*i+1
                A[i][k] = 2*i+1

    x_ref1 = np.linalg.lstsq(W, b1, rcond=None)[0]
    x_ref2 = np.linalg.lstsq(W, b2, rcond=None)[0]
    x_ref3 = np.linalg.lstsq(W, b3, rcond=None)[0]

    x = Matrix.solveMultipleLinear(W, n, m, p, A)
    x1 = x[:,0]
    x2 = x[:,1]
    x3 = x[:,2]

    print("solucao de referencia (sistema 1): ")
    print(x_ref1[:,0])
    print("solucao obtida (sistema 1): ")
    Print.okGreen(x1)
    print("\nsolucao de referencia (sistema 2): ")
    print(x_ref2[:,0])
    print("solucao obtida (sistema 2): ")
    Print.okGreen(x2)
    print("\nsolucao de referencia (sistema 3): ")
    print(x_ref3[:,0])
    print("solucao obtida (sistema 3): ")
    Print.okGreen(x3)

    max_err = Matrix.maxError(x_ref1, x1)
    print("\nerro absoluto maximo 1 = %e" %max_err)
    max_err = Matrix.maxError(x_ref2, x2)
    print("erro absoluto maximo 2 = %e" %max_err)
    max_err = Matrix.maxError(x_ref3, x3)
    print("erro absoluto maximo 3 = %e" %max_err)

def parte3():
    print("\nParte 3\n----------------------\nFatoracao por matrizes nao negativas\n")
    A = [[3/10, 3/5, 0], [1/2, 0, 1], [4/10, 4/5, 0]]
    n = m = 3
    p = 2
    W, H = Matrix.NMF(A, n, m, p)
    print("\nmatriz W:")
    Print.okGreen(W)
    print("matriz H:")
    Print.okGreen(H)

def parte4():
    Print.warning("*** Dependendo dos valores dos parametros, o tempo de execucao pode ser muito alto. ***\n")
    parte4_teste1()
    voltar = False
    while not voltar:
        escolher = input("Deseja escolher valores para os parametros? (s/n): ")
        if escolher == "s":
            parte4_escolher()
        elif escolher == "n":
            voltar = True
        else:
            Print.fail("Opcao invalida! Tente novamente.")

def parte4_teste1():
    ndig_treino = 18
    p = 10
    n_test = 1000
    parte4_rodar(ndig_treino, p, n_test)

def parte4_escolher():
    ndig_treino = int(input("Escolha um valor para ndig_treino: "))
    p = int(input("Escolha um valor para p: "))
    n_test = int(input("Escolha um valor para n_test: "))
    parte4_rodar(ndig_treino, p, n_test)

def parte4_rodar(ndig_treino, p, n_test):
    instance = DigitClassifier.DigitClassifier(p, ndig_treino, n_test)
    Print.okBlue("Teste: ndig_treino = %d p = %d n_test = %d\n----------------------" %(ndig_treino, p, n_test))
    Print.okBlue("Treinando os classificadores...")
    start_time = time.time()
    instance.train()
    Print.okBlue("Feito em %.3f segundos!"%(time.time() - start_time))
    Print.okBlue("Rodando os testes...")
    start_time = time.time()
    instance.test()
    Print.okBlue("Feito em %.3f segundos!"%(time.time() - start_time))
    hitRate, _, hitRatePerDigit = instance.results()
    Print.okGreen("Porcentual total de acertos: %.2f" %hitRate)
    Print.okGreen("Porcentual de acertos por digito:")
    for i in range(10):
        Print.okGreen("%d: %.2f" %(i, hitRatePerDigit[i]))

def printOptions():
    Print.header("\n----------------------\n(1) Rot-givens\n(2) Varios sistemas simultaneos\n(3) Fatoracao por matrizes nao negativas\n(4) Classificacao de digitos")
    Print.header("(q) Sair")

def isWindows():
    return os.name == 'nt'

def main():
    """Main function.
    """
    # enabling Virtual Terminal Processing for Windows to print colorful output!
    if isWindows():
        kernel32 = ctypes.windll.kernel32
        kernel32.SetConsoleMode(kernel32.GetStdHandle(-11), 7)
    Print.bold("\nBem vindo ao EP1 de MAP3121!")
    exit = False
    while not exit:
        printOptions()
        item = input("\nEscolha uma parte do exercicio: ")
        if item == "1":
            parte1()
        elif item == "2":
            parte2()
        elif item == "3":
            parte3()
        elif item == "4":
            parte4()
        elif item == "q":
            exit = True
            Print.okBlue("Fim do programa.")
        else:
            Print.fail("Opcao invalida! Tente novamente.")

if __name__ == "__main__":
    main()


#!/usr/bin/python3

"""defines a class Square that inherits from Rectangle"""
Rectangle = __import__('9-rectangle').Rectangle

class Square(Rectangle):
    """represents a class Square"""

    def __init__(self, size):
        """instantiate Square with private attribute size"""

        self.integer_validator("size", size)
        super().__init__(size, size)
        self.__size = size


import sys
import pandas as pd
import sqlite3
import z_service

def make_fedtbl(sq_conn):
    dtfReg=pd.read_csv(r'C:\Documents and Settings\ggolyshev\PycharmProjects\Cities\Base\regionsF.csv',
                       sep=';', encoding='cp1251')
    dtfFO=dtfReg[['FederalDistrictName', 'FederalDistrictID']].drop_duplicates(['FederalDistrictName', 'FederalDistrictID'])
    dtfFO.rename(columns={'FederalDistrictName':'name', 'FederalDistrictID':'ID'}, inplace=True)
    dtfFO.to_sql('FDistricts', sq_conn, if_exists='replace', index_label='ID',
                 index=False, dtype={'name':'TEXT', 'ID':'INTEGER'})
    return dtfFO

def make_cities_db(sq_conn):
    dtfCities=pd.read_csv(r'C:\Documents and Settings\ggolyshev\PycharmProjects\Cities\Base\info.csv',
                       sep=';', encoding='cp1251')[['norm_name', 'name', 'norm_reg', 'href', 'lat', 'long', 'okato',
                       'oktmo', 'people', 'square', 'height', 'phone_code', 'post_index', 'timezone']]
    dtfCities['oktmo']=dtfCities['oktmo'].apply(lambda x: z_service.codes_correct(x, iSize=11))

    dtfCities.to_sql('Localities', sq_conn, if_exists='replace', index_label='oktmo',
                 index=False, dtype={'norm_name':'TEXT', 'name':'TEXT', 'norm_reg':'TEXT', 'href':'TEXT',
                                     'lat':'REAL', 'long':'REAL', 'okato':'TEXT',
                       'oktmo':'TEXT', 'people':'INTEGER', 'square':'REAL', 'height':'REAL',
                                     'phone_code':'TEXT', 'post_index':'TEXT', 'timezone':'TEXT'})
    return dtfCities

def connect(strDBName):
    return sqlite3.connect(strDBName)

def make_vliages_db(con):
    dtfVil=pd.read_csv(r'C:\Documents and Settings\ggolyshev\PycharmProjects\Cities\Base\villages_info.csv',
                       sep=';', encoding='cp1251', dtype=str)[['name', 'okato1', 'okato2', 'oktmo', 'name2',
                                                               'oktmo_parent', 'name_parent', 'type', 'norm_name']]

    dtfVil=dtfVil.drop(dtfVil[dtfVil['oktmo'].isnull()].index)
    msk=dtfVil['oktmo'].str.len()==11

    dtfVil[msk].to_sql('All_Places', con, if_exists='replace', index_label='oktmo',
                     index=False, dtype={'name': 'TEXT', 'okato1': 'TEXT', 'okato2': 'TEXT', 'oktmo':
                                          'TEXT', 'name2': 'TEXT', 'oktmo_parent': 'TEXT',
                                           'name_parent': 'TEXT', 'type': 'TEXT', 'norm_name': 'TEXT'})

    return dtfVil[msk]

def make_munobr_db(con):
    dtfVil = pd.read_csv(r'C:\Documents and Settings\ggolyshev\PycharmProjects\Cities\Base\villages_info.csv',
                         sep=';', encoding='cp1251', dtype=str)[['name', 'okato1', 'okato2', 'oktmo', 'name2',
                                                                 'oktmo_parent', 'name_parent', 'type', 'norm_name']]

    dtfVil = dtfVil.drop(dtfVil[dtfVil['oktmo'].isnull()].index)
    msk = dtfVil['oktmo'].str.len() == 11

    #sign_budget
    #oktmo_budget
    #name_budget
    dtfRet = pd.read_csv(r'C:\Documents and Settings\ggolyshev\PycharmProjects\Cities\Base\munobr01042016.csv',
                         sep=';', encoding='cp1251', dtype=str)[['name', 'type', 'okato', 'oktmo', 'name2',
                                                                 'sign_budget', 'oktmo_budget', 'name_budget',
                                                                 'oktmo_parent', 'name_parent']]

    lst=dtfRet.columns.tolist()
    lstT=['TEXT'] * len(lst)

    dtfRet=dtfRet.append(dtfVil[~msk])
    dtfRet.to_sql('MunObrs', con, if_exists='replace',
                       index=False, dtype=dict(zip(lst, lstT)))

    return dtfRet

def main():
    conn = connect(r'cities.sqlite')
    pdf=pd.read_sql('select * from All_Places', conn)
    print(pdf)
    #print(make_munobr_db(conn).shape)
    #print(make_vliages_db(conn))
    #print(make_cities_db(conn).shape)
    #print(make_fedtbl(conn))

if __name__ == "__main__":
    sys.exit(main())


import unittest

from poly.edge import Edge
from poly.point import Point
from poly.polygon import Polygon

import random

class TestPolygon(unittest.TestCase):

    def test_weakSimple(self):
        """See Wikipedia for entry on weakly simple polygon."""
        m = Point(0, 0)
        a = Point(0, 4)
        b = Point(8, 4)
        c = Point(8, 0)
        d = Point(4, 0)
        e = Point(4, 1)
        f = Point(6, 1)
        g = Point(6, 3)
        h = Point(2, 3)
        j = Point(2, 1)
        k = Point(4, 1)  # same as e
        l = Point(4, 0)  # same as d
        p = Polygon([a, b, c, d, e, f, g, h, j, k, l, m])
        self.assertTrue(p.simple())

    def test_nonIntersectSimplePolygonsOnEndPoints(self):
        a = Point(0, 0)
        b = Point(-2, 2)
        c = Point(2, 2)

        d = Point(-2, -2)
        e = Point(2, -2)

        p = Polygon([a, b, c])
        q = Polygon([a, d, e])

        self.assertFalse(p.intersect(q))

    def test_canIntersectEndPointWithRealIntersection(self):
        e = Edge (Point(0, 0), Point(2, 2))
        f = Edge (Point(-2, 2), Point(2, -2))

        self.assertTrue(e.intersect(f))

    def test_nonIntersectEndPoints(self):
        p = Point(0, 0)

        e = Edge (p, Point(2, 3))
        f = Edge (p, Point(-2, 3))

        self.assertIsNone(e.intersect(f))


import traceback

from aiogram import Router, F
from aiogram import types
from aiogram.fsm.context import FSMContext
from datetime import datetime, timedelta

from config_reader import myvars, DEBUG
from filters.permission import check_permission
from handlers.superuser_menu import InputData
from keyboards.for_doctor import run_calendar, get_kb_doctor_menu, get_kb_doctor_selected_day, \
    get_kb_doctor_selected_patient
from libs.db_lib import pg_select_one_column as pg_soc, pg_execute, pg_select
from libs.dictanotry_lib import to_ru_dayofweek, to_ru_month3
from libs.google_ss import update_cell, google_get_vars
from libs.load_vars import update_appointments
from main import logger

router = Router()

async def get_user_data(callback: types.CallbackQuery, state: FSMContext):
    user_data = await state.get_data()
    user_data['doctor_id'] = callback.message.chat.id
    user_data['appt_format'] = 'closed'
    user_data['hours'] = [10, 11, 12, 13, 14, 15, 16]
    for key in myvars.doctors.keys():
        if myvars.doctors[key]['tid'] == callback.message.chat.id:
            user_data['doctor'] = key
    return user_data

@router.callback_query(F.data == "cb_doctor_workday_appt")
async def doctor_workday_appt(callback: types.CallbackQuery):
    await callback.message.delete()
    await callback.message.answer("Выбор дня:", reply_markup=await run_calendar())
    await callback.answer("")

@router.callback_query(F.data.startswith("callback_doctor_calendar"))
async def pick_doctor_date(callback: types.CallbackQuery, state: FSMContext):
    action = callback.data.split(":")[1]
    year = callback.data.split(":")[2]
    month = callback.data.split(":")[3]
    day = callback.data.split(":")[4]

    await state.update_data(year=year)
    await state.update_data(month=month)
    await state.update_data(day=day)
    await state.update_data(user_tid=callback.from_user.id)

    temp_date = datetime(int(year), int(month), 1)
    if action == 'PREV-MONTH':
        prev_date = temp_date - timedelta(days=31)
        await callback.message.edit_reply_markup(reply_markup=await run_calendar(year=int(prev_date.year), month=int(prev_date.month)))
    if action == 'NEXT-MONTH':
        next_date = temp_date + timedelta(days=31)
        await callback.message.edit_reply_markup(reply_markup=await run_calendar(year=int(next_date.year), month=int(next_date.month)))
    if action == "SELECTED":
        query = f"SELECT id FROM tb_appointments WHERE date(appt_date) = date('{year}-{month}-{day}') and is_closed = 1"
        res = pg_soc(query)
        # status_apt = ''
        if len(res) > 0:
            status_apt = 'закрыта'
        else:
            status_apt = 'открыта'
        day_of_week = to_ru_dayofweek[datetime(year=int(year), month=int(month), day=int(day)).weekday()]
        text = f' {day_of_week}\n' + \
            f'{day} {to_ru_month3[int(month)]} {year}\n' + \
            '━━━━━━━━━━━━━━━\n' + \
            f'Запись: {status_apt}'
        await callback.message.delete()
        await callback.message.answer(text=text, reply_markup=await get_kb_doctor_selected_day(state))
        await callback.answer("Успешно")
    if action == "BACK":
        await callback.message.delete()
        await callback.message.answer(f'Меню', reply_markup=await get_kb_doctor_menu(state))
        await state.clear()
        await callback.answer('')
    if action == "IGNORE":
        await callback.answer('Выберите число')

@router.callback_query(F.data.startswith("cb_doctor_close_appt_exec"))
async def doctor_close_appt(callback: types.CallbackQuery, state: FSMContext):
    user_data = await get_user_data(callback, state)

    try:
        user_data['spreadsheet_id'] = myvars.doctors[user_data['doctor']]['spreadsheet_id']
        service, sheets, title = await google_get_vars(user_data, callback)

        for hour in user_data['hours']:
            appt_date = datetime(year=int(user_data['year']), month=int(user_data['month']), day=int(user_data['day']), hour=hour)

            # Проверка существует ли запись на этот день и время
            query = f"SELECT EXISTS (SELECT cid FROM tb_appointments WHERE appt_date = '{appt_date}'::timestamp)"
            res = pg_soc(query)[0]
            if res:
                query = f"UPDATE tb_appointments SET is_closed = 1 WHERE appt_date = '{appt_date}'::timestamp"
                pg_execute(query)
            else:
                query = f"INSERT INTO tb_appointments (is_closed, cid, doctor_id, appt_format, appt_date) " + \
                        f"SELECT 1, id, {int(user_data['doctor_id'])}, '{user_data['appt_format']}', '{appt_date}' " \
                        f"FROM tb_customers WHERE tid = {int(user_data['doctor_id'])}"
                pg_execute(query)

            await callback.answer('БД обновлена. Обновляется Google таблица', cache_time=35)

            if DEBUG == 0:
                await update_cell(myvars.doctors[user_data['doctor']]['spreadsheet_id'], int(hour),
                                  int(user_data['month']), int(user_data['year']),
                                  int(user_data['day']), user_data['appt_format'], service, sheets, title)
            else:
                await update_cell(myvars.doctors['Соболевский В.А.']['spreadsheet_id'], int(hour),
                                  int(user_data['month']), int(user_data['year']),
                                  int(user_data['day']), user_data['appt_format'], service, sheets, title)

        await update_appointments()
        await callback.message.delete()
        # await callback.answer('Успешно')

    except Exception as e:
        logger.error(f"exception: {e} traceback: {traceback.format_exc()}")

@router.callback_query(F.data.startswith("cb_doctor_open_appt_exec"))
async def doctor_open_appt(callback: types.CallbackQuery, state: FSMContext):
    user_data = await get_user_data(callback, state)

    try:
        user_data['spreadsheet_id'] = myvars.doctors[user_data['doctor']]['spreadsheet_id']
        service, sheets, title = await google_get_vars(user_data, callback)

        for hour in user_data['hours']:
            appt_date = datetime(year=int(user_data['year']), month=int(user_data['month']), day=int(user_data['day']),
                                 hour=hour)

            # Проверка существует ли запись на этот день и время от пациента
            query = f"SELECT EXISTS (SELECT cid FROM tb_appointments " \
                    f"WHERE appt_date = '{appt_date}'::timestamp and " \
                    f"cid  != (SELECT id FROM tb_customers WHERE tid = doctor_id))"
            print(query)
            res = pg_soc(query)[0]
            value = None
            if res:
                query = "SELECT lastname, name, surname, appt_format FROM tb_customers as cu " \
                        "LEFT JOIN tb_appointments as ap ON cu.id = ap.cid " \
                        f"WHERE (appt_date = '{appt_date}'::timestamp)"
                rows = pg_select(query)
                for row in rows:
                    value = f"openedФИО: {row[0]} {row[1]} {row[2]}\n Формат: {row[3]}"
                query = f"UPDATE tb_appointments SET is_closed = 0 " \
                        f"WHERE appt_date = '{appt_date}'::timestamp and " \
                        f"cid  != (SELECT id FROM tb_customers WHERE tid = doctor_id)"
                pg_execute(query)
            else:
                value = "opened"
                query = f"DELETE FROM tb_appointments " \
                        f"WHERE appt_date = '{appt_date}'::timestamp and is_closed=1"
                pg_execute(query)

            await callback.answer('БД обновлена. Обновляется Google таблица', cache_time=35)
            if DEBUG == 1:
                await update_cell(myvars.doctors['Соболевский В.А.']['spreadsheet_id'], int(hour),
                                  int(user_data['month']), int(user_data['year']),
                                  int(user_data['day']),
                                  value, service, sheets, title)
            else:
                await update_cell(myvars.doctors[user_data['doctor']]['spreadsheet_id'], int(hour),
                                  int(user_data['month']), int(user_data['year']),
                                  int(user_data['day']), value, service, sheets, title)

        await update_appointments()
        await callback.message.delete()
        # await callback.answer('Успешно')

    except Exception as e:
        logger.error(f"exception: {e} traceback: {traceback.format_exc()}")

@router.callback_query(F.data == "cb_doctor_patients")
async def set_doctor(callback: types.CallbackQuery, state: FSMContext):
    is_superuser = await check_permission(myvars.superuser, callback=callback)
    is_doctor = await check_permission(myvars.doctors, callback=callback)

    if is_superuser or is_doctor:
        await state.update_data(role="patient")
        await callback.message.delete()
        await callback.message.answer("Введите фамилию или её часть для поиска:")
        await callback.answer("")
        await state.set_state(InputData.lastname)
    else:
        await callback.message.delete()
        await callback.answer("")

@router.callback_query(F.data.startswith("cb_doctor_search_user_result_"))
async def manage_seleted_patient(callback: types.CallbackQuery, state: FSMContext):
    is_superuser = await check_permission(myvars.superuser, callback=callback)
    is_doctor = await check_permission(myvars.doctors, callback=callback)
    if is_superuser or is_doctor:
        role = callback.data.split("_")[5]
        tid = int(callback.data.split("_")[6])
        await state.update_data(selected_user=tid)
        user_data = await state.get_data()

        await callback.message.delete()
        text = f"Пациент\n" \
               f"━━━━━━━━━━━━━━━\n" \
               f"{[tid]} {user_data['search_user'][tid]['lastname']} " \
               f"{user_data['search_user'][tid]['name']} {user_data['search_user'][tid]['surname']}"

        await callback.message.answer(text=text, reply_markup=await get_kb_doctor_selected_patient())
        await callback.answer("")
    else:
        await callback.message.delete()
        await callback.answer("")

@router.callback_query(F.data == "cb_doctor_get_patient_files")
async def set_doctor(callback: types.CallbackQuery, state: FSMContext):
    user_data = await state.get_data()
    tid = user_data['selected_user']

    # media_group_photo = []
    # media_group_doc = []
    query = f"SELECT file_id, file_type " \
            f"FROM tb_files as f " \
            f"LEFT JOIN tb_customers as cu " \
            f"ON cu.id = f.cid " \
            f"WHERE cu.tid={tid} " \
            f"ORDER BY created DESC"
    print(query)
    rows = pg_select(query)
    for row in rows:
        if row[1] == 'photo':
            # media_group_photo.append(InputMediaPhoto(media=row[0]))
            # await callback.message.answer_media_group(media_group)
            await callback.message.answer_photo(photo=row[0])
        elif row[1] == 'document':
            # media_group_doc.append(InputMediaDocument(media=row[0]))
            await callback.message.answer_document(document=row[0])
        elif row[1] == 'audio':
            await  callback

    # await callback.message.answer_media_group(media_group_photo)
    # await callback.message.answer_media_group(media_group_doc)
    # await callback.message.do answer_media_group(media_group_doc)
    await callback.message.answer("Загрузка завершена")
    await callback.answer("Успешно")


import os

from bcitp.utils.standards import PATH_TO_SESSION

from kivy.uix.screenmanager import Screen
from kivy.properties import ObjectProperty, StringProperty

class StartScreen(Screen):
    # layout
    session_name = ObjectProperty(None)
    label_msg = StringProperty('')

    def __init__(self, session_header, **kwargs):
        super(StartScreen, self).__init__(**kwargs)

        self.sh = session_header

    def change_to_gen_settings(self, *args):
        self.manager.current = 'GeneralSettings'
        self.manager.transition.direction = 'left'

    def change_to_bci(self, *args):

        self.manager.current = 'BCIMenu'
        self.manager.transition.direction = 'left'

    def save_session_name(self, *args):

        sname = self.session_name.text

        if not os.path.isdir(PATH_TO_SESSION):
            os.makedirs(PATH_TO_SESSION)

        if sname == '':
            # if no session_name is provided, use latest modified folder in
            # data/session
            all_subdirs = []
            for d in os.listdir(PATH_TO_SESSION + '.'):
                bd = os.path.join(PATH_TO_SESSION, d)
                if os.path.isdir(bd):
                    all_subdirs.append(bd)
            sname = max(all_subdirs, key=os.path.getmtime).split('/')[-1]

        self.sh.info.name = sname

        if os.path.isdir(PATH_TO_SESSION + sname):

            self.label_msg = "Session " + sname \
                + " already exists. Data will be overwritten"
            self.sh.loadFromPkl()

        else:
            os.makedirs(PATH_TO_SESSION + sname)
            self.sh.saveToPkl()
            self.label_msg = "Session Saved as: " + sname
            self.sh.info.flag = True


class Solution:
    def repeatedNTimes(self, A: List[int]) -> int:
        d={}
        max=0
        maxKey=0
        for i in A:
            if i not in d:
                d[i]=1
            else:
                d[i]+=1
        for i in d:
            if d[i]>max:
                max=d[i]
                maxKey=i
        return maxKey
#https://leetcode.com/problems/n-repeated-element-in-size-2n-array/submissions/


from snappy.snap import t3mlite as t3m
from snappy.snap.mcomplex_base import *
from snappy.SnapPy import matrix

from .hyperboloid_utilities import *

__all__ = ['RaytracingData']

class RaytracingData(McomplexEngine):
    def add_weights(self, weights):
        for tet in self.mcomplex.Tetrahedra:
            tet.Weights = {
                F : weights[4 * tet.Index + f] if weights else 0.0
                for f, F in enumerate(t3m.TwoSubsimplices)}

    def get_uniform_bindings(self):
        d = {}
        d['TetrahedraCombinatorics.otherTetNums'] = (
            'int[]',
            [ tet.Neighbor[F].Index
              for tet in self.mcomplex.Tetrahedra
              for F in t3m.TwoSubsimplices ])

        d['TetrahedraCombinatorics.otherFaceNums'] = (
            'int[]',
            [ tet.Gluing[F][f]
              for tet in self.mcomplex.Tetrahedra
              for f, F in enumerate(t3m.TwoSubsimplices) ])

        d['TetrahedraBasics.SO13tsfms'] = (
            'mat4[]',
            [ tet.O13_matrices[F]
              for tet in self.mcomplex.Tetrahedra
              for F in t3m.TwoSubsimplices ])

        d['TetrahedraBasics.planes'] = (
            'vec4[]',
            [ tet.R13_planes[F]
              for tet in self.mcomplex.Tetrahedra
              for F in t3m.TwoSubsimplices ])

        d['TetrahedraBasics.R13Vertices'] = (
            'vec4[]',
            [ tet.R13_vertices[V]
              for tet in self.mcomplex.Tetrahedra
              for V in t3m.ZeroSubsimplices ])

        d['Colors.face_color_indices'] = (
            'int[]',
            [ tet.Class[F].Index
              for tet in self.mcomplex.Tetrahedra
              for F in t3m.TwoSubsimplices ])

        d['Colors.edge_color_indices'] = (
            'int[]',
            [ tet.Class[E].Index
              for tet in self.mcomplex.Tetrahedra
              for E in t3m.OneSubsimplices ])

        d['Colors.vertex_color_indices'] = (
            'int[]',
            [ tet.Class[V].Index
              for tet in self.mcomplex.Tetrahedra
              for V in t3m.ZeroSubsimplices ])

        d['weights'] = (
            'float[]',
            [ tet.Weights[F]
              for tet in self.mcomplex.Tetrahedra
              for F in t3m.TwoSubsimplices ])

        return d

    def get_compile_time_constants(self):
        d = {}
        d[b'##num_tets##'] = len(self.mcomplex.Tetrahedra)
        d[b'##num_cusps##'] = len(self.mcomplex.Vertices)
        d[b'##num_edges##'] = len(self.mcomplex.Edges)
        return d

    def update_view_state(self, boost_tet_num_and_weight,
                          m = matrix([[1.0, 0.0, 0.0, 0.0],
                                      [0.0, 1.0, 0.0, 0.0],
                                      [0.0, 0.0, 1.0, 0.0],
                                      [0.0, 0.0, 0.0, 1.0]])):
        boost, tet_num, weight = boost_tet_num_and_weight

        boost = matrix(boost, ring = self.RF)
        m = matrix(m, ring = self.RF)

        boost = O13_orthonormalize(boost * m)

        entry_F = -1

        for i in range(100):
            pos = boost.transpose()[0]
            tet = self.mcomplex.Tetrahedra[tet_num]

            amount, F = max(
                [ (r13_dot(pos, tet.R13_planes[F]), F)
                  for F in t3m.TwoSubsimplices ])

            if F == entry_F:
                break
            if amount < 0.0000001:
                break

            boost = O13_orthonormalize(tet.O13_matrices[F] * boost)
            tet_num = tet.Neighbor[F].Index
            entry_F = tet.Gluing[F].image(F)
            weight += tet.Weights[F]

        return boost, tet_num, weight


import json
from unittest import mock
import pytest

from intergov.repos.message_lake.minio.miniorepo import MessageLakeMinioRepo
from tests.unit.domain.wire_protocols.test_generic_message import _generate_msg_object

CONNECTION_DATA = {
    'host': 'minio.host',
    'port': 1000,
    'access_key': 'access_key',
    'secret_key': 'secret_key',
    'bucket': 'bucket',
    'use_ssl': False
}

@mock.patch('intergov.repos.message_lake.minio.miniorepo.miniorepo.boto3')
def test_post(boto3):
    repo = MessageLakeMinioRepo(CONNECTION_DATA)
    boto3.client.assert_called_once()

    msg = _generate_msg_object(sender_ref='xxxx-xxxx-xxxx')
    assert repo.post(msg)

    s3_client = boto3.client.return_value
    assert s3_client.put_object.call_count == 2

@mock.patch('intergov.repos.message_lake.minio.miniorepo.miniorepo.boto3')
def test_update_metadata(boto3):
    repo = MessageLakeMinioRepo(CONNECTION_DATA)
    boto3.client.assert_called_once()
    msg = _generate_msg_object(sender_ref='xxxx-xxxx-xxxx', status='pending')
    metadata = {
        'status': 'received'
    }

    def get_object(**kwargs):
        key = kwargs['Key']
        body = mock.MagicMock()
        if key.endswith('metadata.json'):
            body.read.return_value = json.dumps(metadata).encode('utf-8')
            return {
                'Body': body
            }
        return None

    s3_client = boto3.client.return_value
    s3_client.get_object.side_effect = get_object

    assert repo.update_metadata(str(msg.sender), str(msg.sender_ref), {'status': 'received'})

@mock.patch('intergov.repos.message_lake.minio.miniorepo.ClientError', Exception)
@mock.patch('intergov.repos.message_lake.minio.miniorepo.miniorepo.boto3')
def test_get(boto3):
    repo = MessageLakeMinioRepo(CONNECTION_DATA)
    boto3.client.assert_called_once()
    msg = _generate_msg_object(sender_ref='xxxx-xxxx-xxxx', status='pending')
    msg_dict = msg.to_dict()
    metadata = {
        'status': 'received'
    }

    def get_object(**kwargs):
        key = kwargs['Key']
        body = mock.MagicMock()
        data = None
        if key.endswith('metadata.json'):
            data = metadata
        elif key.endswith('content.json'):
            data = msg_dict
        if data:
            body.read.return_value = json.dumps(data).encode('utf-8')
            return {
                'Body': body
            }

    s3_client = boto3.client.return_value
    s3_client.get_object.side_effect = get_object

    assert repo.get(str(msg.sender), str(msg.sender_ref))

    exception = Exception()
    exception.response = {
        'Error': {
            'Code': 'NoSuchKey'
        }
    }

    def raise_error(on_key):
        def get_object_content(key):
            if key.endswith(on_key):
                raise exception
            else:
                return json.dumps(msg_dict)
        return get_object_content

    s3_client = boto3.client.return_value
    repo.get_object_content = mock.Mock()
    repo.get_object_content.side_effect = raise_error('metadata.json')

    assert repo.get(str(msg.sender), str(msg.sender_ref))
    repo.get_object_content.side_effect = raise_error('content.json')
    assert not repo.get(str(msg.sender), str(msg.sender_ref))

    exception.response['Error']['Code'] = 'Random'
    for key in ['content.json', 'metadata.json']:
        repo.get_object_content.side_effect = raise_error(key)
        with pytest.raises(Exception):
            repo.get(str(msg.sender), str(msg.sender_ref))


DEBUG = False

with open("input.txt") as f:
    lines = f.read().splitlines()
    commands = iter(lines)

X = 1
cooldown = 1
signals = []
current = "INIT"
CRT_screen = ""
suspend = 0
cycle = 0
while True:

    cooldown -= 1
    cycle += 1

    if cooldown == 0:

        X += suspend
        suspend = 0
        current = next(commands, None)

        if current is None:
            break

        if current == "noop":
            cooldown += 1
        else:
            suspend = int(current.split(" ")[1])
            cooldown += 2

    if DEBUG:
        print(f"{cycle:>3}", f"{X:>3}", current)

    if cycle in [20, 60, 100, 140, 180, 220]:
        signals.append(X * cycle)

    # Draw CRT
    crt_x = cycle - 1
    while crt_x >= 40:
        crt_x -= 40
    CRT_screen += "⬜" if crt_x in [X - 1, X, X + 1] else "⬛"

    if DEBUG:
        print("CRT:", CRT_screen)
        print(
            "CUR:",
            "".join((["#" if i in [X - 1, X, X + 1] else "." for i in range(40)])),
        )

if DEBUG:
    print("\nFINAL:")
    for i, signal in enumerate(signals):
        print(i, signal)
print("PART 1:", sum(signals))  # 16480

print("PART 2:")
for Y in range(6):
    print(CRT_screen[Y * 40 : Y * 40 + 40])  # PLEFULPB