import pygame, random
import pygame.freetype

pygame.init()

WIDTH, HEIGHT = 1200, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
FPS = 60
VERSION = "0.2"

clock = pygame.time.Clock()
font_freetype_6 = pygame.freetype.SysFont('Comic Sans MS', 6)
font_freetype_15 = pygame.freetype.SysFont('Comic Sans MS', 15)
font_freetype_30 = pygame.freetype.SysFont('Comic Sans MS', 30)
font_main_8 = pygame.font.SysFont('Comic Sans MS', 8)
font_main_17 = pygame.font.SysFont('Comic Sans MS', 17)

# Рубрика "харе все забывать, разраб"
# Типы карт:          | entity, spell, weapon
# Типы существ:
# - Ошибка (error)          : Название говорит само за себя
# - Механизм (mech)         : Имеет малую прочность и высокую атаку
# - Нежить (undead)         : Слабые существа, некоторые могут возрадится с 1 хп
# - Элементаль (elemental)  : Имеют свойства своих элементов
# - Дракон (dragon)         : Имеют хорошое количество здоровья и сложности, многие драконы имеют провокацию до 1 удара
# - Орк (orc)               : Имеют хорошую атаку и сложность, многие орки могут атаковать сразу после выставления
# Типы заклинаний:    | Лед, Огонь, Электричество, Ветер, Кровь, Свет,  Тьма
#                     | ice, fire,  electricity,   wind,  blood, light, darkness
# Спец. способности:  |
# Типы предметов:     |

CARDS = {
    0: {
        "id": 0,
        "name": "Ошибка",
        "description": "Как ты это получил????",
        "card_type": "entity",
        "type": "any",
        "rarity": "none",
        "hp": 1,
        "attack": 0,
        "defence": 5,
        "mana": 10,
        "special": [],
        "special_vals": [],
        "original": True,
        "attacks": 0
    },
    # spell
    1: {
        "id": 1,
        "name": "Волшебная стрела",
        "description": "Наносит 2 урона герою противника",
        "card_type": "spell",
        "type": "light",
        "rarity": "basic",
        "mana": 2,
        "special": ["damageEnemyPlayer"],
        "special_vals": [2],
        "original": True
    },
    2: {
        "id": 2,
        "name": "Молния",
        "description": "Наносит 3 урона ВСЕМ персонажам",
        "card_type": "spell",
        "type": "electricity",
        "rarity": "rare",
        "mana": 5,
        "special": ["damageAllEntity", "damagePlayer", "damageEnemyPlayer"],
        "special_vals": [3, 3, 3],
        "original": True
    },
    3: {
        "id": 3,
        "name": "ЭМИ вспышка",
        "description": "Изменяет урон всех механизмов до 1",
        "card_type": "spell",
        "type": "electricity",
        "rarity": "rare",
        "mana": 7,
        "special": ["setTypeDamage"],
        "special_vals": [[1, "mech"]],
        "original": True
    },
    4: {
        "id": 4,
        "name": "Ярость",
        "description": "Наносит 5 урона герою игрока и противника",
        "card_type": "spell",
        "type": "blood",
        "rarity": "rare",
        "mana": 5,
        "special": ["damagePlayer", "damageEnemyPlayer"],
        "special_vals": [5, 5],
        "original": True
    },
    5: {
        "id": 5,
        "name": "Солнечное затмение",
        "description": "Выдает вам 3 солнечные вспышки",
        "card_type": "spell",
        "type": "fire",
        "rarity": "epic",
        "mana": 5,
        "special": ["addCards"],
        "special_vals": [[3, 6]],
        "original": True
    },
    6: {
        "id": 6,
        "name": "Солнечная вспышка",
        "description": "Наносит 1 урона ВСЕМ",
        "card_type": "spell",
        "type": "error",
        "rarity": "basic",
        "mana": 2,
        "special": ["damageAllEntity", "damagePlayer", "damageEnemyPlayer"],
        "special_vals": [1, 1, 1],
        "original": True
    },
    7: {
        "id": 7,
        "name": "Солнечная буря",
        "description": "Наносит 3 урона всей нежити",
        "card_type": "spell",
        "type": "fire",
        "rarity": "rare",
        "mana": 7,
        "special": ["damageAllEntityType"],
        "special_vals": [[3, "undead"]],
        "original": True
    },
    # mech
    8: {
        "id": 8,
        "name": "Бип-буп",
        "description": "Обычный боевой робот",
        "card_type": "entity",
        "type": "mech",
        "rarity": "basic",
        "hp": 1,
        "attack": 2,
        "defence": 1,
        "mana": 1,
        "special": [],
        "special_vals": [],
        "original": True,
        "attacks": 0
    },
}

PLAYER_MAIN_DECK = []
PLAYER_BATTLE_DECK = []
PLAYER_HAND = []
PLAYER_TABLE = []

ENEMY_BATTLE_DECK = []
ENEMY_HAND = []
ENEMY_TABLE = []

tableLimit = 7

gameMode = "menu"
gameSubMode = "main"

exit_text_temp = 0
exit_text_i = 0
exit_text = "Вы еще не сохранили ваш прогресс!"

saved = False

playerAngles = [random.randint(0, 50),random.randint(0, 50),random.randint(0, 50)]
enemyAngles = [random.randint(0, 50),random.randint(0, 50),random.randint(0, 50)]

tutorial_text_stage = 0
tutorial_text_i = 0
tutorial_text_temp = 0
tutorial_text = [
    "Приветствую",
    "Вы попали в DragoStone",
    "Для начала вам нужно выбрать карты для колоды",
    "Я вам буду давать по 3 карты, вы должны взять одну",
    "И так 10 раз, прочитать описание карты вы можете внизу",
    "-",
    "Отлично, теперь я расскажу тебе о механиках",
    "У карты есть стоимость в мане, она обозначается в левом верхнем углу карты синим цветом, если у тебя маны меньше чем стоимость - ты не сможешь её разыграть",
    "Также если карта - существо, то у неё может быть урон - желтый, существа атакуют в ваш следующий ход, но есть и те, которые атакуют сразу",
    "Существо имеет еще здоровье - красное и щит - белое, щит поглощает урон, нанесенный существу, тем самым понижая свою прочность, если здоровье существа нулевое - существо умирает",
    "Также карты могут быть оригинальными и копиями, оригинальные карты в любом случае вернутся вам в колоду, а копии уничтожатся",
    "Карты-копии даются другими существами, локациями или заклианиями",
    "Оригинальные карты существ востанавливают все, кроме здоровья, тоесть если у вашего оригинального существа под конец матча будет 5 урона, 8 щита и 3 здоровья, то сбросится все кроме здоровья",
    "Если оригинальное существо умрет - оно возродится после матча с 1 хп",
    "Посмотреть описания карт можно перед матчем в инвентаре",
    "Теперь, можно начать практику, я создам существ, а ты должен их убить, покачто они не будут тебя атаковать",
    "-",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    ""
]

tutorial_card_sellect = []
tutorial_cards_sellected = 0

space_text_temp = 0
space_text_i = 0
space_col = [(255,255,255),(150,150,150)]

PLAYER_MONEY = 100

PLAYER_SELLECTED_CARD = -1

PLAYER_HP = 25
ENEMY_HP = 25

PLAYER_SHIELD = 0
ENEMY_SHIELD = 0

PLAYER_ATTACK = 0
ENEMY_ATTACK = 0

PLAYER_MANA = 0
ENEMY_MANA = 0

PLAYER_MANA_MAX = 0
ENEMY_MANA_MAX = 0

PLAYER_FATIUGE_DAMAGE = 1
ENEMY_FATIUGE_DAMAGE = 1

haveGame = False

#00ffff МЕХАНИКА -------------------------------------------------------------

def player_fatiuge(count = -1, add = True):
    global PLAYER_HP, PLAYER_FATIUGE_DAMAGE, PLAYER_SHIELD
    if count < 0: count = PLAYER_FATIUGE_DAMAGE
    if PLAYER_SHIELD <= 0: PLAYER_HP -= count
    else:
        PLAYER_SHIELD -= count
        if PLAYER_SHIELD <= 0:
            PLAYER_HP -= abs(PLAYER_SHIELD)
            PLAYER_SHIELD = 0
    if add: PLAYER_FATIUGE_DAMAGE += count

def enemy_fatiuge(count = -1, add = True):
    global ENEMY_HP, ENEMY_FATIUGE_DAMAGE, ENEMY_SHIELD
    if count < 0: count = ENEMY_FATIUGE_DAMAGE
    if PLAYER_SHIELD <= 0: ENEMY_HP -= count
    else:
        ENEMY_SHIELD -= count
        if ENEMY_SHIELD <= 0:
            ENEMY_HP -= abs(ENEMY_SHIELD)
            ENEMY_SHIELD = 0
    if add: ENEMY_FATIUGE_DAMAGE += count

def player_damage(count):
    global PLAYER_HP, PLAYER_SHIELD
    if PLAYER_SHIELD <= 0: PLAYER_HP -= count
    else:
        PLAYER_SHIELD -= count
        if PLAYER_SHIELD <= 0:
            PLAYER_HP -= abs(PLAYER_SHIELD)
            PLAYER_SHIELD = 0

def enemy_damage(count):
    global ENEMY_HP, ENEMY_SHIELD
    if ENEMY_SHIELD <= 0: ENEMY_HP -= count
    else:
        ENEMY_SHIELD -= count
        if ENEMY_SHIELD <= 0:
            ENEMY_HP -= abs(ENEMY_SHIELD)
            ENEMY_SHIELD = 0

def damage_all_entity_type(count, type_ = "any"):
    for eid, e in enumerate(PLAYER_TABLE):
        if type_ == e["type"] or type_ == "any" or e["type"] == "any":
            if e["defence"] > 0:
                e["defence"]-=count
                if e["defence"] < 0:
                    e["hp"] -= abs(e["defence"])
                    e["defence"] = 0
                    if e["hp"] <= 0: PLAYER_TABLE.pop(eid)
            else:
                e["hp"]-=count
                if e["hp"] <= 0: PLAYER_TABLE.pop(eid)
    for eid, e in enumerate(ENEMY_TABLE):
        if type_ == e["type"] or type_ == "any" or e["type"] == "any":
            if e["defence"] > 0:
                e["defence"]-=count
                if e["defence"] < 0:
                    e["hp"] -= abs(e["defence"])
                    e["defence"] = 0
                    if e["hp"] <= 0: ENEMY_TABLE.pop(eid)
            else:
                e["hp"]-=count
                if e["hp"] <= 0: ENEMY_TABLE.pop(eid)

def player_draw_a_card(count = 1):
    for i in range(count):
        if len(PLAYER_BATTLE_DECK) > 0:
            card = random.randint(0, len(PLAYER_BATTLE_DECK)-1)
            if len(PLAYER_HAND) < 10: PLAYER_HAND.append(PLAYER_BATTLE_DECK[card])
            PLAYER_BATTLE_DECK.pop(card)
        else: player_fatiuge()

def enemy_draw_a_card(count = 1):
    for i in range(count):
        if len(ENEMY_BATTLE_DECK) > 0:
            card = random.randint(0, len(ENEMY_BATTLE_DECK)-1)
            if len(ENEMY_HAND) < 10: ENEMY_HAND.append(ENEMY_BATTLE_DECK[card])
            ENEMY_BATTLE_DECK.pop(card)
        else: enemy_fatiuge()

def player_add_card_hand(id):
    if len(PLAYER_HAND) < 10:
        card = CARDS[id].copy()
        card["original"] = False
        PLAYER_HAND.append(card.copy())

def save():
    global saved
    saved = True

#00ffff ОТРИСОВКА --------------------------------------------

def render_text_in_rect(rect, font, text, color=(0, 0, 0)):
    words = text.split()
    lines = []
    current_line = ""

    for word in words:
        test_line = current_line + word + " "
        if font.get_rect(test_line).width <= rect.width:
            current_line = test_line
        else:
            lines.append(current_line)
            current_line = word + " "

    lines.append(current_line)

    line_spacing = font.get_sized_height()
    y_offset = rect.height / 2 - (len(lines) * line_spacing) / 2

    for line in lines:
        line_surface, _ = font.render(line, color)
        line_rect = line_surface.get_rect(center=(rect.centerx, rect.y + y_offset))
        screen.blit(line_surface, line_rect)
        y_offset += line_spacing

def draw_stat(x, y, size, text, c1, c2, tox = 0, toy = 0):
    pygame.draw.rect(screen, c1, pygame.Rect(x, y, size, size))
    pygame.draw.rect(screen, c2, pygame.Rect(x, y, size, size), 2)
    screen.blit(text, pygame.Rect((x+tox, y+toy, size, size)))

def player_draw_hand(x, y, highlight = -1, sellected = -1):
    for i, j in enumerate(PLAYER_HAND):
        clr = (255,255,255)
        if j["original"]: clr = (255,255,123)
        if i != highlight and i != sellected:
            if i % 2: x2, y2 = 55, ((i//2)*80)-5
            else: x2, y2 = -5, ((i//2)*80)-5
            pygame.draw.rect(screen, (0,0,0), pygame.Rect(x+x2+5, y+y2+5, 50, 70))
            pygame.draw.rect(screen, clr, pygame.Rect(x+x2+5, y+y2+5, 50, 70), 2)
            draw_stat(x+x2, y+y2, 10, font_main_8.render(str(j["mana"]), False, (0,0,255)), (128,255,255), (0,255,255), 1, -1)
            if j["card_type"] == "entity":
                draw_stat(x+x2+50, y+y2+70, 10, font_main_8.render(str(j["hp"]), False, (0,0,0)), (255,0,0), (255,0,0), 1, -1)
                if j["defence"] > 0: draw_stat(x+x2+50, y+y2+55, 10, font_main_8.render(str(j["defence"]), False, (0,0,0)), (255,255,255), (200,200,200), 1, -1)
                if j["attack"] > 0: draw_stat(x+x2, y+y2+70, 10, font_main_8.render(str(j["attack"]), False, (0,0,0)), (255,255,200), (255,255,0), 1, -1)
            col = (10,10,10)
            if j["card_type"] == "entity": col = (0,255,0)
            elif j["card_type"] == "spell": col = (0,120,255)
            pygame.draw.rect(screen, col, pygame.Rect(x+x2+46, y+y2+2, 12, 2))
            pygame.draw.rect(screen, col, pygame.Rect(x+x2+56, y+y2+2, 2, 12))
            render_text_in_rect(pygame.Rect(x+x2+5, y+y2+5, 50, 70), font_freetype_6, j["name"], (255,255,255))
    clr = (255,255,255)
    if sellected >= 0 and sellected <= 10 and sellected < len(PLAYER_HAND):
        mx, my = pygame.mouse.get_pos()
        if PLAYER_HAND[sellected]["original"]: clr = (255,255,123)
        pygame.draw.rect(screen, (0,0,0), pygame.Rect(mx-55, my-65, 110, 130))
        pygame.draw.rect(screen, clr, pygame.Rect(mx-55, my-65, 110, 130), 2)
        draw_stat(mx-60, my-70, 20, font_main_17.render(str(PLAYER_HAND[sellected]["mana"]), False, (0,0,255)), (128,255,255), (0,255,255), 2, -2)
        if PLAYER_HAND[sellected]["card_type"] == "entity":
            draw_stat(mx+40, my+50, 20, font_main_17.render(str(PLAYER_HAND[sellected]["hp"]), False, (0,0,0)), (255,0,0), (255,0,0), 2, -2)
            if PLAYER_HAND[sellected]["defence"] > 0: draw_stat(mx+40, my+20, 20, font_main_17.render(str(PLAYER_HAND[sellected]["defence"]), False, (0,0,0)), (255,255,255), (200,200,200), 2, -2)
            if PLAYER_HAND[sellected]["attack"] > 0: draw_stat(mx-60, my+50, 20, font_main_17.render(str(PLAYER_HAND[sellected]["attack"]), False, (0,0,0)), (255,255,200), (255,255,0), 2, -2)
        col = (10,10,10)
        if PLAYER_HAND[sellected]["card_type"] == "entity": col = (0,255,0)
        elif PLAYER_HAND[sellected]["card_type"] == "spell": col = (0,120,255)
        pygame.draw.rect(screen, col, pygame.Rect(mx+34, my-70, 24, 4))
        pygame.draw.rect(screen, col, pygame.Rect(mx+56, my-70, 4, 24))
        render_text_in_rect(pygame.Rect(mx-55, my-65, 110, 130), font_freetype_15, PLAYER_HAND[sellected]["name"], (255,255,255))
    else:
        if highlight >= 0 and highlight <= 10 and highlight < len(PLAYER_HAND):
            if PLAYER_HAND[highlight]["original"]: clr = (255,255,123)
            if highlight % 2: x2, y2 = 30, ((highlight//2)*80)-30
            else: x2, y2 = -30, ((highlight//2)*80)-30
            pygame.draw.rect(screen, (0,0,0), pygame.Rect(x+x2+5, y+y2+5, 110, 130))
            pygame.draw.rect(screen, clr, pygame.Rect(x+x2+5, y+y2+5, 110, 130), 2)
            draw_stat(x+x2, y+y2, 20, font_main_17.render(str(PLAYER_HAND[highlight]["mana"]), False, (0,0,255)), (128,255,255), (0,255,255), 2, -2)
            if PLAYER_HAND[highlight]["card_type"] == "entity":
                draw_stat(x+x2+100, y+y2+120, 20, font_main_17.render(str(PLAYER_HAND[highlight]["hp"]), False, (0,0,0)), (255,0,0), (255,0,0), 2, -2)
                if PLAYER_HAND[highlight]["defence"] > 0: draw_stat(x+x2+100, y+y2+90, 20, font_main_17.render(str(PLAYER_HAND[highlight]["defence"]), False, (0,0,0)), (255,255,255), (200,200,200), 2, -2)
                if PLAYER_HAND[highlight]["attack"] > 0: draw_stat(x+x2, y+y2+120, 20, font_main_17.render(str(PLAYER_HAND[highlight]["attack"]), False, (0,0,0)), (255,255,200), (255,255,0), 2, -2)
            col = (10,10,10)
            if PLAYER_HAND[highlight]["card_type"] == "entity": col = (0,255,0)
            elif PLAYER_HAND[highlight]["card_type"] == "spell": col = (0,120,255)
            pygame.draw.rect(screen, col, pygame.Rect(x+x2+94, y+y2, 24, 4))
            pygame.draw.rect(screen, col, pygame.Rect(x+x2+116, y+y2, 4, 24))
            render_text_in_rect(pygame.Rect(x+x2+5, y+y2+5, 110, 130), font_freetype_15, PLAYER_HAND[highlight]["name"], (255,255,255))

def enemy_draw_hand(x, y, highlight = -1):
    for i, j in enumerate(ENEMY_HAND):
        clr = (255,255,255)
        if j["original"]: clr = (255,255,123)
        if i != highlight:
            if i % 2: x2, y2 = 55, ((i//2)*80)-5
            else: x2, y2 = -5, ((i//2)*80)-5
            pygame.draw.rect(screen, (0,0,0), pygame.Rect(x+x2+5, y+y2+5, 50, 70))
            pygame.draw.rect(screen, clr, pygame.Rect(x+x2+5, y+y2+5, 50, 70), 2)
            draw_stat(x+x2, y+y2, 10, font_main_8.render(str(j["mana"]), False, (0,0,255)), (128,255,255), (0,255,255), 1, -1)
            if j["card_type"] == "entity":
                draw_stat(x+x2+50, y+y2+70, 10, font_main_8.render(str(j["hp"]), False, (0,0,0)), (255,0,0), (255,0,0), 1, -1)
                if j["defence"] > 0: draw_stat(x+x2+50, y+y2+55, 10, font_main_8.render(str(j["defence"]), False, (0,0,0)), (255,255,255), (200,200,200), 1, -1)
                if j["attack"] > 0: draw_stat(x+x2, y+y2+70, 10, font_main_8.render(str(j["attack"]), False, (0,0,0)), (255,255,200), (255,255,0), 1, -1)
            col = (10,10,10)
            if j["card_type"] == "entity": col = (0,255,0)
            elif j["card_type"] == "spell": col = (0,120,255)
            pygame.draw.rect(screen, col, pygame.Rect(x+x2+46, y+y2+2, 12, 2))
            pygame.draw.rect(screen, col, pygame.Rect(x+x2+56, y+y2+2, 2, 12))
            render_text_in_rect(pygame.Rect(x+x2+5, y+y2+5, 50, 70), font_freetype_6, j["name"], (255,255,255))
    clr = (255,255,255)
    if highlight >= 0 and highlight <= 10 and highlight < len(ENEMY_HAND):
        if ENEMY_HAND[highlight]["original"]: clr = (255,255,123)
        if highlight % 2: x2, y2 = 30, ((highlight//2)*80)-30
        else: x2, y2 = -30, ((highlight//2)*80)-30
        pygame.draw.rect(screen, (0,0,0), pygame.Rect(x+x2+5, y+y2+5, 110, 130))
        pygame.draw.rect(screen, clr, pygame.Rect(x+x2+5, y+y2+5, 110, 130), 2)
        draw_stat(x+x2, y+y2, 20, font_main_17.render(str(ENEMY_HAND[highlight]["mana"]), False, (0,0,255)), (128,255,255), (0,255,255), 2, -2)
        if ENEMY_HAND[highlight]["card_type"] == "entity":
            draw_stat(x+x2+100, y+y2+120, 20, font_main_17.render(str(ENEMY_HAND[highlight]["hp"]), False, (0,0,0)), (255,0,0), (255,0,0), 2, -2)
            if ENEMY_HAND[highlight]["defence"] > 0: draw_stat(x+x2+100, y+y2+90, 20, font_main_17.render(str(ENEMY_HAND[highlight]["defence"]), False, (0,0,0)), (255,255,255), (200,200,200), 2, -2)
            if ENEMY_HAND[highlight]["attack"] > 0: draw_stat(x+x2, y+y2+120, 20, font_main_17.render(str(ENEMY_HAND[highlight]["attack"]), False, (0,0,0)), (255,255,200), (255,255,0), 2, -2)
        col = (10,10,10)
        if ENEMY_HAND[highlight]["card_type"] == "entity": col = (0,255,0)
        elif ENEMY_HAND[highlight]["card_type"] == "spell": col = (0,120,255)
        pygame.draw.rect(screen, col, pygame.Rect(x+x2+94, y+y2, 24, 4))
        pygame.draw.rect(screen, col, pygame.Rect(x+x2+116, y+y2, 4, 24))
        render_text_in_rect(pygame.Rect(x+x2+5, y+y2+5, 110, 130), font_freetype_15, ENEMY_HAND[highlight]["name"], (255,255,255))

def player_draw_table(x, y):
    pos = pygame.mouse.get_pos()
    highlight = -1
    for i, j in enumerate(PLAYER_TABLE):
        x2 = (i*60)-(30*len(PLAYER_TABLE))
        if PLAYER_SELLECTED_CARD == -1:
            if pygame.Rect(x+x2+5, y+5, 50, 70).collidepoint(pos): highlight = i
        if i != highlight:
            clr = (255,255,255)
            if j["original"]: clr = (255,255,123)
            pygame.draw.rect(screen, (0,0,0), pygame.Rect(x+x2+5, y+5, 50, 70))
            pygame.draw.rect(screen, clr, pygame.Rect(x+x2+5, y+5, 50, 70), 2)
            draw_stat(x+x2, y, 10, font_main_8.render(str(j["mana"]), False, (0,0,255)), (128,255,255), (0,255,255), 1, -1)
            if j["card_type"] == "entity":
                draw_stat(x+x2+50, y+70, 10, font_main_8.render(str(j["hp"]), False, (0,0,0)), (255,0,0), (255,0,0), 1, -1)
                if j["defence"] > 0: draw_stat(x+x2+50, y+55, 10, font_main_8.render(str(j["defence"]), False, (0,0,0)), (255,255,255), (200,200,200), 1, -1)
                if j["attack"] > 0: draw_stat(x+x2, y+70, 10, font_main_8.render(str(j["attack"]), False, (0,0,0)), (255,255,200), (255,255,0), 1, -1)
            col = (10,10,10)
            if j["card_type"] == "entity": col = (0,255,0)
            pygame.draw.rect(screen, col, pygame.Rect(x+x2+46, y+2, 12, 2))
            pygame.draw.rect(screen, col, pygame.Rect(x+x2+56, y+2, 2, 12))
            render_text_in_rect(pygame.Rect(x+x2+5, y+5, 50, 70), font_freetype_6, j["name"], (255,255,255))
    if highlight > -1:
        clr = (255,255,255)
        if PLAYER_TABLE[highlight]["original"]: clr = (255,255,123)
        x2 = (highlight*60)-(30*len(PLAYER_TABLE))-30
        y2 = -30
        pygame.draw.rect(screen, (0,0,0), pygame.Rect(x+x2+5, y+y2+5, 110, 130))
        pygame.draw.rect(screen, clr, pygame.Rect(x+x2+5, y+y2+5, 110, 130), 2)
        draw_stat(x+x2, y+y2, 20, font_main_17.render(str(PLAYER_TABLE[highlight]["mana"]), False, (0,0,255)), (128,255,255), (0,255,255), 2, -2)
        if PLAYER_TABLE[highlight]["card_type"] == "entity":
            draw_stat(x+x2+100, y+y2+120, 20, font_main_17.render(str(PLAYER_TABLE[highlight]["hp"]), False, (0,0,0)), (255,0,0), (255,0,0), 2, -2)
            if PLAYER_TABLE[highlight]["defence"] > 0: draw_stat(x+x2+100, y+y2+90, 20, font_main_17.render(str(PLAYER_TABLE[highlight]["defence"]), False, (0,0,0)), (255,255,255), (200,200,200), 2, -2)
            if PLAYER_TABLE[highlight]["attack"] > 0: draw_stat(x+x2, y+y2+120, 20, font_main_17.render(str(PLAYER_TABLE[highlight]["attack"]), False, (0,0,0)), (255,255,200), (255,255,0), 2, -2)
        col = (10,10,10)
        if PLAYER_TABLE[highlight]["card_type"] == "entity": col = (0,255,0)
        elif PLAYER_TABLE[highlight]["card_type"] == "spell": col = (0,120,255)
        pygame.draw.rect(screen, col, pygame.Rect(x+x2+94, y+y2, 24, 4))
        pygame.draw.rect(screen, col, pygame.Rect(x+x2+116, y+y2, 4, 24))
        render_text_in_rect(pygame.Rect(x+x2+5, y+y2+5, 110, 130), font_freetype_15, PLAYER_TABLE[highlight]["name"], (255,255,255))

def enemy_draw_table(x, y):
    pos = pygame.mouse.get_pos()
    highlight = -1
    for i, j in enumerate(ENEMY_TABLE):
        x2 = (i*60)-(30*len(ENEMY_TABLE))
        if PLAYER_SELLECTED_CARD == -1:
            if pygame.Rect(x+x2+5, y+5, 50, 70).collidepoint(pos): highlight = i
        if i != highlight:
            clr = (255,255,255)
            if j["original"]: clr = (255,255,123)
            pygame.draw.rect(screen, (0,0,0), pygame.Rect(x+x2+5, y+5, 50, 70))
            pygame.draw.rect(screen, clr, pygame.Rect(x+x2+5, y+5, 50, 70), 2)
            draw_stat(x+x2, y, 10, font_main_8.render(str(j["mana"]), False, (0,0,255)), (128,255,255), (0,255,255), 1, -1)
            if j["card_type"] == "entity":
                draw_stat(x+x2+50, y+70, 10, font_main_8.render(str(j["hp"]), False, (0,0,0)), (255,0,0), (255,0,0), 1, -1)
                if j["defence"] > 0: draw_stat(x+x2+50, y+55, 10, font_main_8.render(str(j["defence"]), False, (0,0,0)), (255,255,255), (200,200,200), 1, -1)
                if j["attack"] > 0: draw_stat(x+x2, y+70, 10, font_main_8.render(str(j["attack"]), False, (0,0,0)), (255,255,200), (255,255,0), 1, -1)
            col = (10,10,10)
            if j["card_type"] == "entity": col = (0,255,0)
            pygame.draw.rect(screen, col, pygame.Rect(x+x2+46, y+2, 12, 2))
            pygame.draw.rect(screen, col, pygame.Rect(x+x2+56, y+2, 2, 12))
            render_text_in_rect(pygame.Rect(x+x2+5, y+5, 50, 70), font_freetype_6, j["name"], (255,255,255))
    if highlight > -1:
        clr = (255,255,255)
        if ENEMY_TABLE[highlight]["original"]: clr = (255,255,123)
        x2 = (highlight*60)-(30*len(ENEMY_TABLE))-30
        y2 = -30
        pygame.draw.rect(screen, (0,0,0), pygame.Rect(x+x2+5, y+y2+5, 110, 130))
        pygame.draw.rect(screen, clr, pygame.Rect(x+x2+5, y+y2+5, 110, 130), 2)
        draw_stat(x+x2, y+y2, 20, font_main_17.render(str(ENEMY_TABLE[highlight]["mana"]), False, (0,0,255)), (128,255,255), (0,255,255), 2, -2)
        if ENEMY_TABLE[highlight]["card_type"] == "entity":
            draw_stat(x+x2+100, y+y2+120, 20, font_main_17.render(str(ENEMY_TABLE[highlight]["hp"]), False, (0,0,0)), (255,0,0), (255,0,0), 2, -2)
            if ENEMY_TABLE[highlight]["defence"] > 0: draw_stat(x+x2+100, y+y2+90, 20, font_main_17.render(str(ENEMY_TABLE[highlight]["defence"]), False, (0,0,0)), (255,255,255), (200,200,200), 2, -2)
            if ENEMY_TABLE[highlight]["attack"] > 0: draw_stat(x+x2, y+y2+120, 20, font_main_17.render(str(ENEMY_TABLE[highlight]["attack"]), False, (0,0,0)), (255,255,200), (255,255,0), 2, -2)
        col = (10,10,10)
        if ENEMY_TABLE[highlight]["card_type"] == "entity": col = (0,255,0)
        elif ENEMY_TABLE[highlight]["card_type"] == "spell": col = (0,120,255)
        pygame.draw.rect(screen, col, pygame.Rect(x+x2+94, y+y2, 24, 4))
        pygame.draw.rect(screen, col, pygame.Rect(x+x2+116, y+y2, 4, 24))
        render_text_in_rect(pygame.Rect(x+x2+5, y+y2+5, 110, 130), font_freetype_15, ENEMY_TABLE[highlight]["name"], (255,255,255))

def draw_mana():
    for i in range(1, 11):
        col = (50,50,255)
        if i <= PLAYER_MANA: col = (170,170,255)
        if i <= PLAYER_MANA_MAX: pygame.draw.rect(screen, col, pygame.Rect(650+(i*20), 515, 15, 15))
        else: pygame.draw.rect(screen, (30,30,30), pygame.Rect(650+(i*20), 515, 15, 15))
        col = (50,50,255)
        if i <= ENEMY_MANA: col = (170,170,255)
        if i <= ENEMY_MANA_MAX: pygame.draw.rect(screen, col, pygame.Rect(650+(i*20), 75, 15, 15))
        else: pygame.draw.rect(screen, (30,30,30), pygame.Rect(650+(i*20), 75, 15, 15))
    screen.blit(font_main_17.render(f"x{PLAYER_MANA}", False, (50,50,255)), pygame.Rect((870, 510, 50, 20)))
    screen.blit(font_main_17.render(f"x{ENEMY_MANA}", False, (50,50,255)), pygame.Rect((870, 70, 50, 20)))

def draw_rotated_rect(x, y, w, h, color, angle):
    rect_surface = pygame.Surface((w, h), pygame.SRCALPHA)
    pygame.draw.rect(rect_surface, color, (0, 0, w, h))
    rotated_surface = pygame.transform.rotate(rect_surface, int(angle))
    screen.blit(rotated_surface, (x - rotated_surface.get_width() // 2, y - rotated_surface.get_height() // 2))

def draw_player(x, y):
    draw_rotated_rect(x, y, 40, 40, (150,150,150), playerAngles[2])
    draw_rotated_rect(x, y, 30, 30, (200,200,200), playerAngles[1])
    draw_rotated_rect(x, y, 20, 20, (255,255,255), playerAngles[0])
    draw_stat(x+40, y+10, 25, font_main_17.render(str(PLAYER_HP), False, (0,0,0)), (255,0,0), (255,50,50), 2, 0)
    if PLAYER_SHIELD > 0: draw_stat(x+40, y-20, 25, font_main_17.render(str(PLAYER_SHIELD), False, (0,0,0)), (255,255,255), (200,200,200), 2, 0)
    if PLAYER_ATTACK > 0: draw_stat(x-65, y-20, 25, font_main_17.render(str(PLAYER_ATTACK), False, (0,0,0)), (255,255,200), (255,255,0), 2, 0)

def draw_enemy(x, y):
    draw_rotated_rect(x, y, 40, 40, (150,0,0), enemyAngles[2])
    draw_rotated_rect(x, y, 30, 30, (200,0,0), enemyAngles[1])
    draw_rotated_rect(x, y, 20, 20, (255,0,0), enemyAngles[0])
    draw_stat(x+40, y-10, 25, font_main_17.render(str(ENEMY_HP), False, (0,0,0)), (255,0,0), (255,50,50), 2, 0)
    if ENEMY_SHIELD > 0: draw_stat(x+40, y+20, 25, font_main_17.render(str(ENEMY_SHIELD), False, (0,0,0)), (255,255,255), (200,200,200), 2, 0)
    if ENEMY_ATTACK > 0: draw_stat(x-65, y+20, 25, font_main_17.render(str(ENEMY_ATTACK), False, (0,0,0)), (255,255,200), (255,255,0), 2, 0)

def draw_single_card(x, y, card, highlight = False):
    if not highlight:
        clr = (255,255,255)
        if CARDS[card]["original"]: clr = (255,255,123)
        pygame.draw.rect(screen, (0,0,0), pygame.Rect(x+5, y+5, 50, 70))
        pygame.draw.rect(screen, clr, pygame.Rect(x+5, y+5, 50, 70), 2)
        draw_stat(x, y, 10, font_main_8.render(str(CARDS[card]["mana"]), False, (0,0,255)), (128,255,255), (0,255,255), 1, -1)
        if CARDS[card]["card_type"] == "entity":
            draw_stat(x+50, y+70, 10, font_main_8.render(str(CARDS[card]["hp"]), False, (0,0,0)), (255,0,0), (255,0,0), 1, -1)
            if CARDS[card]["defence"] > 0: draw_stat(x+50, y+55, 10, font_main_8.render(str(CARDS[card]["defence"]), False, (0,0,0)), (255,255,255), (200,200,200), 1, -1)
            if CARDS[card]["attack"] > 0: draw_stat(x, y+70, 10, font_main_8.render(str(CARDS[card]["attack"]), False, (0,0,0)), (255,255,200), (255,255,0), 1, -1)
        col = (10,10,10)
        if CARDS[card]["card_type"] == "entity": col = (0,255,0)
        elif CARDS[card]["card_type"] == "spell": col = (0,120,255)
        pygame.draw.rect(screen, col, pygame.Rect(x+46, y+2, 12, 2))
        pygame.draw.rect(screen, col, pygame.Rect(x+56, y+2, 2, 12))
        render_text_in_rect(pygame.Rect(x+5, y+5, 50, 70), font_freetype_6, CARDS[card]["name"], (255,255,255))
    else:
        clr = (255,255,255)
        if CARDS[card]["original"]: clr = (255,255,123)
        x2 = -30
        y2 = -30
        pygame.draw.rect(screen, (0,0,0), pygame.Rect(x+x2+5, y+y2+5, 110, 130))
        pygame.draw.rect(screen, clr, pygame.Rect(x+x2+5, y+y2+5, 110, 130), 2)
        draw_stat(x+x2, y+y2, 20, font_main_17.render(str(CARDS[card]["mana"]), False, (0,0,255)), (128,255,255), (0,255,255), 2, -2)
        if CARDS[card]["card_type"] == "entity":
            draw_stat(x+x2+100, y+y2+120, 20, font_main_17.render(str(CARDS[card]["hp"]), False, (0,0,0)), (255,0,0), (255,0,0), 2, -2)
            if CARDS[card]["defence"] > 0: draw_stat(x+x2+100, y+y2+90, 20, font_main_17.render(str(CARDS[card]["defence"]), False, (0,0,0)), (255,255,255), (200,200,200), 2, -2)
            if CARDS[card]["attack"] > 0: draw_stat(x+x2, y+y2+120, 20, font_main_17.render(str(CARDS[card]["attack"]), False, (0,0,0)), (255,255,200), (255,255,0), 2, -2)
        col = (10,10,10)
        if CARDS[card]["card_type"] == "entity": col = (0,255,0)
        elif CARDS[card]["card_type"] == "spell": col = (0,120,255)
        pygame.draw.rect(screen, col, pygame.Rect(x+x2+94, y+y2, 24, 4))
        pygame.draw.rect(screen, col, pygame.Rect(x+x2+116, y+y2, 4, 24))
        render_text_in_rect(pygame.Rect(x+x2+5, y+y2+5, 110, 130), font_freetype_15, CARDS[card]["name"], (255,255,255))

#00ffff ПРОВЕРКИ --------------------------------------------

def check_highlight(x, y):
    pos = pygame.mouse.get_pos()
    for i in range(10):
        if i % 2:
            if pygame.Rect(x+60, y+((i//2)*80), 50, 70).collidepoint(pos): return i
        else:
            if pygame.Rect(x, y+((i//2)*80), 50, 70).collidepoint(pos): return i
    return -1

def sellect_card(x, y):
    global PLAYER_SELLECTED_CARD
    if PLAYER_SELLECTED_CARD < 0: PLAYER_SELLECTED_CARD = check_highlight(x, y)
    else: PLAYER_SELLECTED_CARD = -1

SP = False

running = True
while running:
    #00ff00 МЕХАНИКА ------------------------------------------------------------------
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.MOUSEBUTTONUP:
            pos = pygame.mouse.get_pos()
            if gameMode == "menu":
                if gameSubMode == "main":
                    if pygame.Rect((50, 50, 200, 20)).collidepoint(pos):
                        if haveGame: pass
                    if pygame.Rect((50, 75, 200, 20)).collidepoint(pos): gameSubMode = "sellect_campaign"
                    if pygame.Rect((50, 100, 200, 20)).collidepoint(pos): gameSubMode = "settings"
                    if pygame.Rect((50, 125, 200, 20)).collidepoint(pos): save()
                    if pygame.Rect((50, 150, 200, 20)).collidepoint(pos):
                        if saved: running = False
                        else: gameSubMode = "exit"
                elif gameSubMode == "sellect_campaign":
                    if pygame.Rect((50, 50, 200, 20)).collidepoint(pos): gameSubMode = "main"
                    if pygame.Rect((50, 75, 200, 20)).collidepoint(pos): gameMode, gameSubMode = "tutorial", "talk"
                elif gameSubMode == "settings":
                    if pygame.Rect((50, 50, 200, 20)).collidepoint(pos): gameSubMode = "main"
                elif gameSubMode == "exit":
                    if pygame.Rect((50, 50, 200, 20)).collidepoint(pos): gameSubMode = "main"
                    if pygame.Rect((50, 75, 200, 20)).collidepoint(pos):
                        save()
                        running = False
                    if pygame.Rect((50, 100, 200, 20)).collidepoint(pos): running = False
            elif gameMode == "tutorial":
                if gameSubMode == "getCards":
                    tt = -1
                    for i, j in enumerate(tutorial_card_sellect):
                        if pygame.Rect(300+(i*250)+5, 80, 50, 70).collidepoint(pos):
                            tt = j
                            break
                    if tt != -1:
                        PLAYER_MAIN_DECK.append(CARDS[tt].copy())
                        tutorial_card_sellect = []
                        tutorial_cards_sellected+=1
            elif gameMode == "battle":
                if pygame.Rect(300, 180, 620, 240).collidepoint(pos):
                    if PLAYER_SELLECTED_CARD != -1:
                        if PLAYER_HAND[PLAYER_SELLECTED_CARD]["card_type"] == "entity":
                            if PLAYER_MANA >= PLAYER_HAND[PLAYER_SELLECTED_CARD]["mana"]:
                                if len(PLAYER_TABLE) < 7:
                                    PLAYER_MANA-=PLAYER_HAND[PLAYER_SELLECTED_CARD]["mana"]
                                    PLAYER_TABLE.append(PLAYER_HAND[PLAYER_SELLECTED_CARD].copy())
                                    PLAYER_HAND.pop(PLAYER_SELLECTED_CARD)
                                    PLAYER_SELLECTED_CARD = -1
                        elif PLAYER_HAND[PLAYER_SELLECTED_CARD]["card_type"] == "spell":
                            if PLAYER_MANA >= PLAYER_HAND[PLAYER_SELLECTED_CARD]["mana"]:
                                PLAYER_MANA-=PLAYER_HAND[PLAYER_SELLECTED_CARD]["mana"]
                                for i, j in enumerate(PLAYER_HAND[PLAYER_SELLECTED_CARD]["special"]):
                                    val = PLAYER_HAND[PLAYER_SELLECTED_CARD]["special_vals"][i]
                                    if j == "damageAllEntity": damage_all_entity_type(val)
                                    elif j == "damageAllEntityType": damage_all_entity_type(val[0], val[1])
                                    elif j == "damagePlayer": player_damage(val)
                                    elif j == "damageEnemyPlayer": enemy_damage(val)
                                    elif j == "addCards":
                                        for t in range(val[0]): player_add_card_hand(val[1])
                                    elif j == "null": pass
                                    elif j == "null": pass
                                    elif j == "null": pass
                                    elif j == "null": pass
                                    elif j == "null": pass
                                PLAYER_HAND.pop(PLAYER_SELLECTED_CARD)
                                PLAYER_SELLECTED_CARD = -1
                sellect_card(100, 100)

    for i in range(len(playerAngles)):
        playerAngles[i]+=(i+1)/3
        if playerAngles[i] >= 360: playerAngles[i]-=360
    for i in range(len(enemyAngles)):
        enemyAngles[i]+=(i+1)/3
        if enemyAngles[i] >= 360: enemyAngles[i]-=360

    if gameMode == "menu" and gameSubMode == "exit":
        exit_text_temp+=1
        if exit_text_temp >= 2:
            exit_text_i+=1
            exit_text_temp = 0
    else:
        exit_text_i = 0
        exit_text_temp = 0

    if gameMode == "tutorial":
        tutorial_text_temp+=1
        if tutorial_text_temp >= 2:
            tutorial_text_i+=1
            tutorial_text_temp = 0
        if gameSubMode == "talk":
            keys = pygame.key.get_pressed()
            if keys[pygame.K_SPACE]:
                if not SP:
                    tutorial_text_i = 0
                    tutorial_text_temp = 0
                    tutorial_text_stage += 1
                SP = True
            else:
                SP = False
        if gameSubMode == "getCards":
            if len(tutorial_card_sellect) < 3:
                tutorial_card_sellect.append(random.randint(1, len(CARDS)-2))
    else:
        exit_text_i = 0
        exit_text_temp = 0

    space_text_temp+=1
    if space_text_temp > 30:
        space_text_temp = 0
        space_text_i = {0:1,1:0}[space_text_i]

    #00ff00 ОТРИСОВКА ------------------------------------------------------------------

    screen.fill((0,0,0))

    if gameMode == "menu":
        pos = pygame.mouse.get_pos()
        if gameSubMode == "main":
            col = (50,50,50)
            if haveGame:
                col = (255,255,255)
                if pygame.Rect((50, 50, 200, 20)).collidepoint(pos): col = (255,255,0)
            screen.blit(font_main_17.render(f"Продолжить", True, col), pygame.Rect((50, 50, 200, 20)))
            col = (255,255,255)
            if pygame.Rect((50, 75, 200, 20)).collidepoint(pos): col = (255,255,0)
            screen.blit(font_main_17.render(f"Новая игра", True, col), pygame.Rect((50, 75, 200, 20)))
            col = (255,255,255)
            if pygame.Rect((50, 100, 200, 20)).collidepoint(pos): col = (255,255,0)
            screen.blit(font_main_17.render(f"Настройки", True, col), pygame.Rect((50, 100, 200, 20)))
            col = (255,255,255)
            if pygame.Rect((50, 125, 200, 20)).collidepoint(pos): col = (255,255,0)
            screen.blit(font_main_17.render(f"Сохранить прогресс", True, col), pygame.Rect((50, 125, 200, 20)))
            col = (255,255,255)
            if pygame.Rect((50, 150, 200, 20)).collidepoint(pos): col = (255,255,0)
            screen.blit(font_main_17.render(f"Выйти", True, col), pygame.Rect((50, 150, 200, 20)))
        if gameSubMode == "sellect_campaign":
            col = (255,255,255)
            if pygame.Rect((50, 50, 200, 20)).collidepoint(pos): col = (255,255,0)
            screen.blit(font_main_17.render(f"Назад", True, col), pygame.Rect((50, 50, 200, 20)))
            col = (255,255,255)
            if pygame.Rect((50, 75, 200, 20)).collidepoint(pos): col = (255,255,0)
            screen.blit(font_main_17.render(f"Обучение", True, col), pygame.Rect((50, 75, 200, 20)))
            col = (255,255,255)
            if pygame.Rect((50, 100, 200, 20)).collidepoint(pos): col = (255,255,0)
            screen.blit(font_main_17.render(f"Номальный режим", True, col), pygame.Rect((50, 100, 200, 20)))
            col = (255,255,255)
            if pygame.Rect((50, 125, 200, 20)).collidepoint(pos): col = (255,255,0)
            screen.blit(font_main_17.render(f"Мастер режим", True, col), pygame.Rect((50, 125, 200, 20)))
        if gameSubMode == "settings":
            col = (255,255,255)
            if pygame.Rect((50, 50, 200, 20)).collidepoint(pos): col = (255,255,0)
            screen.blit(font_main_17.render(f"Назад", True, col), pygame.Rect((50, 50, 200, 20)))
        if gameSubMode == "exit":
            render_text_in_rect(pygame.Rect((0, 0, WIDTH, HEIGHT)), font_freetype_30, "".join([j for i, j in enumerate(list(exit_text)) if i <= exit_text_i]), (255,0,0))
            col = (255,255,255)
            if pygame.Rect((50, 50, 200, 20)).collidepoint(pos): col = (255,255,0)
            screen.blit(font_main_17.render(f"Назад", True, col), pygame.Rect((50, 50, 200, 20)))
            col = (255,255,255)
            if pygame.Rect((50, 75, 200, 20)).collidepoint(pos): col = (255,255,0)
            screen.blit(font_main_17.render(f"Сохранить и выйти", True, col), pygame.Rect((50, 75, 200, 20)))
            col = (255,255,255)
            if pygame.Rect((50, 100, 200, 20)).collidepoint(pos): col = (255,0,0)
            screen.blit(font_main_17.render(f"Выйти без сохранения", True, col), pygame.Rect((50, 100, 200, 20)))

    elif gameMode == "tutorial":
        if gameSubMode == "talk":
            render_text_in_rect(pygame.Rect((0, 0, WIDTH, HEIGHT)), font_freetype_30, "".join([j for i, j in enumerate(list(tutorial_text[tutorial_text_stage])) if i <= tutorial_text_i-20]), (255,255,255))
            if tutorial_text_i > len(tutorial_text[tutorial_text_stage])+100: render_text_in_rect(pygame.Rect((0, 500, WIDTH, 100)), font_freetype_15, "[SPACE]", space_col[space_text_i])
            if tutorial_text_stage == 5: gameSubMode = "getCards"
        if gameSubMode == "getCards":
            pos = pygame.mouse.get_pos()
            for i, j in enumerate(tutorial_card_sellect):
                draw_single_card(300+(i*250), 75, j, pygame.Rect(300+(i*250)+5, 80, 50, 70).collidepoint(pos))
            if tutorial_cards_sellected >= 10:
                tutorial_text_stage=6
                tutorial_text_i=0
                tutorial_text_temp=0
                tutorial_card_sellect=[]
                gameSubMode = "talk"

    elif gameMode == "shop":
        if gameSubMode == "main": pass

    elif gameMode == "campaign":
        if gameSubMode == "main": pass

    elif gameMode == "battle":
        if gameSubMode == "main":
            pygame.draw.rect(screen, (50,50,50), pygame.Rect(300, 50, 620, 500))
            pygame.draw.rect(screen, (100,100,100), pygame.Rect(300, 180, 620, 100))
            pygame.draw.rect(screen, (100,100,100), pygame.Rect(300, 320, 620, 100))
            pygame.draw.rect(screen, (50,50,50), pygame.Rect(70, 50, 180, 500))
            pygame.draw.rect(screen, (50,50,50), pygame.Rect(970, 50, 180, 500))

            draw_mana()

            player_draw_table(600, 330)
            enemy_draw_table(600, 190)

            draw_player(600, 470)
            draw_enemy(600, 120)

            player_draw_hand(100, 100, check_highlight(100, 100), PLAYER_SELLECTED_CARD)
            if PLAYER_SELLECTED_CARD < 0: enemy_draw_hand(1000, 100, check_highlight(1000, 100))
            else: enemy_draw_hand(1000, 100, -1)

    pygame.display.flip()

    clock.tick(FPS)


import os
import shutil

for folder in os.listdir("doc/build"):
    shutil.rmtree("doc/build/%s" % folder)
for file in os.listdir("doc/source"):
    if file.endswith(".rst") and file!="index.rst":
        os.remove("doc/source/%s" % file)
os.system("sphinx-apidoc -o doc/source src")
os.chdir("doc")
os.system("make html")


# problem is to fine out the prieme divisible number of any Number

from math import sqrt

def prime_divisible_value(number):
    factors_list = []

    while number % 2 == 0:
        number //= 2
        factors_list.append(2)

    sqrt_num = int(sqrt(number))

    for i in range(3, sqrt_num, 2):
        while number % i == 0:
            number //= i
            factors_list.append(i)

    if number > 1:
        factors_list.append(number)
    return factors_list

if __name__ == '__main__':
    number = 4
    expected_ans = [2, 2]
    factors = prime_divisible_value(number)
    assert expected_ans == factors, factors
    print(factors)

    number = 10
    expected_ans = [2, 5]
    factors = prime_divisible_value(number)
    assert expected_ans == factors, factors
    print(factors)

    number = 27
    expected_ans = [3, 3, 3]
    factors = prime_divisible_value(number)
    assert expected_ans == factors, factors
    print(factors)

    number = 101
    expected_ans = [101]
    factors = prime_divisible_value(number)
    assert expected_ans == factors, factors
    print(factors)

    number = 1
    expected_ans = []
    factors = prime_divisible_value(number)
    assert expected_ans == factors, factors
    print(factors)

# take input number as a list

x = list(map(int, input().split()))
print(x)

def even_number(n):
    return n % 2 == 0

# # using filter
# even_list = filter(even_number, x)
# print('list printed', list(even_list))

# using lambda function
even_list_1 = filter(lambda y: y % 2 == 0, x)
print(list(even_list_1))

x = "arman shanto"
print(x.title())


from os.path import join

import joblib
import pandas as pd
from sklearn.tree import export_graphviz
from sklearn.utils import resample

from config import DIR_PATH, PATH_MATRICES
from disambiguator import Disambiguator, TARGET, CATEGORICAL_FEATURES
from utils.helpers import extract_file_name_from_path, convert_str_to_list, load_pickle_file

def convert_binary_to_triple_schema(assignment):
    if assignment is True:
        return 1
    elif assignment is False:
        return -1
    else:
        return 0

def downsample(x, y, max_skewness=1, max_size=None, return_index=False):
    """Adopted from https://elitedatascience.com/imbalanced-classes"""
    df = x.copy()
    df.loc[:, 'TARGET'] = y
    df_class_1 = df[(df['TARGET'] == "true") | (df['TARGET'] == 1)]
    df_class_0 = df[(df['TARGET'] == "false") | (df['TARGET'] == 0)]

    # Downsample class 1
    if max_skewness == 0:  # change nothing
        size = len(df_class_1)
    elif max_skewness >= 1:
        size = int(min(max_skewness * len(df_class_0), len(df_class_1)))
    else:  # max_skewness < 1 but > 0, then increase reduce size of class 1 even more so that class 0 is overrepresented
        size = int(max_skewness * len(df_class_0))
    try:
        df_class_1_downsampled = resample(df_class_1, replace=False, n_samples=size, random_state=1)
    except ValueError:
        print("Class 0 still too large, smapling class 1 with replacement")
        df_class_1_downsampled = resample(df_class_1, replace=True, n_samples=size, random_state=1)

    # Combine minority class with downsampled majority class
    df_downsampled = pd.concat([df_class_1_downsampled, df_class_0])
    if max_size and max_size < len(df_downsampled):
        df_downsampled = df_downsampled.sample(max_size, random_state=1)

    if return_index is True:
        return df_downsampled.index
    else:
        return df_downsampled.drop('TARGET', axis=1), df_downsampled['TARGET']

def export_decisiontree(tree_model, file_path, feature_names):
    export_graphviz(tree_model, out_file=file_path, precision=2,
                    filled=True, feature_names=feature_names)

def load_ai_blocks(files, max_size, min_size):
    blocks = []
    print(len(files))
    for f in files:
        df = pd.read_excel(f)
        if max_size >= len(df) > min_size:
            blocks.append(extract_file_name_from_path(f)[0])
    return blocks

def build_similarity_matrices(blocks, features, verbose=False, squared=False):
    """for each ai in blocks, build a DataFrame containing the attributes and a DataFrame containing all
     pairwise combinations (=features) of all authorships in the block.
     Return dictionaries {ai: attributes_df} and {ai: features_df}"""

    def build_similarity_matrix(block, features, verbose=False, squared=False):
        d = Disambiguator(block)
        """get attrs from features"""
        feature_to_attr = d.feature_to_pw_comp_method
        create_attrs = [v[0] for f, v in feature_to_attr.items() if f in features and f != "aid_equal"]
        create_attrs = list(set(create_attrs))
        print(f"create attrs: {create_attrs}")
        d.populate_block(verbose=verbose)
        for col in ['country', 'city']:  # entries are list objects but stored in file as strings
            if col in d.block.columns:
                d.block.loc[:, col] = d.block.loc[:, col].map(convert_str_to_list)
        d.ignore_ambiguous_authorships()
        d.prepare_attributes_for_modelling(create_attrs=create_attrs)
        if verbose:
            print("Attributes: ", d.attributes.columns)

        d.build_all_pw_comparisons(store_pw_combs=True, squared=squared, features=features)
        feats = d.feature_matrix.merge(d.pw_combs[['document_id_x', 'document_id_y']], how='outer',
                                       left_index=True,
                                       right_index=True)  # TODO: this simply adds document_ids and should be replaced by real IDs

        return feats, d.attributes

    print(f"features: {features}")
    ai_block_to_similarity_matrix = {}
    ai_block_to_all_attrs = {}
    print('...')
    print(len(blocks))

    for ai_block in blocks:
        if verbose:
            print(ai_block)
        feats, attrs = build_similarity_matrix(ai_block, features, verbose, squared)

        ai_block_to_all_attrs[ai_block] = attrs
        ai_block_to_similarity_matrix[ai_block] = feats

    return ai_block_to_similarity_matrix, ai_block_to_all_attrs

def remove_document_id_col(df):
    cols = [c for c in df.columns if not c.startswith('document_id')]
    return df[cols].copy()

def remove_duplicate_rows(df):
    return df.drop_duplicates().reset_index(drop=True)

def split_into_features_and_target(df, target_col):
    d = df.copy()
    d.loc[:, target_col] = d[target_col].map({'true': 1, 'false': 0})
    features_df, target = d.drop(target_col, axis=1), d[target_col]
    return features_df, target

def vectorize_categorical_features(df, target_col, cat_attrs):
    cat_cols = [c for c in df.columns if c in cat_attrs and c != target_col]
    return pd.get_dummies(df, columns=cat_cols)

def encode_path_params_for_model_dump(model_type, scoring_func, max_block_size, min_block_size, downsample_ratio):
    file_name_part = '_'.join([model_type, scoring_func, 'blocksize_range', str(min_block_size), str(max_block_size),
                               'max_skewness', str(downsample_ratio)])
    file_name_clf = file_name_part + '.pkl'
    file_name_validation_blocks = 'ai_blocks_validate_' + file_name_part + '.pkl'
    file_name_feature_info = 'feature_info_' + file_name_part + '.pkl'

    return file_name_clf, file_name_validation_blocks, file_name_feature_info

def load_model(model_type, scoring_func, max_block_size, min_block_size, downsample_ratio):
    file_name_clf, file_name_validation_blocks, \
    file_name_feature_info = encode_path_params_for_model_dump(model_type, scoring_func, max_block_size, min_block_size,
                                                               downsample_ratio)
    clf = joblib.load(join(DIR_PATH, 'models', file_name_clf))
    feature_info = joblib.load(join(DIR_PATH, 'models', file_name_feature_info))

    return clf, feature_info  # , ai_blocks_validate

def remove_obvious_nonmatches(df):
    """Remove rows from feature matrix (each row represents comparison of two authorships) where
    first_name or middle_name or middle_name_init are incompatible"""
    cond_first_name = (df['first_name_equal'] != 'false')
    cond_middle_name = (df['middle_name_equal'] != 'false')
    cond_middle_name_init = (df['middle_name_init_equal'] != 'false')

    return df[cond_first_name & cond_middle_name & cond_middle_name_init]

def filter_by_ai_blocks(block_to_f_mat, block_to_a_mat, blocks):
    block_to_f_mat_reduced = {k: v for k, v in block_to_f_mat.items() if k in blocks}
    block_to_a_mat_reduced = {k: v for k, v in block_to_a_mat.items() if k in blocks}

    return blocks, block_to_f_mat_reduced, block_to_a_mat_reduced

def fill_missing_feature_cols(df, feature_cols):
    for f in set(feature_cols).difference(set(df.columns)):
        df[f] = 0
    df = df.reindex(columns=feature_cols)
    return df

def filter_ai_blocks_by_size(block_to_matrix, block_to_attr, max_size, min_size):
    blocks = [b for b, m in block_to_attr.items() if max_size >= len(m) > min_size]
    bm = {b: m for b, m in block_to_matrix.items() if b in blocks}
    ba = {b: a for b, a in block_to_attr.items() if b in blocks}

    return blocks, bm, ba

def remove_au_pairs_with_same_doc_id(feat_matrix):
    doc_id_cols = [c for c in feat_matrix.columns if c.startswith('document_id')]
    assert len(doc_id_cols) == 2
    col_1, col_2 = doc_id_cols[0], doc_id_cols[1]
    """
    document_id cols contain author position after + sign.
    Restrict to only those rows (authorship pairs) where doc id is different.
    """
    return feat_matrix[
        feat_matrix[col_1].map(lambda x: x.split('+')[0]) != feat_matrix[col_2].map(
            lambda x: x.split('+')[0])].reset_index(drop=True)

def prepare_sim_matrix_for_clustering(feat_matrix, features):
    """Does not reduce the x-dimension of matrix, only manipulation of features (columns)"""
    data_cluster = remove_document_id_col(feat_matrix)
    x = split_into_features_and_target(data_cluster, TARGET)[0]
    x = vectorize_categorical_features(x, TARGET, CATEGORICAL_FEATURES)
    x = fill_missing_feature_cols(x, features)
    return x

def load_matrices(blocks):
    ai_block_to_matrix = load_pickle_file(join(PATH_MATRICES, 'ai_block_to_matrix.pickle'))
    ai_block_to_attrs = load_pickle_file(join(PATH_MATRICES, 'ai_block_to_attrs.pickle'))
    ai_blocks, ai_block_to_matrix, ai_block_to_attrs = filter_by_ai_blocks(ai_block_to_matrix, ai_block_to_attrs,
                                                                           blocks)

    return ai_block_to_attrs, ai_block_to_matrix


import datetime
import json
from interval import intervalRandOrNot
from sendMail import sendMail

def sender(mails,repet=1,interval=-1,approx=-1):
    repet = int(repet)
    dateStart = datetime.datetime.today()
    spaceTime = intervalRandOrNot(interval,approx)

    count = 0

    stop = False

    while stop != True :
        diffTmstp = datetime.datetime.today().timestamp() - dateStart.timestamp()

        if (diffTmstp >= spaceTime["spaceTime"]):

            mailToRemoveList = []

            for mail in mails :

                sendPending = sendMail(mail)
                logFile = '..\logs\log_' + str(datetime.datetime.today().timestamp())+ '.json'

                if sendPending["error"] != -1:

                    logContent = {
                        "mail" :{
                            "sendTime":str(datetime.datetime.today()),
                            "diffTime":str(spaceTime["randomInterval"]),
                            "sender":mail["email_address"],
                            "receiver": mail["email_receiver"]
                            }
                        }
                    dateStart = datetime.datetime.today()
                    spaceTime = intervalRandOrNot(spaceTime["interval"],spaceTime["approx"])

                else :

                    logContent = {
                        "error" : {
                            "errorTime":str(datetime.datetime.today()),
                            "errorMsg":str(sendPending["errorText"]),
                            "sender":mail["email_address"],
                            "receiver": mail["email_receiver"]
                        }
                    }
                    mailToRemoveList.append(mail)

                f = open(logFile, 'w')
                json.dump(logContent,f)
                f.close()

            for mailToRemove in mailToRemoveList:

                mails.remove(mailToRemove)

                if len(mails)<1:
                    return None
            count += 1
            if count == repet:
                stop = True


import json
from system_info import SystemInfo

data = {}
h1 = SystemInfo()
data["cpu_temperature"] = h1.cpu_temperature
data["disk_space"] = h1.disk_space
data["cpu_use"] = h1.cpu_use
data["ram_info"] = h1.ram_info
print(json.dumps(data))


# Abre o arquivo de entrada
with open("funcionarios.txt", "r") as arquivo_entrada:

    # Lê todas as linhas do arquivo
    linhas = arquivo_entrada.readlines()
    # Itera sobre as linhas
    for linha in linhas:
        # Separa as informações de cada funcionário
        funcionario = linha.strip().split(",")

        # Imprime as informações na tela
        print(f"Nome: {funcionario[0]}")
        print(f"Idade: {funcionario[1]}")
        print(f"Gênero: {funcionario[2]}\n")
        #print()

# Cria um novo arquivo de saída
with open("funcionarios_com_salario.txt", "w") as arquivo_saida:
    # Itera sobre as linhas do arquivo de entrada novamente
    for linha in linhas:
        # Separa as informações de cada funcionário
        funcionario = linha.strip().split(",")

        # Calcula um salário fictício para o funcionário
        salario = int(funcionario[1]) * 1000

        # Escreve as informações do funcionário e o salário no novo arquivo
        arquivo_saida.write(f"{funcionario[0]}, {funcionario[1]}, {funcionario[2]}, {salario}\n")


from collections import deque
n = int(input())

def d(p1, p2):
    return ((p1[0]-p2[0])**2+(p1[1]-p2[1])**2)**0.5

p = [[*map(int, input().split())]for _ in range(n)]
g = [[]for _ in range(n)]
for i in range(n-1):
    for j in range(i+1, n):
        dist = d(p[i], p[j])
        g[i].append((dist, j))
        g[j].append((dist, i))

dp = [[1e9]*n for _ in range(1 << n)]
r = 1e9
q = deque([(1, 0)])
dp[1][0] = 0
while q:
    qry, now = q.popleft()
    if qry+1 == 1 << n:
        r = min(r, dp[qry][now] + g[now][0][0])
        continue
    for next_dist, next_node in g[now]:
        if qry & ~(1 << next_node) and dp[qry | (1 << next_node)][next_node] > dp[qry][now]+next_dist:
            dp[qry | (1 << next_node)][next_node] = dp[qry][now]+next_dist
            q.append((qry | (1 << next_node), next_node))

print(r)


#!/usr/bin/env python
from __future__ import absolute_import
from __future__ import division
from flask import Flask, render_template, Response,jsonify
from imutils import face_utils
import cv2, imutils, dlib, numpy as np, os, tensorflow as tf, sys
import struct, collections
import gestureframework as plib

app = Flask(__name__)

status_text='';
detector = dlib.get_frontal_face_detector()
pl=''
probables = ''
gls=[]
feedback_decisions=[]
blink=0
indexpred = 0;
predictor = dlib.shape_predictor('models/face-detector.dat')
model_points = np.array([
                            (0.0, 0.0, 0.0),             # Nose tip
                            (0.0, -330.0, -65.0),        # Chin
                            (-225.0, 170.0, -135.0),     # Left eye left corner
                            (225.0, 170.0, -135.0),      # Right eye right corne
                            (-150.0, -150.0, -125.0),    # Left Mouth corner
                            (150.0, -150.0, -125.0)      # Right mouth corner

                        ])

@app.route('/')
def index():
	return render_template('home.html')

def image_resize(image):
	r = 100.0 / image.shape[1]
	dim = (100, int(image.shape[0] * r))
	resized = cv2.resize(image, dim, interpolation = cv2.INTER_AREA)
	return resized

def get_frame():
	camera=cv2.VideoCapture(0)

	COUNTER = 0
	EYE_AR_THRESH = 0.22#0.2
	EYE_AR_CONSEC_FRAMES = 10
	classification_flag=0
	feedback_flag=0
	classify_count=0
	fr=1
	first_letter=[]
	first_probability=[]
	second_letter=[]
	second_probability=[]
	firstdecision='na'
	seconddecision='na'
	feedback_count=0
	predicted_letter=''
	predictions_intotal = []
	letters = []

	while True:
		grabbed, frame = camera.read()
		global status_text
		status_text='Video Capture starts.'
		size = frame.shape
		h=size[0]
		w=size[1]
		gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
		rects = detector(gray, 0)
		focal_length = size[1]
		center = (size[1]/2, size[0]/2)
		camera_matrix = np.array(
								 [[focal_length, 0, center[0]],
								 [0, focal_length, center[1]],
								 [0, 0, 1]], dtype = "double"
								 )
		if len(rects) != 0:
			status_text='Face Detected!'
			maxArea = 0
			maxRect = None
			for rect in rects:
				if rect.area() > maxArea:
					maxArea = rect.area()
					maxRect = [rect.left(),rect.top(),rect.right(),rect.bottom()]
			rect = dlib.rectangle(*maxRect)
			shape = predictor(gray, rect)
			global blink
			if blink==0:
				left_eye,right_eye,ear=plib.eyes_detection(shape)
				status_text='Eyes Detected!'
				blink = 1;
			elif blink==1:
				landmarks = plib.dlibLandmarksToPoints(shape)
				landmarks = np.array(landmarks)
				#for (x, y) in landmarks:
					#cv2.circle(frame, (x, y), 1, (0, 0, 255), -1)
				if (classification_flag==0):
					ix = landmarks[32][0]
					fx = landmarks[34][0]
					iy = landmarks[29][1]
					fy = landmarks[30][1]
					tempimg = frame[iy:fy,ix:fx,:]
					status_text='Nose skin detection!'
					meanimg = np.uint8([[cv2.mean(tempimg)[:3]]])
					skinRegionycb,skinycb = plib.findSkinYCB(meanimg, frame)

					maskedskinycb = plib.applyMask(skinycb, landmarks)
					#cv2.putText(skinycb, "YCrCb", (50, 50), cv2.FONT_HERSHEY_COMPLEX, .9, (255,255,255), 1, cv2.LINE_AA)

					x1=int(landmarks[0][0])
					#cv2.circle(frame, (400,200),10, (255,0,0),-1)
					newframe=frame[:,0:x1]
					maskedframe=maskedskinycb[:,0:x1]
					handregion=skinRegionycb[:,0:x1]

					drawing,xh,yh,wh,hh=plib.handconvex(handregion,newframe,maxArea)

					if ((xh!=0) and (yh!=0) and (wh!=0) and (hh!=0)):
						status_text='Hand Detected..'
						crphand=maskedframe[yh:yh+hh,xh:xh+wh]
						r = 90.0 / crphand.shape[1]
						dim = (90, int(crphand.shape[0] * r))
						resized = crphand

						if classify_count<20:
							if (fr%2)==0:
								resized = cv2.resize(resized, (224,224))
								np_image_data = np.asarray(resized)
								np_image_data=cv2.normalize(np_image_data.astype('float'), None, -0.5, .5, cv2.NORM_MINMAX)
								np_final = np.expand_dims(np_image_data,axis=0)
								predictions=plib.handclassify(np_final)
								letter,confidence=predictions[0]
								first_letter.append(letter)
								first_probability.append(confidence)
								letter,confidence=predictions[1]
								second_letter.append(letter)
								second_probability.append(confidence)
								classify_count=classify_count+1
								for i in predictions:
									predictions_intotal.append(i)
						else:
							status_text='Hand Gesture Recognized'
							classification_flag=1
							letters_counter=collections.Counter(first_letter)
							#print(letters_counter)
							letters=sorted(letters_counter.items(), key=lambda x: x[1])
							predicted_letter,freq=letters[len(letters)-1]
							global indexpred
							indexpred = len(letters)-1
							print("madan. " + str(indexpred));
							global pl
							pl='Predicted letter : '+predicted_letter
							global probables
							#probables = "Probable letters with confidence : {}".format('\n '.join(str(v) for v in reversed(letters)));
							#print('Predictions'+ str(predictions))
							probables = "Probable letters with confidence : {}".format(str(letters))
				else:
					status='Feedback Mode..'
					global feedback_decisions
					if feedback_count<20 or len(feedback_decisions) == 0:
						feedback_count=feedback_count+1
					else:
						feedback = feedback_decisions[0]
						if feedback == 'inprobables':
							indexpred-=1;
							print("madan. " + str(indexpred));
							if (indexpred >= 0):
								predicted_letter,freq=letters[indexpred]
								#print('Next Predicted letter: '+predicted_letter)
								pl='Predicted letter : '+predicted_letter
							else:
								firstdecision='na'
								seconddecision='na'
								classification_flag=0
								classify_count=0
								pl=''
								probables = ''
								first_letter=[]
								second_letter=[]
						elif feedback == 'yes':
							gls.append(predicted_letter)
							pl='Predicted letter : '+predicted_letter
							pl=''
							probables = ''
							firstdecision='na'
							classification_flag=0
							classify_count=0
							first_letter=[]
							second_letter=[]
						elif feedback == 'no':
							firstdecision='na'
							seconddecision='na'
							classification_flag=0
							classify_count=0
							pl=''
							probables = ''
							first_letter=[]
							second_letter=[]
						else:
							print("nothing")
						feedback_decisions=[]
						feedback_count=0
						if (classification_flag==0):
							indexpred = 0
		else:
			status_text='No Faces Detected..'

		fr=fr+1
		imgencode=cv2.imencode('.jpg',frame)[1]
		stringData=imgencode.tostring()
		yield (b'--frame\r\n'
            b'Content-Type: text/plain\r\n\r\n'+stringData+b'\r\n')
	del(camera)

@app.route('/status')
def status():
	status_result = {'status': status_text, 'predicted_letter': pl,'probables': probables}
	return jsonify(status_result)
@app.route('/calc')
def calc():
     return Response(get_frame(),mimetype='multipart/x-mixed-replace; boundary=frame')
@app.route('/yes')
def yesmessage():
	global feedback_decisions
	feedback_decisions.append('yes')
	global blink
	blink = 1
	return "success"
@app.route('/inprobables')
def inprobablesmessage():
	global feedback_decisions
	feedback_decisions.append('inprobables')
	global blink
	blink = 1
	return "success"
@app.route('/no')
def nomessage():
	global feedback_decisions
	feedback_decisions.append('no')
	global blink
	blink = 1
	return "success"
if __name__ == '__main__':
	app.run(host='0.0.0.0', debug=True, threaded=True)


# This file contains functions that find the initial centers
# for kmeans clustering.
# content(functions):
#   - create(centers). Display found center point as red pixel.

import kmeans.IO.load_image as loader
import os
import numpy as np
import skimage.io as io
import kmeans.image_processing.mask as mk
import matplotlib.pyplot as plt
import kmeans.image_processing.image_properties as image_properties

def create_centers(img_input, r, color_treshold):
    r""" This function creates an array of initial centers for kmeans().
    It is based on finding next-closest pixel with highest intensity,
    and then wiping out all pixel values within a radius r.

        - input:
            - img_np: a np.array of the preprocessed image

            - r: the radius of the circular mask to be created.
            It corresponds to the average radius of the nuclei,
            as estimated by radius.estimate_radius()

            - color_treshold: an integer number between 0-255.
            This sets the treshold which intensity values to include.

        - output:
            - save_c_max: a np.array containing the initial centers.
    WARNING:
        - img_input has to be a grayscale image (2D np.array) with the objects of
        interest having higher intensity values than the background !
    """

    # make a copy of the input image
    img_np = np.copy(img_input[:,:,2])

    # cast radius to int
    r = np.int32(r)

    # define the dimensions of extended image
    ext1 = img_np.shape[0]+2*r
    ext2 = img_np.shape[1]+2*r

    # create the extended image
    img_ext = np.zeros((ext1, ext2))

    # indexing for copying all img_np pixels into img_ext
    left_index = (r,r)
    right_index = (img_ext.shape[0]-r, img_ext.shape[1]-r)

    # select axis0 and axis1 values of img_ext which are to be
    # replaced with img_np values.
    img_ext[left_index[0]:right_index[0], left_index[1]:right_index[1]] = img_np
    #io.imshow(img_ext)
    #io.show()
    #print(img_ext)

     # define the circular mask of radius r.
    mask = mk.circular_mask(r)

    # WHILE INSTANTIATION
    # This loop finds out the positions of intensity values maxcol
    # in the image. maxcol is initially set to 255, but
    # gets updated during the loop and will correspond to the maximum
    # intensity value found in the image. Then, all pixels will be
    # selected with the same intensity value.

    maxcol = 255

    # create an empty list to save the maximum intensity value corresponding
    # to the center of a nucleus.

    save_c_max = []

    while maxcol > color_treshold:
         # find maximum intensity value in img_ext.
        maxcol = np.amax(img_ext)

        # find position of maxcol value
        img_whitex, img_whitey = np.where(img_ext == maxcol)

        # select the first position with maximum intensity value
        first = (img_whitex[0], img_whitey[0])

        # specify indices where to apply the mask
        left_index = (first[0]-r, first[1]-r)
        right_index = (first[0]+r, first[1]+r)

        # create a squared subselection of the img_ext whose size is equal to mask
        submattochange = img_ext[left_index[0]:right_index[0], left_index[1]:right_index[1]]

        # apply the mask
        img_ext[left_index[0]:right_index[0], left_index[1]:right_index[1]] = np.multiply(submattochange,mask)

        # show the cells replaced by the mask
        # io.imshow(img_ext)
        # io.show()

        # save the values of position and intensity
        list_save = [first[0]-r, first[1]-r, maxcol]

        # put list_save list into save_c_max
        save_c_max.append(list_save)

    # cast save_c_max to int
    save_c_max = np.int32(np.array(save_c_max))

    i = 0
    while i < save_c_max.shape[0]:

        # This while iterates over all found center pixels of
        # the nuclei and replaces their color with red
        # (channel 0, intensity 255).

        img_input[save_c_max[i,0], save_c_max[i,1], 0] = 255
        i = i+1

    #r"""
    #Display image of the nuclei whose found center pixel
    #is colored red.
    #"""
    #plt.figure()
    #io.imshow(img_input)
    #io.show()

    return save_c_max # np.array that contains int of position and intensity of the centers

def random_centers(k,):
    r""" A function that computes random intial centers.
    k has to be given. Not working yet.
    """
    #centr = np.random.random((k, pos.shape[1]))
    return


from django.shortcuts import render,redirect
from .models import Photo,Video
from django.db.models import F
from accounts.models import (
    FanOfTheMatch,ManOfTheMatch,
    TravelWithTheTeam,MomementOfTheMatch,
)
from django.core.paginator import Paginator
from django.contrib import messages

# Create your views here.
def photo_view(request):
    template_name = 'fanzone/photos_list.html'
    photos_list = Photo.objects.all()
    paginator = Paginator(photos_list,8) # Show 25 contacts per page

    page = request.GET.get('page')
    photos = paginator.get_page(page)
    return render(request,template_name,{'photos':photos})

def video_view(request):
    template_name = 'fanzone/videos_list.html'
    videos_list = Video.objects.all()
    paginator = Paginator(videos_list,4) # Show 25 contacts per page

    page = request.GET.get('page')
    videos = paginator.get_page(page)
    return render(request,template_name,{'videos':videos})

def voting_view(request):
    template_name = 'fanzone/voting.html'
    mtm = ManOfTheMatch.objects.filter(published=True)
    ftm = FanOfTheMatch.objects.filter(published=True)
    motm = MomementOfTheMatch.objects.filter(published=True)
    ttt = TravelWithTheTeam.objects.filter(published=True)

    return render(request,template_name,{'mtm':mtm,'ftm':ftm,'motm':motm,'ttt':ttt})

def man_of_the_match_votes(requests,mtm_id):
    mtm = ManOfTheMatch.objects.get(id=mtm_id)
    mtm.votes = F('votes') + 1
    mtm.save()
    print(mtm.votes)
    mtm.refresh_from_db()
    print(mtm.votes)
    new_vote =  mtm.votes
    messages.success(requests, 'Thank you for voting.')
    return redirect('fanzone:voting')

def fan_of_the_match_votes(requests,fan_id):
    fan = FanOfTheMatch.objects.get(id=fan_id)
    fan.votes = F('votes') + 1
    fan.save()
    print(fan.votes)
    fan.refresh_from_db()
    print(fan.votes)
    new_vote =  fan.votes
    messages.success(requests, 'Thank you for voting.')
    return redirect('fanzone:voting')

def moment_of_the_match_votes(requests,momt_id):
    momt = MomementOfTheMatch.objects.get(id=momt_id)
    momt.votes = F('votes') + 1
    momt.save()
    print(momt.votes)
    momt.refresh_from_db()
    print(momt.votes)
    new_vote =  momt.votes
    messages.success(requests, 'Thank you for voting.')
    return redirect('fanzone:voting')

def travel_with_the_team_votes(requests,ttt_id):
    ttt = TravelWithTheTeam.objects.get(id=ttt_id)
    ttt.votes = F('votes') + 1
    ttt.save()
    print(ttt.votes)
    ttt.refresh_from_db()
    print(ttt.votes)
    new_vote = ttt.votes
    messages.success(requests, 'Thank you for voting.')
    return redirect('fanzone:voting')


import sys
input = sys.stdin.readline
sys.setrecursionlimit(10**6)

def dfs(start, color):
    global answer

    for i in graph[start]:
        if not visited[i]:
            visited[i] = -color
            dfs(i, -color)
        elif visited[i] == -color:
            pass
        else:
            answer = "NO"
            break

k = int(input())
for _ in range(k):
    V, E = map(int, input().split())
    graph = [[] for _ in range(V+1)]
    visited = [0]*(V+1)
    answer = "YES"
    for _ in range(E):
        u, v = map(int, input().split())
        graph[u].append(v)
        graph[v].append(u)

    for i in range(1, V):
        if not visited[i]:
            dfs(i, 1)
    print(answer)

백준/Gold/1707. 이분 그래프/이분 그래프.py


'''
public int plus(int a, int b){
    sum = a + b;
    return sum;
}
function plus(a, b){
    var sum = a + b;
    return sum
}
'''

def plus(a, b):
    sum = a + b
    return sum

result = plus(3, 7)
print(result)

result = plus("3", "한글")
print(result)

print("============================================")

def my_function():
    print("hello world")

my_function()

def noMsg():
    pass

print(noMsg())
print("============================================")

'''
a, b = (1, 2)
print(a)
print(b)
'''

def sum_and_mul(a, b):
    sum = a + b
    mul = a * b
    return sum, mul

num1, num2 = sum_and_mul(3, 7)
print(num1)
print(num2)

result = sum_and_mul(3, 7)  # 튜플로 넘어온다
print(result, type(result))
print(result[0])
print(result[1])

print("==========================================")

def plusPrint(a=100, b=1000):
    print("a=%d, b=%d 이고 합은 %d 입니다." % (a, b, a + b))

plusPrint(3, 7)
plusPrint(7)
# plusPrint(, 7) 오류
plusPrint(b=70)  # a=기본값(100)  b=70
plusPrint(b=7, a=3)

print("==========================================")

def sum_many(*data):
    # data = (1,2,3,4,5)
    # data = (1, 2)
    sum = 0;
    for num in data:
        sum = sum + num

    return sum

print(sum_many(1, 2))
print(sum_many(1, 2, 3))
print(sum_many(1, 2, 3, 4))
print(sum_many(1, 2, 3, 4, 5, 6, 7, 8, 9))

print("==========================================")

def sum_mul(mode, *args):
    # 더하기
    if mode == "sum":
        result = 0
        for i in args:
            result = result + i

    elif mode == "mul":
        result = 1
        for i in args:
            result = result * i

    else:
        result = "오류"

    return result

print(sum_mul("sum", 1, 2, 3, 4, 5, 6, 7))
print(sum_mul("mul", 5, 6, 7))

'''
print(sum_mul("sum", 1,2,3)) #더하기
print(sum_mul("mul", 1,2,3)) #곱하기
'''

print("=======================================")

def addPerson(hp, **kwargs):
    print(hp)
    print(kwargs)  # 타입 딕션어리

addPerson('010-222-3333', name='김가은', age=27)

print("=======================================")

def addPerson2(*hp, **kwargs):
    print(hp)  # 타입 튜플
    print(kwargs)  # 타입 딕션어리

addPerson2('010-222-3333', name='김가은', age=28)
addPerson2('010-222-3333', '010-222-2222', name='김가은', age=27)
addPerson2('010-222-3333', '010-222-2222', '010-222-2222', name='김가은', age=27)


import sys
import csv

def main():

    if argv() == True:
        try:
            people =[]
            with open(sys.argv[1]) as file_before:
                reader = csv.DictReader(file_before)
                for row in reader:
                    name = row['name'].split(',')
                    house = row['house']
                    first_name = name[1].lstrip()
                    last_name = name[0]
                    people.append({'first': first_name , 'last': last_name, 'house': house})

            with open(sys.argv[2], 'w') as file_after:
                writer = csv.DictWriter(file_after, fieldnames=['first', 'last', 'house'])
                writer.writeheader()
                writer.writerows(people)

        except FileNotFoundError:
            sys.exit(f'Could bot read {sys.argv[1]}')

def argv():
    True
    if len(sys.argv) == 3 and  '.csv' in sys.argv[1]:
        return True
    elif len(sys.argv) < 3:
            sys.exit('Too few command-line arguments')
    elif len(sys.argv) > 3:
            sys.exit('Too many command-line arguments')
    else:
        sys.exit('not a csv file')

if __name__ == "__main__":
    main()


from django.contrib import admin
from django.urls import path,include
from . import views

urlpatterns=[

     path('', views.products, name='products'),
     path('product_details<int:id>/', views.product_details, name = 'product_details'),
     path('add_product/<int:id>', views.add_product, name='add_product'),
     path('delete_product<int:id>', views.delete_product, name = 'delete_product'),
     path('edit_product<int:id>/', views.edit_product, name = 'edit_product')

]


import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread('./test.jpg',cv2.WINDOW_NORMAL)
# cv2.namedWindow('transfrom')
rows,cols = img.shape

# 位移变换
M1 = np.float32([[1,0,50],[0,1,50]])
photo1 = cv2.warpAffine(img,M1,(rows,cols))
# cv2.imshow('transform',photo1)

# 旋转变换
M2 = cv2.getRotationMatrix2D((rows/2,cols/2),180,1)
photo2 = cv2.warpAffine(img,M2,(rows,cols))
# cv2.imshow('rotation',photo2)

# Affine 仿射变换(相对位置关系保留，输入三个点)
pts1 = np.float32([[50,50],[200,50],[50,200]])
pts2 = np.float32([[10,100],[100,50],[100,250]])
M3 = cv2.getAffineTransform(pts1,pts2)
photo3 = cv2.warpAffine(img,M3,(cols,rows))
#cv2.imshow('Affine',photo3)
plt.subplot(121),plt.imshow(img),plt.title('input')
plt.subplot(122),plt.imshow(photo3),plt.title('output')
plt.show()
cv2.waitKey(0)

# persipective 景深变换(输入四个点位置，任意三个非线性)
pts1 = np.float32([[56,65],[200,53],[28,200],[200,200]])
pts2 = np.float32([[0,0],[300,0],[0,300],[300,300]])
M4 = cv2.getPerspectiveTransform(pts1,pts2)
photo4 = cv2.warpPerspective(img,M4,(rows,cols))
plt.subplot(121),plt.imshow(img),plt.title('input')
plt.subplot(122),plt.imshow(photo4),plt.title('output')
plt.show()
cv2.destroyAllWindows()


import json
from pprint import pprint
currency = {"Country": "India", "Currency": "Rupee"}

json_var = json.dumps(currency)
print(json_var)
print(type(json_var))

with open("data_file/currency.json","a") as curr:
    curr.write(json_var)


# https://leetcode.com/problems/combination-sum/submissions/
class Solution:
    def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
        res = set()

        def helper(combo, sumCombo):
            if sumCombo > target:
                return

            if sumCombo == target:
                # we're adding sorted tuple to avoid duplicates
                # else we will add [2,3,3], [3,3,2] etc.
                res.add(tuple(sorted(combo)))
                # cant add more since all nums are positive
                # so we'll always overshoot target after this stage
                return

            # sum of combo is less than target
            for i in candidates:
                combo.append(i)
                helper(combo, sumCombo + i)
                combo.pop()

        helper([], 0)
        return [list(i) for i in res]


import numpy as np
import random
import numpy.random as npr

def roulette_wheel_selection(s, fitness_values):
    # function to fortune wheel
    def fortune_wheel():

        max = sum([fitness_values[i] for i in fitness_values])
        selection_probs = [fitness_values[i] / max for i in fitness_values]
        return npr.choice(len(fitness_values), p=selection_probs)

    mate = []
    p1 = fortune_wheel()
    p2 = fortune_wheel()
    while p2 == p1:
        print('p1: ', p1)
        print('p2: ', p2)
        p1 = fortune_wheel()
        p2 = fortune_wheel()
    mate.append(s[p1].chromosome)
    mate.append(s[p2].chromosome)
    return tuple(mate)

def tournament_selection(s, fitness_values):
    # function to create a tournament
    def tournament():
        tournament_size = round(0.2 * len(fitness_values))
        random_sample = random.sample(range(0, len(fitness_values)), tournament_size)
        corresponding_fitness_values = [fitness_values[i] for i in random_sample]
        position = corresponding_fitness_values.index(max(corresponding_fitness_values))
        return random_sample[position]

    # select parents
    mate = []
    p1 = tournament()
    p2 = tournament()
    while p2 == p1:
        p1 = tournament()
        p2 = tournament()
    mate.append(s[p1].chromosome)
    mate.append(s[p2].chromosome)
    return tuple(mate)

def random_selection(s):
    mate = []
    p1 = np.random.choice(list(s.keys()))
    p2 = np.random.choice(list(s.keys()))
    while p2 == p1:
        p1 = np.random.choice(list(s.keys()))
        p2 = np.random.choice(list(s.keys()))
    mate.append(s[p1].chromosome)
    mate.append(s[p2].chromosome)
    return tuple(mate)

class Parent_Selection:
    def __init__(self, s, fitness_values, evolutionary_learning_methods):
        self.parent_selection_method = evolutionary_learning_methods['parent_selection_method']
        if self.parent_selection_method == 'roulette_wheel_selection':
            self.mate = roulette_wheel_selection(s, fitness_values)
        elif self.parent_selection_method == 'tournament_selection':
            self.mate = tournament_selection(s, fitness_values)
        else:
            self.mate = random_selection(s)


# encoding: utf-8
# @author: MrZhou
# @file: 12continue语句.py
# @time: 2023/2/15 16:56
# @desc:
#  continue语句用来高速python跳过当前循环的剩余语句，然后继续进行下一轮循环
# continue 用在while和for循环中

var = 10  # 第二个实例
while var > 0:
    var = var - 1
    if var == 5:
        continue
    print('当前变量值 :', var)
print("Good bye!")


# This module contains the logic for "blending" of errors.
# Since prospector runs multiple tools with overlapping functionality, this
# module exists to merge together equivalent warnings from different tools for
# the same line. For example, both pyflakes and pylint will generate an
# "Unused Import" warning on the same line. This is obviously redundant, so we
# remove duplicates.
from collections import defaultdict

import pkg_resources
import yaml

__all__ = (
    "blend",
    "BLEND_COMBOS",
)

def blend_line(messages, blend_combos=None):
    """
    Given a list of messages on the same line, blend them together so that we
    end up with one message per actual problem. Note that we can still return
    more than one message here if there are two or more different errors for
    the line.
    """
    blend_combos = blend_combos or BLEND_COMBOS
    blend_lists = [[] for _ in range(len(blend_combos))]
    blended = []

    # first we split messages into each of the possible blendable categories
    # so that we have a list of lists of messages which can be blended together
    for message in messages:
        key = (message.source, message.code)
        found = False
        for blend_combo_idx, blend_combo in enumerate(blend_combos):
            if key in blend_combo:
                found = True
                blend_lists[blend_combo_idx].append(message)

        # note: we use 'found=True' here rather than a simple break/for-else
        # because this allows the same message to be put into more than one
        # 'bucket'. This means that the same message from pycodestyle can 'subsume'
        # two from pylint, for example.

        if not found:
            # if we get here, then this is not a message which can be blended,
            # so by definition is already blended
            blended.append(message)

    # we should now have a list of messages which all represent the same
    # problem on the same line, so we will sort them according to the priority
    # in BLEND and pick the first one
    for blend_combo_idx, blend_list in enumerate(blend_lists):
        if len(blend_list) == 0:
            continue
        # pylint:disable=cell-var-from-loop
        blend_list.sort(
            key=lambda msg: blend_combos[blend_combo_idx].index(
                (msg.source, msg.code),
            ),
        )
        if blend_list[0] not in blended:
            # We may have already added this message if it represents
            # several messages in other tools which are not being run -
            # for example, pylint missing-docstring is blended with pydocstyle
            # D100, D101 and D102, but should not appear 3 times!
            blended.append(blend_list[0])

        # Some messages from a tool point out an error that in another tool is handled by two
        # different errors or more. For example, pylint emits the same warning (multiple-statements)
        # for "two statements on a line" separated by a colon and a semi-colon, while pycodestyle has E701
        # and E702 for those cases respectively. In this case, the pylint error will not be 'blended' as
        # it will appear in two blend_lists. Therefore we mark anything not taken from the blend list
        # as "consumed" and then filter later, to avoid such cases.
        for now_used in blend_list[1:]:
            now_used.used = True

    return [m for m in blended if not getattr(m, "used", False)]

def blend(messages, blend_combos=None):
    blend_combos = blend_combos or BLEND_COMBOS

    # group messages by file and then line number
    msgs_grouped = defaultdict(lambda: defaultdict(list))

    for message in messages:
        msgs_grouped[message.location.path][message.location.line].append(
            message,
        )

    # now blend together all messages on the same line
    out = []
    for by_line in msgs_grouped.values():
        for messages_on_line in by_line.values():
            out += blend_line(messages_on_line, blend_combos)

    return out

def get_default_blend_combinations():
    combos = yaml.safe_load(pkg_resources.resource_string(__name__, "blender_combinations.yaml"))
    combos = combos.get("combinations", [])

    defaults = []
    for combo in combos:
        toblend = []
        for msg in combo:
            toblend += msg.items()
        defaults.append(tuple(toblend))

    return tuple(defaults)

BLEND_COMBOS = get_default_blend_combinations()