import asyncio
import logging
import traceback

import sentry_sdk
from aiogram import Bot
from aiogram import types
from aiogram.contrib.fsm_storage.redis import RedisStorage2
from aiogram.dispatcher import Dispatcher
from aiogram.dispatcher import FSMContext
from aiogram.dispatcher.filters import Text
from aiogram.types import ContentType
from aiogram.utils.executor import Executor
from helpers import log_button_click
from sentry_sdk import capture_exception
from sentry_sdk import capture_message
from telegram_bot.constants import START_COMMAND
from telegram_bot.constants import AdminConsts
from telegram_bot.constants import ButtonNames as BN
from telegram_bot.constants import DialogConsts
from telegram_bot.constants import Messages
from telegram_bot.db import setup_db
from telegram_bot.exceptions import ApplicationLogicException
from telegram_bot.filters import AdminFilter
from telegram_bot.helpers import PersonInfoToChannelResender
from telegram_bot.helpers import StoryToChannelResender
from telegram_bot.helpers import answer_with_actions_keyboard
from telegram_bot.helpers import check_return_or_start_cmd
from telegram_bot.helpers import create_person_info_from_message
from telegram_bot.helpers import get_obj_id_from_callback_data
from telegram_bot.helpers import is_dialog_finished
from telegram_bot.keyboards import CANCEL_DIALOG_KEYBOARD
from telegram_bot.keyboards import RETURN_KEYBOARD
from telegram_bot.keyboards import STOP_DIALOG_SEARCH_KEYBOARD
from telegram_bot.keyboards import get_person_info_keyboard_markup
from telegram_bot.keyboards import get_story_keyboard_markup
from telegram_bot.models import AnonymousDialog
from telegram_bot.models import PersonInformation
from telegram_bot.models import Story
from telegram_bot.settings import ADMIN_OBJS_COUNT_SETTING
from telegram_bot.settings import REDIS_STORAGE_PARAMS
from telegram_bot.settings import SENTRY_URL
from telegram_bot.settings import TOKEN
from telegram_bot.states import ProjectStates

if SENTRY_URL:
    sentry_sdk.init(
        SENTRY_URL,

        # Set traces_sample_rate to 1.0 to capture 100%
        # of transactions for performance monitoring.
        # We recommend adjusting this value in production.
        traces_sample_rate=1.0
    )

bot = Bot(token=TOKEN)
dp = Dispatcher(bot, storage=RedisStorage2(**REDIS_STORAGE_PARAMS))
dp.filters_factory.bind(AdminFilter)
runner = Executor(dp)
# Включаем логирование, чтобы не пропустить важные сообщения
logging.basicConfig(level=logging.INFO)

async def answer(message, text, photo_file_id=None, **kwargs):
    """Ответ на сообщение с текстом/изображением и доп. параметрами"""
    if photo_file_id:
        await message.answer_photo(photo_file_id, text, **kwargs)
    else:
        await message.answer(text, **kwargs)

@dp.message_handler(commands=[START_COMMAND])
@log_button_click
async def process_start_command(message: types.Message):
    """Выдает стартовое сообщение."""
    await message.answer(Messages.START)
    await answer_with_actions_keyboard(message, Messages.CHOOSE_ACTION)

@dp.message_handler(Text(BN.values[BN.SEND_INFORMATION_FORM]))
@log_button_click
async def send_information_form(message: types.Message):
    """Обработчик нажатия на кнопку отправки анкеты сообщений."""
    await message.answer(
        Messages.SEND_INFORMATION_FORM, parse_mode="Markdown")
    await message.answer(
        Messages.INFORMATION_FORM_TEMPLATE, reply_markup=RETURN_KEYBOARD)
    await ProjectStates.send_information_form.set()

# TODO: может сделать всплывающую форму с разными полями (?)
#  как у бота @DurgerKingBot (да, название именно такое:))
@dp.message_handler(state=ProjectStates.send_information_form,
                    content_types=[ContentType.ANY])
async def send_information_form_saving(
        message: types.Message, state: FSMContext):
    """Сохранение анкеты."""

    return_or_start_cmd = await check_return_or_start_cmd(message, state)
    if return_or_start_cmd:
        return

    await create_person_info_from_message(message)

    await answer_with_actions_keyboard(
        message, Messages.INFORMATION_FORM_PROCESSED)
    await state.finish()

@dp.message_handler(Text(BN.values[BN.SEND_STORY]))
@log_button_click
async def send_story(message: types.Message):
    """Обработчик нажатия на кнопку отправки интересной истории."""
    await message.answer(Messages.SEND_STORY, reply_markup=RETURN_KEYBOARD)
    await ProjectStates.send_story.set()

@dp.message_handler(state=ProjectStates.send_story)
async def story_saving(
        message: types.Message, state: FSMContext):
    """Сохранение истории."""
    return_or_start_cmd = await check_return_or_start_cmd(message, state)
    if return_or_start_cmd:
        return

    await Story.create(text=message.text, user_id=message.from_user.id)

    await answer_with_actions_keyboard(message, Messages.STORY_PROCESSED)
    await state.finish()

@dp.message_handler(Text(AdminConsts.GET_STORIES), is_admin=True)
async def get_user_stories(message: types.Message, state: FSMContext):
    """Получение админом историй."""

    user_stories = await Story.filter(
        is_published=False
    ).limit(ADMIN_OBJS_COUNT_SETTING)

    if not user_stories:
        raise ApplicationLogicException(AdminConsts.STORIES_IS_EMPTY)

    for story in user_stories:
        await message.answer(
            story.text, reply_markup=get_story_keyboard_markup(story.id))

@dp.callback_query_handler(
    lambda c: AdminConsts.DELETE_STORY_CODE in c.data)
async def delete_story(callback_query: types.CallbackQuery):
    """Удаление истории вместе с сообщением."""
    story_id = get_obj_id_from_callback_data(callback_query.data)
    await Story.filter(id=story_id).delete()

    if callback_query.message:
        await callback_query.message.delete()

@dp.callback_query_handler(
    lambda c: AdminConsts.APPROVE_STORY_CODE in c.data)
async def process_story_approve(callback_query: types.CallbackQuery):
    """Авто-пересылка истории в канал"""
    story_id = get_obj_id_from_callback_data(callback_query.data)
    await StoryToChannelResender(story_id, callback_query.message).send()

@dp.callback_query_handler(
    lambda c: AdminConsts.NEED_TO_EDIT_STORY_CODE in c.data)
async def need_to_edit_story(callback_query: types.CallbackQuery,
                             state: FSMContext):
    """Отправка истории на редактирование вместе с сообщением от админа."""
    story_id = get_obj_id_from_callback_data(callback_query.data)
    await state.set_data({'user_story_id': story_id})

    await callback_query.message.answer(
        AdminConsts.NEED_TO_EDIT_TO_ADMIN, reply_markup=RETURN_KEYBOARD)

    await ProjectStates.need_to_edit_story.set()

@dp.message_handler(state=ProjectStates.need_to_edit_story)
async def need_to_edit_story_send_msg(
        message: types.Message, state: FSMContext):
    """Отправка истории на редактирование вместе с сообщением от админа."""

    return_or_start_cmd = await check_return_or_start_cmd(message, state)
    if return_or_start_cmd:
        return

    state_data = await state.get_data()
    user_story_id = state_data.get('user_story_id', None)
    if user_story_id:
        story = await Story.filter(id=user_story_id).first()

        await bot.send_message(
            story.user_id,
            f'{AdminConsts.ADMIN_ANSWER}\n{Messages.STORY_NEED_TO_EDIT}',
            parse_mode="Markdown"
        )
        await bot.send_message(story.user_id, story.text)
        await bot.send_message(
            story.user_id, f'{AdminConsts.ADMIN_ANSWER}\n{message.text}',
            parse_mode="Markdown"
        )
        await answer_with_actions_keyboard(
            message, AdminConsts.ADMIN_MSG_SENDED)
    else:
        raise ApplicationLogicException('История не найдена!')
    await state.finish()

@dp.message_handler(Text(
    AdminConsts.GET_PERSON_INFO), is_admin=True)
async def get_user_info_forms(message: types.Message, state: FSMContext):
    """Получение админом анкет."""

    persons_information = await PersonInformation.filter(
        is_published=False
    ).limit(ADMIN_OBJS_COUNT_SETTING)

    if not persons_information:
        raise ApplicationLogicException(AdminConsts.PERSON_INFOS_IS_EMPTY)

    for person_info in persons_information:
        await answer(
            message, person_info.text, person_info.image_file_id,
            reply_markup=get_person_info_keyboard_markup(person_info.id)
        )

@dp.callback_query_handler(
    lambda c: AdminConsts.DELETE_PERSON_INFO_CODE in c.data)
async def delete_person_info(callback_query: types.CallbackQuery):
    """Удаление анкеты вместе с сообщением."""
    info_id = get_obj_id_from_callback_data(callback_query.data)
    await PersonInformation.filter(id=info_id).delete()

    if callback_query.message:
        await callback_query.message.delete()

@dp.callback_query_handler(
    lambda c: AdminConsts.APPROVE_PERSON_INFO_CODE in c.data)
async def process_person_info_approve(callback_query: types.CallbackQuery):
    """Авто-пересылка анкеты в канал"""
    person_info_id = get_obj_id_from_callback_data(callback_query.data)
    await PersonInfoToChannelResender(
        person_info_id, callback_query.message).send()

@dp.callback_query_handler(
    lambda c: AdminConsts.NEED_TO_EDIT_PERSON_INFO_CODE in c.data)
async def need_to_edit_person_info(callback_query: types.CallbackQuery,
                                   state: FSMContext):
    """Отправка анкеты на редактирование вместе с сообщением от админа."""
    person_info_id = get_obj_id_from_callback_data(callback_query.data)
    await state.set_data({'user_person_info_id': person_info_id})

    await callback_query.message.answer(
        AdminConsts.NEED_TO_EDIT_TO_ADMIN, reply_markup=RETURN_KEYBOARD)

    await ProjectStates.need_to_edit_person_info.set()

@dp.message_handler(state=ProjectStates.need_to_edit_person_info)
async def need_to_edit_person_info_send_msg(
        message: types.Message, state: FSMContext):
    """Отправка анкеты на редактирование вместе с сообщением от админа."""

    return_or_start_cmd = await check_return_or_start_cmd(message, state)
    if return_or_start_cmd:
        return

    state_data = await state.get_data()
    user_person_info_id = state_data.get('user_person_info_id', None)
    if user_person_info_id:
        person_info = await PersonInformation.filter(
            id=user_person_info_id).first()

        await bot.send_message(
            person_info.user_id,
            f'{AdminConsts.ADMIN_ANSWER}\n{Messages.INFO_NEED_TO_EDIT}',
            parse_mode="Markdown"
        )
        await bot.send_photo(
            person_info.user_id, person_info.image_file_id, person_info.text)
        await bot.send_message(
            person_info.user_id,
            f'{AdminConsts.ADMIN_ANSWER}\n{message.text}',
            parse_mode="Markdown"
        )
        await answer_with_actions_keyboard(
            message, AdminConsts.ADMIN_MSG_SENDED)
    else:
        raise ApplicationLogicException('Анкета не найдена!')
    await state.finish()

############### Dialog part ###############

@dp.message_handler(Text(BN.values[BN.START_ANONYMOUS_DIALOG]))
@log_button_click
async def start_anon_dialog_search(message: types.Message, state: FSMContext):
    """Обработчик нажатия на кнопку поиск собеседника для диалога."""
    current_user_id = message.from_user.id

    dialog_partner = await AnonymousDialog.filter(
        to_user_id__isnull=True).exclude(user_id=current_user_id).first()
    dialog_partner_id = getattr(dialog_partner, 'user_id', None)

    if dialog_partner_id:
        await state.finish()

        partner_dialog_state = Dispatcher.get_current().current_state(
            chat=dialog_partner_id, user=dialog_partner_id)
        if partner_dialog_state:
            await partner_dialog_state.finish()

        await ProjectStates.anon_dialog_state.set()
        await ProjectStates.anon_dialog_state.set(
            chat_id=dialog_partner_id,
            user_id=dialog_partner_id,
            # Для юзера, которому устанавливаем состояние диалога, так же
            # прокидываем id пользователя с которым он общается.
            data={'dialog_partner_id': current_user_id}
        )

        await state.set_data({'dialog_partner_id': dialog_partner_id})

        dialog_partner.to_user_id = current_user_id
        await dialog_partner.save()

        await message.answer(
            DialogConsts.PARTNER_FOUNDED, reply_markup=CANCEL_DIALOG_KEYBOARD)

        await bot.send_message(
            dialog_partner_id, DialogConsts.PARTNER_FOUNDED,
            reply_markup=CANCEL_DIALOG_KEYBOARD
        )
    else:
        await ProjectStates.search_anon_dialog_state.set()
        await message.answer(
            DialogConsts.SEARCH_STARTED_BUTTON,
            reply_markup=STOP_DIALOG_SEARCH_KEYBOARD, parse_mode="Markdown"
        )

        current_user_is_searching = await AnonymousDialog.filter(
            to_user_id__isnull=True,
            user_id=current_user_id
        ).exists()
        if not current_user_is_searching:
            await AnonymousDialog.create(user_id=current_user_id)

@dp.message_handler(state=ProjectStates.search_anon_dialog_state)
async def dialog_search(
        message: types.Message, state: FSMContext):
    """Обработчик сообщений для состояния поиска диалога."""
    state_data = await state.get_data()
    dialog_partner_id = state_data.get('dialog_partner_id', None)

    dialog_finished = await is_dialog_finished(
        message, state, dialog_partner_id)
    if dialog_finished:
        return
    await message.answer(DialogConsts.STILL_SEARCHING)

@dp.message_handler(state=ProjectStates.anon_dialog_state)
async def anon_dialog(
        message: types.Message, state: FSMContext):
    """Обработчик пересылки сообщений в диалоге."""
    state_data = await state.get_data()
    dialog_partner_id = state_data.get('dialog_partner_id', None)

    dialog_finished = await is_dialog_finished(
        message, state, dialog_partner_id)
    if dialog_finished:
        return

    if dialog_partner_id:
        await bot.send_message(dialog_partner_id, message.text)

############### End dialog part ###############

@dp.message_handler(Text(AdminConsts.SEND_SENTRY_ERROR_CMD))
async def send_test_sentry_error(message: types.Message):
    """Обработчик отправки тестового сообщения в Sentry."""
    capture_message('Тестовое сообщение в Sentry')
    await answer_with_actions_keyboard(
        message, 'Тестовое сообщение в Sentry отправлено!')

@dp.message_handler(content_types=[ContentType.ANY])
async def unknown_message_handler(message: types.Message):
    """Обработчик неизвестных сообщений."""
    await message.answer(Messages.UNKNOWN_MESSAGE)
    state = dp.current_state()
    await check_return_or_start_cmd(message, state)

@dp.errors_handler(exception=Exception)
async def message_not_modified_handler(update, error):
    """Обработка ошибок.

    В случае ApplicationLogicException, просто выводится сообщение из текста
    ошибки.
    В случае другой ошибки, выводится сообщение о непредвиденной ошибке,
    очищается контекст, и происходит выход на главный экран.
    """
    message = update.message or update.callback_query.message
    if isinstance(error, ApplicationLogicException):
        await message.answer(str(error))
    else:
        await answer_with_actions_keyboard(message, Messages.ERROR)
        state = dp.current_state()
        await state.finish()
        # TODO: добавить логирование
        # Отправка ошибки в Sentry
        if SENTRY_URL:
            capture_exception(error)
        traceback.print_exc()

    return True

if __name__ == '__main__':
    setup_db(runner)
    loop = asyncio.get_event_loop()
    runner.start_polling(dp)


#  Game class

import pygwidgets
import pygame
import random

from Constants import *

# Card Class
class Card:

    def __init__(self, window, rank, suit, value):
        # must add code here to save away parameters in instance variables
        # and create two Image objects, one for the current card, one for the backOfCard
        # you can remove this line when you add your own
        self.window = window
        self.rank = rank
        self.CardName = suit
        self.value = value
        self.image = pygwidgets.Image(window, (0, 0), 'images/' + self.rank + ' of ' + self.CardName + '.png')
        self.backOfImage = pygwidgets.Image(window, (0, 0), 'images/BackOfCard.png')
        self.cardImage = self.image
        self.loc = ''

    def conceal(self):
        self.image = self.backOfImage

    def setLoc(self, locTuple):
        self.image.setLoc(locTuple)
        self.loc = locTuple

    def reveal(self):
        self.image = self.cardImage

    def getName(self):
        return self.CardName

    def getValue(self):
        return self.value

    def draw(self):
        self.image.setLoc(self.loc)
        self.image.draw()

    @staticmethod
    def getCardNameAndValue():
        return ("CardName", 0)

# Deck Class
class Deck:
    SUIT_TUPLE = SUIT_TUPLE_VALUE
    RANK_TUPLE = RANK_TUPLE_VALUE
    STANDARD_VALUES_TUPLE = STANDARD_VALUES_TUPLE_VALUE

    def __init__(self, window, valuesTuple=STANDARD_VALUES_TUPLE):
        # If nothing is passed in for valuesTuple, it uses default values
        self.startingDeckList = []
        self.playingDeckList = []
        for suit in Deck.SUIT_TUPLE:
            for index, rank in enumerate(Deck.RANK_TUPLE):
                oCard = Card(window, rank, suit, valuesTuple[index])
                self.startingDeckList.append(oCard)

    def shuffle(self):
        # make a copy of the starting deck and save in the playing deck list
        self.playingDeckList = self.startingDeckList[:]
        for oCard in self.playingDeckList:
            oCard.conceal()
        random.shuffle(self.playingDeckList)

    def getCard(self):
        if len(self.playingDeckList) == 0:
            raise Exception('No more cards')
        oCard = self.playingDeckList.pop()  # pop one off the deck and return it
        return oCard

# Game Class
class Game:
    CARD_OFFSET = GAME_CARD_OFFSET_VALUE
    CARDS_TOP = GAME_CARDS_TOP_VALUE
    CARDS_LEFT = GAME_CARDS_LEFT_VALUE
    NCARDS = GAME_NCARDS_VALUE

    def __init__(self, window):
        self.window = window
        self.oDeck = Deck(self.window)
        self.score = 100
        self.scoreText = pygwidgets.DisplayText(window, (450, 164), 'Score: ' + str(self.score), fontSize=36, textColor=WHITE, justified='right')
        self.messageText = pygwidgets.DisplayText(window, (50, 460), '', width=900, justified='center', fontSize=36, textColor=WHITE)
        self.loserSound = pygame.mixer.Sound("sounds/loser.wav")
        self.winnerSound = pygame.mixer.Sound("sounds/ding.wav")
        self.cardShuffleSound = pygame.mixer.Sound("sounds/cardShuffle.wav")

        self.cardXPositionsList = []
        thisLeft = Game.CARDS_LEFT
        # Calculate the x positions of all cards ... once
        for i in range(Game.NCARDS):
            self.cardXPositionsList.append(thisLeft)
            thisLeft = thisLeft + Game.CARD_OFFSET
        self.reset()  # start a round of the game

    def reset(self):  # This method is called when a new round starts
        self.score = 100
        self.scoreText.setValue('Score: ' + str(self.score))
        self.cardShuffleSound.play()
        self.cardList = []
        self.oDeck.shuffle()
        for cardIndex in range(0, Game.NCARDS):  # Deal out cards
            oCard = self.oDeck.getCard()
            self.cardList.append(oCard)
            thisXPosition = self.cardXPositionsList[cardIndex]
            oCard.setLoc((thisXPosition, Game.CARDS_TOP))

        self.showCard(0)
        self.cardNumber = 0
        self.currentCardName, self.currentCardValue = self.getCardNameAndValue(self.cardNumber)
        self.messageText.setValue(
            'Starting card is ' + self.currentCardName + '. Will the next card be higher or lower?')

    def getCardNameAndValue(self, index):
        oCard = self.cardList[index]
        theName = oCard.getName()
        theValue = oCard.getValue()
        return theName, theValue

    def showCard(self, index):
        oCard = self.cardList[index]
        oCard.reveal()

    def hitHigherOrLower(self, higherOrLower):
        self.cardNumber = self.cardNumber + 1
        self.showCard(self.cardNumber)
        nextCardName, nextCardValue = self.getCardNameAndValue(self.cardNumber)

        if higherOrLower == HIGHER:
            if nextCardValue > self.currentCardValue:
                self.score = self.score + 15
                self.messageText.setValue('Yes, the ' + nextCardName + ' was higher')
                self.winnerSound.play()
            else:
                self.score = self.score - 10
                self.messageText.setValue('No, the ' + nextCardName + ' was lower')
                self.loserSound.play()

        else:  # user hit the lower button:
            if nextCardValue < self.currentCardValue:
                self.score = self.score + 15
                self.messageText.setValue('Yes, the ' + nextCardName + ' was lower')
                self.winnerSound.play()
            else:
                self.score = self.score - 10
                self.messageText.setValue('No, the ' + nextCardName + ' was higher')
                self.loserSound.play()

        self.scoreText.setValue('Score: ' + str(self.score))
        self.currentCardValue = nextCardValue  # set up for next higher/lower button choice

        done = (self.cardNumber == (Game.NCARDS - 1))  # did we reach the last card?
        return done

    def draw(self):
        # Tell each card to draw itself
        for oCard in self.cardList:
            oCard.draw()

        self.scoreText.draw()
        self.messageText.draw()


'''
-------------------------------------------------------------------------------
Name:		problem1.py
Purpose:	convert celsius to fahrenheit

Author:	Sedighi.R

Created:	date in 02/10/2019
------------------------------------------------------------------------------
'''

# get celsius from user
celsius = float(input("Enter the celsius: "))

# compute fahrenheit from celsius
fahrenheit = (9/5*celsius) + 32

# output fahrenheit
print("The temperature in fahrenheit is", fahrenheit)


# Multiply (Intro)
# This is an intro mission, the purpose of which is to explain how to solve missions on CheckiO.
# If you want to know how to get the maximum out of using CheckiO, check out our blog post "From Basic
# to Advance usage".

# This mission is the easiest one. Write a function that will receive 2 numbers as input and it should
# return the multiplication of these 2 numbers.

# Input: Two arguments. Both are of type int.

# Output: Int.

# Examples:

# assert mult_two(3, 2) == 6
# assert mult_two(0, 1) == 0

####################SOLUTION####################

def mult_two(a: int, b: int) -> int:
    c = a * b
    return c

print("Example")
print(mult_two(1, 2))

#######################OR#######################
mult_two = int.__mul__
#######################OR#######################
from operator import mul as mult_two
#######################OR#######################
import numpy as np

def mult_two(a, b):
    return np.product([a, b])

if __name__ == '__main__':
    print("Example:")
    print(mult_two(3, 2))


import argparse
from collections import OrderedDict

from amaranth import *
from amaranth.lib.cdc import ResetSynchronizer
from amaranth.build import *

from amaranth_soc import wishbone
from amaranth_soc.periph import ConstantMap

from amaranth_stdio.serial import AsyncSerial

from amaranth_boards.arty_a7 import ArtyA7_35Platform
from amaranth_boards.ecpix5 import ECPIX545Platform, ECPIX585Platform

from lambdasoc.cpu.minerva import MinervaCPU
from lambdasoc.periph.intc import GenericInterruptController
from lambdasoc.periph.serial import AsyncSerialPeripheral
from lambdasoc.periph.sram import SRAMPeripheral
from lambdasoc.periph.timer import TimerPeripheral
from lambdasoc.periph.sdram import SDRAMPeripheral
from lambdasoc.periph.eth import EthernetMACPeripheral

from lambdasoc.soc.cpu import CPUSoC, BIOSBuilder

from lambdasoc.cores.pll.lattice_ecp5 import PLL_LatticeECP5
from lambdasoc.cores.pll.xilinx_7series import PLL_Xilinx7Series
from lambdasoc.cores import litedram, liteeth
from lambdasoc.cores.utils import request_bare

from lambdasoc.sim.blackboxes.serial import AsyncSerial_Blackbox
from lambdasoc.sim.platform import CXXRTLPlatform

__all__ = ["MinervaSoC"]

class _ClockResetGenerator(Elaboratable):
    def __init__(self, *, sync_clk_freq, with_sdram, with_ethernet):
        if not isinstance(sync_clk_freq, (int, float)) or sync_clk_freq <= 0:
            raise ValueError("Sync domain clock frequency must be a positive integer or float, "
                             "not {!r}"
                             .format(sync_clk_freq))
        self.sync_clk_freq = sync_clk_freq
        self.with_sdram    = bool(with_sdram)
        self.with_ethernet = bool(with_ethernet)

    def elaborate(self, platform):
        m = Module()

        m.domains += [
            ClockDomain("_ref", reset_less=platform.default_rst is None, local=True),
            ClockDomain("sync"),
        ]

        m.d.comb += ClockSignal("_ref").eq(platform.request(platform.default_clk, 0).i)
        if platform.default_rst is not None:
            m.d.comb += ResetSignal("_ref").eq(platform.request(platform.default_rst, 0).i)

        # On the Arty A7, the DP83848 Ethernet PHY uses a 25 MHz reference clock.
        if isinstance(platform, ArtyA7_35Platform) and self.with_ethernet:
            m.domains += ClockDomain("_eth_ref", local=True)
            m.submodules += Instance("BUFGCE",
                i_I  = ClockSignal("_eth_ref"),
                i_CE = ~ResetSignal("_eth_ref"),
                o_O  = platform.request("eth_clk25", 0).o,
            )

        # The LiteDRAM core provides its own PLL, which drives the litedram_user clock domain.
        # We reuse this clock domain as the sync domain, in order to avoid CDC between LiteDRAM
        # and the SoC interconnect.
        if self.with_sdram:
            m.domains += ClockDomain("litedram_input")
            m.d.comb += ClockSignal("litedram_input").eq(ClockSignal("_ref"))
            if platform.default_rst is not None:
                m.d.comb += ResetSignal("litedram_input").eq(ResetSignal("_ref"))

            m.domains += ClockDomain("litedram_user")
            m.d.comb += [
                ClockSignal("sync").eq(ClockSignal("litedram_user")),
                ResetSignal("sync").eq(ResetSignal("litedram_user")),
            ]

            # On the Arty A7, we still use our own PLL to drive the Ethernet PHY reference clock.
            if isinstance(platform, ArtyA7_35Platform) and self.with_ethernet:
                eth_ref_pll_params = PLL_Xilinx7Series.Parameters(
                    i_domain     = "_ref",
                    i_freq       = platform.default_clk_frequency,
                    i_reset_less = platform.default_rst is None,
                    o_domain     = "_eth_ref",
                    o_freq       = 25e6,
                )
                m.submodules.eth_ref_pll = eth_ref_pll = PLL_Xilinx7Series(eth_ref_pll_params)

                if platform.default_rst is not None:
                    eth_ref_pll_arst = ~eth_ref_pll.locked | ResetSignal("_ref")
                else:
                    eth_ref_pll_arst = ~eth_ref_pll.locked

                m.submodules += ResetSynchronizer(eth_ref_pll_arst, domain="_eth_ref")

        # In simulation mode, the sync clock domain is directly driven by the platform clock.
        elif isinstance(platform, CXXRTLPlatform):
            assert self.sync_clk_freq == platform.default_clk_frequency
            m.d.comb += ClockSignal("sync").eq(ClockSignal("_ref"))
            if platform.default_rst is not None:
                m.d.comb += ResetSignal("sync").eq(ResetSignal("_ref"))

        # Otherwise, we use a PLL to drive the sync clock domain.
        else:
            if isinstance(platform, ArtyA7_35Platform):
                sync_pll_params = PLL_Xilinx7Series.Parameters(
                    i_domain     = "_ref",
                    i_freq       = platform.default_clk_frequency,
                    i_reset_less = platform.default_rst is None,
                    o_domain     = "sync",
                    o_freq       = self.sync_clk_freq,
                )
                if self.with_ethernet:
                    sync_pll_params.add_secondary_output(domain="_eth_ref", freq=25e6)
                m.submodules.sync_pll = sync_pll = PLL_Xilinx7Series(sync_pll_params)
            elif isinstance(platform, (ECPIX545Platform, ECPIX585Platform)):
                sync_pll_params = PLL_LatticeECP5.Parameters(
                    i_domain     = "_ref",
                    i_freq       = platform.default_clk_frequency,
                    i_reset_less = platform.default_rst is None,
                    o_domain     = "sync",
                    o_freq       = self.sync_clk_freq,
                )
                m.submodules.sync_pll = sync_pll = PLL_LatticeECP5(sync_pll_params)
            else:
                assert False

            if platform.default_rst is not None:
                sync_pll_arst = ~sync_pll.locked | ResetSignal("_ref")
            else:
                sync_pll_arst = ~sync_pll.locked

            m.submodules += ResetSynchronizer(sync_pll_arst, domain="sync")
            if isinstance(platform, ArtyA7_35Platform) and self.with_ethernet:
                m.submodules += ResetSynchronizer(sync_pll_arst, domain="_eth_ref")

        return m

class MinervaSoC(CPUSoC, Elaboratable):
    def __init__(self,
            sync_clk_freq,
            cpu_core,
            bootrom_addr,
            bootrom_size,
            scratchpad_addr,
            scratchpad_size,
            uart_core,
            uart_addr,
            uart_irqno,
            timer_addr,
            timer_width,
            timer_irqno):
        if not isinstance(sync_clk_freq, (int, float)) or sync_clk_freq <= 0:
            raise ValueError("Sync domain clock frequency must be a positive integer or float, "
                             "not {!r}"
                             .format(sync_clk_freq))
        self.sync_clk_freq = int(sync_clk_freq)

        if not isinstance(cpu_core, MinervaCPU):
            raise TypeError("CPU core must be an instance of MinervaCPU, not {!r}"
                            .format(cpu_core))
        self.cpu = cpu_core

        self._arbiter = wishbone.Arbiter(addr_width=30, data_width=32, granularity=8,
                                         features={"cti", "bte", "err"})
        self._decoder = wishbone.Decoder(addr_width=30, data_width=32, granularity=8,
                                         features={"cti", "bte", "err"})

        self._arbiter.add(self.cpu.ibus)
        self._arbiter.add(self.cpu.dbus)

        self.intc = GenericInterruptController(width=len(self.cpu.ip))

        self.bootrom = SRAMPeripheral(size=bootrom_size, writable=False)
        self._decoder.add(self.bootrom.bus, addr=bootrom_addr)

        self.scratchpad = SRAMPeripheral(size=scratchpad_size)
        self._decoder.add(self.scratchpad.bus, addr=scratchpad_addr)

        self.uart = AsyncSerialPeripheral(core=uart_core)
        self._decoder.add(self.uart.bus, addr=uart_addr)
        self.intc.add_irq(self.uart.irq, index=uart_irqno)

        self.timer = TimerPeripheral(width=timer_width)
        self._decoder.add(self.timer.bus, addr=timer_addr)
        self.intc.add_irq(self.timer.irq, index=timer_irqno)

        self._sdram  = None
        self._sram   = None
        self._ethmac = None

    @property
    def memory_map(self):
        return self._decoder.bus.memory_map

    @property
    def constants(self):
        return super().constants.union(
            SDRAM  = self.sdram .constant_map if self.sdram  is not None else None,
            ETHMAC = self.ethmac.constant_map if self.ethmac is not None else None,
            SOC    = ConstantMap(
                WITH_SDRAM        = self.sdram  is not None,
                WITH_ETHMAC       = self.ethmac is not None,
                MEMTEST_ADDR_SIZE = 8192,
                MEMTEST_DATA_SIZE = 8192,
            ),
        )

    @property
    def mainram(self):
        assert not (self._sdram and self.sram)
        return self._sdram or self._sram

    @property
    def sdram(self):
        return self._sdram

    @property
    def sram(self):
        return self._sram

    def add_sdram(self, core, *, addr, cache_size):
        if self.mainram is not None:
            raise AttributeError("Main RAM has already been set to {!r}".format(self.mainram))
        if core.config.user_clk_freq != self.sync_clk_freq:
            raise ValueError("LiteDRAM user domain clock frequency ({} MHz) must match sync "
                             "domain clock frequency ({} MHz)"
                             .format(core.config.user_clk_freq / 1e6, self.sync_clk_freq / 1e6))
        self._sdram = SDRAMPeripheral(core=core, cache_size=cache_size)
        self._decoder.add(self._sdram.bus, addr=addr)

    def add_internal_sram(self, *, addr, size):
        if self.mainram is not None:
            raise AttributeError("Main RAM has already been set to {!r}".format(self.mainram))
        self._sram = SRAMPeripheral(size=size)
        self._decoder.add(self._sram.bus, addr=addr)

    @property
    def ethmac(self):
        return self._ethmac

    def add_ethmac(self, core, *, addr, irqno, local_ip, remote_ip):
        if self._ethmac is not None:
            raise AttributeError("Ethernet MAC has already been set to {!r}"
                                 .format(self._ethmac))
        self._ethmac = EthernetMACPeripheral(core=core, local_ip=local_ip, remote_ip=remote_ip)
        self._decoder.add(self._ethmac.bus, addr=addr)
        self.intc.add_irq(self._ethmac.irq, index=irqno)

    def elaborate(self, platform):
        m = Module()

        m.submodules.crg = _ClockResetGenerator(
            sync_clk_freq = self.sync_clk_freq,
            with_sdram    = self.sdram is not None,
            with_ethernet = self.ethmac is not None,
        )

        m.submodules.cpu        = self.cpu
        m.submodules.arbiter    = self._arbiter
        m.submodules.decoder    = self._decoder
        m.submodules.uart       = self.uart
        m.submodules.timer      = self.timer
        m.submodules.intc       = self.intc
        m.submodules.bootrom    = self.bootrom
        m.submodules.scratchpad = self.scratchpad

        if self.sdram is not None:
            m.submodules.sdram = self.sdram
        if self.sram is not None:
            m.submodules.sram = self.sram
        if self.ethmac is not None:
            m.submodules.ethmac = self.ethmac

        m.d.comb += [
            self._arbiter.bus.connect(self._decoder.bus),
            self.cpu.ip.eq(self.intc.ip),
        ]

        return m

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("--build-dir", type=str,
            default="build/minerva_soc",
            help="local build directory (default: 'build/sdram_soc')")
    parser.add_argument("--platform", type=str,
            choices=("sim", "arty_a7", "ecpix5_45", "ecpix5_85"),
            default="sim",
            help="target platform")
    parser.add_argument("--sync-clk-freq", type=int,
            default=75,
            help="SoC clock frequency, in MHz. (default: 75)")
    parser.add_argument("--with-sdram", action="store_true",
            help="enable SDRAM")
    parser.add_argument("--internal-sram-size", type=int,
            default=8192,
            help="Internal RAM size, in bytes. Ignored if --with-sdram is provided. "
                 "(default: 8192)")
    parser.add_argument("--baudrate", type=int,
            default=9600,
            help="UART baudrate (default: 9600)")
    parser.add_argument("--with-ethernet", action="store_true",
            help="enable Ethernet")
    parser.add_argument("--local-ip", type=str,
            default="192.168.1.50",
            help="Local IPv4 address (default: 192.168.1.50)")
    parser.add_argument("--remote-ip", type=str,
            default="192.168.1.100",
            help="Remote IPv4 address (default: 192.168.1.100)")
    args = parser.parse_args()

    # Platform selection

    if args.platform == "sim":
        platform = CXXRTLPlatform()
    elif args.platform == "arty_a7":
        platform = ArtyA7_35Platform()
    elif args.platform == "ecpix5_45":
        platform = ECPIX545Platform()
    elif args.platform == "ecpix5_85":
        platform = ECPIX585Platform()
    else:
        assert False

    # LiteDRAM

    if args.with_sdram:
        if isinstance(platform, CXXRTLPlatform):
            litedram_config = litedram.ECP5Config(
                memtype        = "DDR3",
                module_name    = "MT41K256M16",
                module_bytes   = 2,
                module_ranks   = 1,
                input_clk_freq = int(platform.default_clk_frequency),
                user_clk_freq  = int(platform.default_clk_frequency),
                init_clk_freq  = int(1e6),
            )
        elif isinstance(platform, ArtyA7_35Platform):
            litedram_config = litedram.Artix7Config(
                memtype          = "DDR3",
                speedgrade       = "-1",
                cmd_latency      = 0,
                module_name      = "MT41K128M16",
                module_bytes     = 2,
                module_ranks     = 1,
                rtt_nom          = 60,
                rtt_wr           = 60,
                ron              = 34,
                input_clk_freq   = int(platform.default_clk_frequency),
                user_clk_freq    = int(args.sync_clk_freq * 1e6),
                iodelay_clk_freq = int(200e6),
            )
        elif isinstance(platform, (ECPIX545Platform, ECPIX585Platform)):
            litedram_config = litedram.ECP5Config(
                memtype        = "DDR3",
                module_name    = "MT41K256M16",
                module_bytes   = 2,
                module_ranks   = 1,
                input_clk_freq = int(platform.default_clk_frequency),
                user_clk_freq  = int(args.sync_clk_freq * 1e6),
                init_clk_freq  = int(25e6),
            )
        else:
            assert False

        if isinstance(platform, CXXRTLPlatform):
            litedram_pins = None
        else:
            litedram_pins = request_bare(platform, "ddr3", 0)

        litedram_core = litedram.Core(litedram_config, pins=litedram_pins)
        litedram_core.build(litedram.Builder(), platform, args.build_dir,
                            sim=isinstance(platform, CXXRTLPlatform))
        mainram_size  = litedram_core.size
    else:
        litedram_core = None
        mainram_size  = args.internal_sram_size

    # LiteEth

    if args.with_ethernet:
        if isinstance(platform, CXXRTLPlatform):
            raise NotImplementedError("Ethernet is currently unsupported in simulation.")
        elif isinstance(platform, ArtyA7_35Platform):
            liteeth_config = liteeth.Artix7Config(
                phy_iface = "mii",
                clk_freq  = int(25e6),
            )
        elif isinstance(platform, (ECPIX545Platform, ECPIX585Platform)):
            liteeth_config = liteeth.ECP5Config(
                phy_iface = "rgmii",
                clk_freq  = int(125e6),
            )
        else:
            assert False

        liteeth_pins = request_bare(platform, f"eth_{liteeth_config.phy_iface}", 0)
        liteeth_core = liteeth.Core(liteeth_config, pins=liteeth_pins)
        liteeth_core.build(liteeth.Builder(), platform, args.build_dir)
    else:
        liteeth_core = None

    # UART

    if isinstance(platform, CXXRTLPlatform):
        uart_core = AsyncSerial_Blackbox(
            data_bits = 8,
            divisor   = 1,
        )
    else:
        uart_core = AsyncSerial(
            data_bits = 8,
            divisor   = int(args.sync_clk_freq * 1e6 // args.baudrate),
            pins      = platform.request("uart", 0),
        )

    # SoC and BIOS

    if isinstance(platform, CXXRTLPlatform):
        sync_clk_freq = platform.default_clk_frequency
    else:
        sync_clk_freq = int(args.sync_clk_freq * 1e6)

    soc = MinervaSoC(
        sync_clk_freq = sync_clk_freq,

        cpu_core = MinervaCPU(
            reset_address = 0x00000000,
            with_icache   = True,
            icache_nlines = 16,
            icache_nwords = 4,
            icache_nways  = 1,
            icache_base   = 0x40000000,
            icache_limit  = 0x40000000 + mainram_size,
            with_dcache   = True,
            dcache_nlines = 16,
            dcache_nwords = 4,
            dcache_nways  = 1,
            dcache_base   = 0x40000000,
            dcache_limit  = 0x40000000 + mainram_size,
            with_muldiv   = True,
        ),

        bootrom_addr    = 0x00000000,
        bootrom_size    = 0x8000,
        scratchpad_addr = 0x00008000,
        scratchpad_size = 0x1000,

        uart_addr       = 0x80000000,
        uart_core       = uart_core,
        uart_irqno      = 1,
        timer_addr      = 0x80001000,
        timer_width     = 32,
        timer_irqno     = 0,
    )

    if args.with_sdram:
        soc.add_sdram(litedram_core, addr=0x40000000, cache_size=4096)
    else:
        soc.add_internal_sram(addr=0x40000000, size=args.internal_sram_size)

    if args.with_ethernet:
        soc.add_ethmac(liteeth_core, addr=0x90000000, irqno=2,
                       local_ip=args.local_ip, remote_ip=args.remote_ip)

    soc.build(build_dir=args.build_dir, do_init=True)

    if isinstance(platform, CXXRTLPlatform):
        platform.build(soc, build_dir=args.build_dir, blackboxes={
            "lambdasoc.sim.blackboxes.serial": "serial_pty",
        })
    else:
        platform.build(soc, build_dir=args.build_dir, do_program=True)


import torch
import torch.nn as nn
import torch.nn.functional as F
from models.layers.init_weights import init_weights

#===============================================================================
# SCM
#===============================================================================
class SCM(nn.Module):
    def __init__(self, in_channels, inter_channels):
        super(SCM, self).__init__()
        self.inter_channels = inter_channels
        if self.inter_channels is None:
            self.inter_channels = in_channels // 2
            if self.inter_channels == 0:
                self.inter_channels = 1

        self.conv_v_1 = nn.Conv2d(in_channels, self.inter_channels, kernel_size=1)
        self.conv_k_1 = nn.Conv2d(in_channels, self.inter_channels, kernel_size=1)
        self.conv_q_1 = nn.Conv2d(in_channels, self.inter_channels, kernel_size=1)
        self.conv_v_2 = nn.Conv2d(in_channels, self.inter_channels, kernel_size=1)
        self.conv_k_2 = nn.Conv2d(in_channels, self.inter_channels, kernel_size=1)
        self.conv_q_2 = nn.Conv2d(in_channels, self.inter_channels, kernel_size=1)

    def forward(self, x_1, x_2):
        V_1 = self.conv_v_1(x_1)
        K_1 = self.conv_k_1(x_1)
        Q_1 = self.conv_q_1(x_1)
        shape = V_1.shape
        # print(shape)
        V_1 = V_1.view(V_1.shape[0], V_1.shape[1], -1)
        K_1 = K_1.view(K_1.shape[0], K_1.shape[1], -1)
        Q_1 = Q_1.view(Q_1.shape[0], Q_1.shape[1], -1)

        V_2 = self.conv_v_2(x_2)
        K_2 = self.conv_k_2(x_2)
        Q_2 = self.conv_q_2(x_2)
        V_2 = V_2.view(V_2.shape[0], V_2.shape[1], -1)
        K_2 = K_2.view(K_2.shape[0], K_2.shape[1], -1)
        Q_2 = Q_2.view(Q_2.shape[0], Q_2.shape[1], -1)

        R12 = torch.sigmoid(torch.matmul(torch.transpose(Q_1, -1, -2), K_2))
        R21 = torch.sigmoid(torch.matmul(torch.transpose(Q_2, -1, -2), K_1))
        # print(R12.shape)

        Fu_1 = torch.matmul(R12, torch.transpose(V_2, -1, -2))
        Fu_2 = torch.matmul(R21, torch.transpose(V_1, -1, -2))
        Fu_1 = torch.transpose(Fu_1, -1, -2).view(shape)
        Fu_2 = torch.transpose(Fu_2, -1, -2).view(shape)
        # print(Fu_1.shape)

        y_1 = torch.cat([x_1, Fu_1], dim=1)
        y_2 = torch.cat([x_2, Fu_2], dim=1)
        # print(y_1.shape)
        return y_1, y_2

#===============================================================================
# PSP module
#===============================================================================
def _PSP1x1Conv(in_channels, out_channels, norm_layer, norm_kwargs):
    return nn.Sequential(
        nn.Conv2d(in_channels, out_channels, 1, bias=False),
        norm_layer(out_channels, **({} if norm_kwargs is None else norm_kwargs)),
        nn.ReLU(True)
    )

class PyramidPooling(nn.Module):
    def __init__(self, in_channels, **kwargs):
        super(PyramidPooling, self).__init__()
        out_channels = int(in_channels / 4)
        self.avgpool1 = nn.AdaptiveAvgPool2d(1)
        self.avgpool2 = nn.AdaptiveAvgPool2d(2)
        self.avgpool3 = nn.AdaptiveAvgPool2d(3)
        self.avgpool4 = nn.AdaptiveAvgPool2d(6)
        self.conv1 = _PSP1x1Conv(in_channels, out_channels, **kwargs)
        self.conv2 = _PSP1x1Conv(in_channels, out_channels, **kwargs)
        self.conv3 = _PSP1x1Conv(in_channels, out_channels, **kwargs)
        self.conv4 = _PSP1x1Conv(in_channels, out_channels, **kwargs)

    def forward(self, x):
        size = x.size()[2:]
        feat1 = F.interpolate(self.conv1(self.avgpool1(x)), size, mode='bilinear', align_corners=True)
        feat2 = F.interpolate(self.conv2(self.avgpool2(x)), size, mode='bilinear', align_corners=True)
        feat3 = F.interpolate(self.conv3(self.avgpool3(x)), size, mode='bilinear', align_corners=True)
        feat4 = F.interpolate(self.conv4(self.avgpool4(x)), size, mode='bilinear', align_corners=True)
        return torch.cat([x, feat1, feat2, feat3, feat4], dim=1)

#===============================================================================
# EADAM
#===============================================================================
class EADAM_V1(nn.Module):
    def __init__(self, in_channels, inter_channels=None):
        super().__init__()
        self.inter_channels = inter_channels
        if self.inter_channels is None:
            self.inter_channels = in_channels // 2
            if self.inter_channels == 0:
                self.inter_channels = 1

        self.conv_v = nn.Conv2d(in_channels, self.inter_channels, kernel_size=1)
        self.conv_k = nn.Conv2d(in_channels, self.inter_channels, kernel_size=1)
        self.conv_q = nn.Conv2d(in_channels, self.inter_channels, kernel_size=1)
        self.conv_out = nn.Conv2d(self.inter_channels, in_channels, kernel_size=1)

    def forward(self, x_en, x_de):
        V = self.conv_v(x_en)
        K = self.conv_k(x_en)
        Q = self.conv_q(x_de)
        shape = V.shape

        V = V.view(V.shape[0], V.shape[1], -1)
        K = K.view(V.shape[0], K.shape[1], -1)
        Q = Q.view(Q.shape[0], Q.shape[1], -1)

        H = torch.matmul(V, torch.transpose(K, -1, -2))
        H = torch.matmul(torch.sigmoid(H), Q) / (V.shape[1] * V.shape[2])**0.5

        H = H.view(shape)
        attmap = self.conv_out(H)

        return attmap + x_en + x_de

#===============================================================================
# multiscale input Module
#===============================================================================
class MultiInput(nn.Module):
    def __init__(self, in_channels, factor):
        super().__init__()
        self.conv_in = nn.Conv2d(3, in_channels, kernel_size=3, padding=1)
        self.bn = nn.BatchNorm2d(in_channels)
        self.conv_out = nn.Conv2d(in_channels * 2, in_channels, 1)
        self.factor = factor

    def forward(self, img, features):
        x = F.interpolate(img, scale_factor=self.factor, mode='bilinear', align_corners=True)
        x = self.conv_in(x)
        x = self.bn(x)
        out = torch.cat([x, features], dim=1)
        out = self.conv_out(out)

        return out

#===============================================================================
# TopHat Module
#===============================================================================
def dilation(x, size):
    maxpool = nn.MaxPool2d((size, size), stride=(1, 1), padding=size // 2)

    return maxpool(x)

def erosion(x, size):
    maxpool = nn.MaxPool2d((size, size), stride=(1, 1), padding=size // 2)

    return -maxpool(-x)

def black_tophat(x, size):
    x_dilate = dilation(x, size)
    x_close = erosion(x_dilate, size)

    return x_close - x

class TopHatBlockV2(nn.Module):
    def __init__(self, in_channels, poolsize=[3, 5, 7]):
        super().__init__()
        self.conv_in = nn.Conv2d(in_channels, in_channels, 1)
        self.conv_out = nn.Conv2d(in_channels, in_channels, 1)

        self.poolsize = poolsize
        self.conv_1x1 = nn.Conv2d(in_channels * len(poolsize), in_channels, 1)

    def forward(self, x):
        identity = x

        x = self.conv_in(x)

        out = []
        for idx, size in enumerate(self.poolsize):
            out.append(black_tophat(x, size))

        out = torch.cat(out, dim=1)
        out = self.conv_1x1(out)

        return out + identity

#===============================================================================
# PCA Blocks
#===============================================================================
class SAPCABlockV5(nn.Module):
    """
    Spatial attention block
    """

    def __init__(self, in_channels, scale=3):
        super().__init__()
        self.scale = scale
        self.conv1 = nn.Conv2d(in_channels, in_channels, 1)
        self.conv2 = nn.Sequential(
            nn.Conv2d(in_channels, in_channels, 3, padding=1, bias=False),
            nn.BatchNorm2d(in_channels),
        )

    def forward(self, x):
        gx = self.conv1(x)
        gx_ = gx.view(gx.shape[0], gx.shape[1], -1)
        gx_ = gx_ - torch.mean(gx_, dim=-1, keepdim=True)

        cmat = torch.matmul(gx_, gx_.transpose(-1, -2)) / gx.shape[0]
        w = []
        for i in range(cmat.shape[0]):
            eigval, eigvec = torch.symeig(cmat[i], eigenvectors=True)
            w.append(eigvec[:, -16:].transpose(-1, -2))
        w = torch.stack(w, dim=0)

        z = torch.matmul(w, gx_)  # 这一步可以考虑加softmax
        z = F.softmax(z * self.scale, dim=1)
        y_ = torch.matmul(w.transpose(-1, -2), z)
        y_ = y_.view(gx.shape[0], gx.shape[1], gx.shape[2], gx.shape[3])

        attmap = self.conv2(y_)

        x_en = x + attmap

        return x_en

class SAPCABlockV4(nn.Module):
    """
    Spatial attention block
    """

    def __init__(self, in_channels):
        super().__init__()
        self.conv1 = nn.Conv2d(in_channels, in_channels, 1)
        self.conv2 = nn.Sequential(nn.Conv2d(in_channels, in_channels, 1, bias=False),
                                   # norm_layer(in_channels),
                                   )

    def forward(self, x):
        gx = self.conv1(x)
        gx_ = gx.view(gx.shape[0], gx.shape[1], -1)
        gx_ = gx_ - torch.mean(gx_, dim=-1, keepdim=True)

        cmat = torch.matmul(gx_, gx_.transpose(-1, -2)) / gx.shape[0]
        w = []
        for i in range(cmat.shape[0]):
            eigval, eigvec = torch.symeig(cmat[i], eigenvectors=True)
            w.append(eigvec[:, -x.shape[1] // 4:].transpose(-1, -2))
        w = torch.stack(w, dim=0)

        z = torch.matmul(w, gx_)  # 这一步可以考虑加softmax
        y_ = torch.matmul(w.transpose(-1, -2), z)
        y_ = y_.view(gx.shape[0], gx.shape[1], gx.shape[2], gx.shape[3])

        attmap = self.conv2(y_)

        x_en = x + attmap

        return x_en

#================================================================
#================================================================
#================================================================
class SAPCABlockV3(nn.Module):
    """
    # Spatial attention block
    """

    def __init__(self, in_channels):
        super().__init__()
        self.conv1 = nn.Conv2d(in_channels, in_channels, 1)
        self.conv2 = nn.Conv2d(in_channels // 4, in_channels, 1)
        self.prelu = nn.PReLU()

    def forward(self, x):
        gx = self.conv1(x)
        gx_ = gx.view(gx.shape[0], gx.shape[1], -1)
        gx_ = gx_ - torch.mean(gx_, dim=-1, keepdim=True)

        cmat = torch.matmul(gx_, gx_.transpose(-1, -2)) / gx.shape[0]
        w = []
        for i in range(cmat.shape[0]):
            eigval, eigvec = torch.symeig(cmat[i], eigenvectors=True)
            w.append(eigvec[:, -x.shape[1] // 4:].transpose(-1, -2))
        w = torch.stack(w, dim=0)

        y = torch.matmul(w, gx_)
        y = y.view(y.shape[0], y.shape[1], gx.shape[2], gx.shape[3])

        attmap = self.conv2(y)
        x_en = x + attmap

        return x_en

class SAPCABlockV2(nn.Module):
    """
    #Spatial attention block
    """

    def __init__(self, in_channels):
        super().__init__()
        self.conv1 = nn.Conv2d(in_channels, in_channels, 1)
        self.conv2 = nn.Conv2d(in_channels // 4, in_channels, 1)
        self.prelu = nn.PReLU()

    def forward(self, x):
        gx = self.prelu(self.conv1(x))
        gx_ = gx.view(gx.shape[0], gx.shape[1], -1)

        cmat = torch.matmul(gx_, gx_.transpose(-1, -2)) / gx.shape[0]
        w = []
        for i in range(cmat.shape[0]):
            eigval, eigvec = torch.symeig(cmat[i], eigenvectors=True)
            w.append(eigvec[:, -x.shape[1] // 4:].transpose(-1, -2))
        w = torch.stack(w, dim=0)

        y = torch.matmul(w, gx_)
        y = torch.sigmoid(y)
        y = y.view(y.shape[0], y.shape[1], gx.shape[2], gx.shape[3])

        attmap = self.conv2(y)
        x_en = x * torch.tanh(attmap)

        return x_en

class SAPCABlock(nn.Module):
    """
    #Spatial attention block
    """

    def __init__(self, in_channels):
        super().__init__()
        self.conv1 = nn.Conv2d(in_channels, in_channels, 1)
        self.conv2 = nn.Conv2d(in_channels // 4, in_channels, 1)
        self.prelu = nn.PReLU()

    def forward(self, x):
        gx = self.prelu(self.conv1(x))
        gx_ = gx.view(gx.shape[0], gx.shape[1], -1)

        cmat = torch.matmul(gx_, gx_.transpose(-1, -2)) / gx.shape[0]
        w = []
        for i in range(cmat.shape[0]):
            eigval, eigvec = torch.symeig(cmat[i], eigenvectors=True)
            w.append(eigvec[:, -x.shape[1] // 4:].transpose(-1, -2))
        w = torch.stack(w, dim=0)

        y = torch.matmul(w, gx_)
        y = y.view(y.shape[0], y.shape[1], gx.shape[2], gx.shape[3])

        attmap = self.conv2(y)
        x_en = x + attmap

        return x_en

class DecoderBlock(nn.Module):
    def __init__(self, in_channels, n_filters):
        super(DecoderBlock, self).__init__()

        self.conv1 = nn.Conv2d(in_channels, in_channels // 4, 1)
        self.norm1 = nn.BatchNorm2d(in_channels // 4)
        self.relu1 = nn.ReLU(inplace=True)

        self.deconv2 = nn.ConvTranspose2d(in_channels // 4, in_channels // 4, 3, stride=2, padding=1, output_padding=1)
        self.norm2 = nn.BatchNorm2d(in_channels // 4)
        self.relu2 = nn.ReLU(inplace=True)

        self.conv3 = nn.Conv2d(in_channels // 4, n_filters, 1)
        self.norm3 = nn.BatchNorm2d(n_filters)
        self.relu3 = nn.ReLU(inplace=True)

    def forward(self, x):
        x = self.conv1(x)
        x = self.norm1(x)
        x = self.relu1(x)
        x = self.deconv2(x)
        x = self.norm2(x)
        x = self.relu2(x)
        x = self.conv3(x)
        x = self.norm3(x)
        x = self.relu3(x)

        return x


import numpy as np
import cv2
import argparse
from collections import deque

# badan bayad kamel konam
def create_hue_mask(image, lower_color, upper_color):
    lower = np.array(lower_color, np.uint8)
    upper = np.array(upper_color, np.uint8)

    # Create a mask from the colors
    mask = cv2.inRange(image, lower, upper)
    output_image = cv2.bitwise_and(image, image, mask=mask)
    return output_image
# construct the argument parse and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-v", "--video",
	help="path to the (optional) video file")
ap.add_argument("-b", "--buffer", type=int, default=64,
	help="max buffer size")
args = vars(ap.parse_args())
pts = deque(maxlen=args["buffer"])
cap = cv2.VideoCapture(0)

while (True):
    # Capture frame-by-frame
    ret, frame = cap.read()
    output = frame.copy()
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    gray = cv2.GaussianBlur(gray, (3, 3), 0)
    edged = cv2.Canny(gray, 10, 250)

    # construct and apply a closing kernel to 'close' gaps between 'white'
    # pixels
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (7, 7))
    closed = cv2.morphologyEx(edged, cv2.MORPH_CLOSE, kernel)

    im2, contours, hierarchy = cv2.findContours(closed.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

    center = None

    # only proceed if at least one contour was found
    if len(contours) > 0:
        # find the largest contour in the mask, then use
        # it to compute the minimum enclosing circle and
        # centroid
        c = max(contours, key=cv2.contourArea)
        ((x, y), radius) = cv2.minEnclosingCircle(c)
        M = cv2.moments(c)
        center = (int(M["m10"] / M["m00"]), int(M["m01"] / M["m00"]))

        # only proceed if the radius meets a minimum size
        if radius > 10:
            # draw the circle and centroid on the frame,
            # then update the list of tracked points
            cv2.circle(output, (int(x), int(y)), int(radius),
                       (0, 255, 255), 2)
            cv2.circle(output, center, 5, (0, 0, 255), -1)

    # update the points queue
    pts.appendleft(center)

    # loop over the set of tracked points
    for i in xrange(1, len(pts)):
        # if either of the tracked points are None, ignore
        # them
        if pts[i - 1] is None or pts[i] is None:
            continue

        # otherwise, compute the thickness of the line and
        # draw the connecting lines

        cv2.line(output, pts[i - 1], pts[i], (0, 0, 255), 1)

    #im2, cnts, hierarchy = cv2.findContours(closed.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    total = 0
    # print (len(contours))
    # print (contours[0][2][0][0])
    # print(contours[4][2])
    ii = 0
    jj = 0
    x = 0
    y = 0
    x_ave = 0
    y_ave = 0

    for c in contours:
        # approximate the contour
        peri = cv2.arcLength(c, True)
        approx = cv2.approxPolyDP(c, 0.02 * peri, True)

        # if the approximated contour has four points, then assume that the
        # contour is a book -- a book is a rectangle and thus has four vertices
        if len(approx) == 4:
            cv2.drawContours(output, [approx], -1, (0, 255, 0), 4)
            total += 1

    while (ii < (len(contours))):

        # print (contours[ii][0])

        # print(len(contours[ii]))
        # print(ii)
        while (jj < len(contours[ii])):
            # print(contours[ii-1][jj-1])
            # print(contours[ii][jj][0])
            x = x + contours[ii][jj][0][0]
            y = y + contours[ii][jj][0][1]

            # print("ok")
            # print(ii, jj)
            jj = jj + 1

        x_ave = x / len(contours[ii])
        y_ave = y / len(contours[ii])
        # print(x_ave)
        jj = 0
        ii = ii + 1

 #   cv2.drawContours(output, contours, -1, (0, 255, 0), 3)

    cv2.imshow('frame', output)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()


from window import *
import numpy as np

def cartesian_to_polar(stft_cartesian):
    """
    Converts a short time fourier transform in cartesian coordinates to polar
    :param stft: 2-d numpy array short time fourier transform in cartesian coordinates
    :return: 2-d numpy array (magnitude), 2-d numpy array (radians between (-pi,pi])
    """

    return np.absolute(stft_cartesian), np.angle(stft_cartesian)

def polar_to_cartesian(magnitudes, angles):
    """
    Inverts cartesian_to_polar. Takes magnitudes and phases of stft and converts to cartesian coordinates
    :param magnitudes: 2-d numpy array of magnitudes
    :param angles: 2-d numpy array of phases of equal dimension to magnitudes
    :return: 2-d numpy of cartesian coordinates
    """

    return magnitudes * np.exp(1j * angles)

class ShortTimeFourierTransform:
    def __init__(self, window_length):
        self._w = Window(window_length)

    def apply(self, signal, analysis_hop_length):
        """
        Apply short time fourier transform
        :param signal: 1-d numpy array time series
        :return: 2-d numpy array short time fourier transform
        """
        frames = center(
                    self._w.hann(
                        self._w.subsets(signal, analysis_hop_length)))
        output = np.fft.rfft(frames)
        return output

    def apply_inverse(self, stft_cartesian, synthesis_hop_length):
        """
        Invert the short time fourier transform
        :param stft: 2-d numpy array short time fourier transform in cartesian coordinates
        :return: 1-d numpy array time series
        """
        number_of_frames, _fft_size = stft_cartesian.shape

        output_length = synthesis_hop_length * (number_of_frames - 1) + self.window_length()

        out = np.zeros(output_length, dtype=np.float32)
        norm = np.zeros(output_length, dtype=np.float32)
        w_norm = self._w.hann(np.ones(self.window_length())) ** 2

        for i_frame in np.arange(number_of_frames):
            i_out = i_frame * synthesis_hop_length
            out[i_out:i_out+self.window_length()] += self._w.hann(
                                                        invert_center(
                                                            np.fft.irfft(stft_cartesian[i_frame],
                                                                         self.window_length())))
            norm[i_out:i_out+self.window_length()] += w_norm

        norm[0] = 1
        return out / norm

    def window_length(self):
        return self._w.length()


#coding:UTF-8

import numpy as np

def get_func_from_parameters(func_type, parameters):
    if func_type == "None":
        func = lambda x: x
    elif func_type == "constant":
        value = parameters[0]
        func = lambda x: value
    elif func_type == "sigmoid":
        half = parameters[0]
        slope = float(parameters[1])
        m = parameters[2]
        func = lambda x: m/(1.+np.exp(-(x-half)/slope))
    elif func_type == "sigmoid_fix":
        half = parameters[0]
        slope = float(parameters[1])
        func = lambda x: 1/(1.+np.exp(-(x-half)/slope))
    elif func_type == "1minhill":
        k = parameters[0]
        n = parameters[1]
        if k <= 0 or n <=0:
            raise Exception()
        func = lambda x: k**n/(k**n+x**n)
    elif func_type == "hill":
        k = parameters[0]
        n = parameters[1]
        m = parameters[2]
        if n <= 0 or m <= 0:
            raise Exception()
        func = lambda x: m*x**n/(k**n+x**n)
    elif func_type == "ahill":
        k = parameters[0]
        m = parameters[1]
        func = lambda x: m/(1.+k/x)
    elif func_type == "rlinear":
        k = parameters[0]
        m = float(parameters[1])
        func = lambda x: m/(x+k)
    elif func_type == "rlinear_fix":
        k = float(parameters[0])
        func = lambda x: k/(x+k)
    elif func_type == "exp":
        k = float(parameters[0])
        m = parameters[1]
        c = parameters[2]
        func = lambda x: m*np.exp(x/k)+c
    elif func_type == "exp_fix":
        k = float(parameters[0])
        func = lambda x: np.exp(x/k)
    elif func_type == "pow":
        A = parameters[0]
        B = parameters[1]
        C = parameters[2]
        if B <= 0:
            raise Exception()
        func = lambda x: A*x**B+C
    elif func_type == "relu":
        th = parameters[0]
        slope = parameters[1]
        base = parameters[2]
        def func(x):
            if x < th:
                return base
            else:
                return base+slope*(x-th)
    elif func_type == "linear":
        func = lambda x: parameters[0]*x
    elif func_type == "linear_kb":
        func = lambda x: parameters[0]*x+parameters[1]
    elif func_type == "linear_b_fix":
        func = lambda x: parameters[0]*x+1
    else:
        raise Exception("UNKNOWN func types for %s"%func_type)
    return np.vectorize(func, otypes=[np.float])


# ********************** ASSIGNMENT: FOR LOOPS: BASIC I *******************************************************

# 1
# for x in range(150):
#     print(x)

# 2
# for x in range(5,1000,5):
#     print(x)

# 3
# for x in range(1,100):
#     if(x % 5 == 0):
#         print("Coding")
#     if(x % 10 == 0):
#         print("Coding Dojo")
#     else:
#         print(x)

# 4
# sum = 0
# for x in range(0,500000):
#     if(x % 2 != 0):
#         sum += x
# print(sum)

# 5
# for x in range(2018,0,-4):
#     print(x)

# 6
# lowNum = 30
# highNum = 404
# mult = 23
# for x in range(lowNum,highNum):
#     if(x % mult == 0):
#         print(x)

# **************************** Assignment: Functions Basic II *******************************************************

# 1
x = [ [5,2,3], [10,8,9] ]
x[1][0] = 15
# print(x)

students = [
    {'first_name':  'Michael', 'last_name' : 'Jordan'},
    {'first_name' : 'John', 'last_name' : 'Rosales'}
]
students[0]["last_name"] = "Bryant"
# print(students)

sports_directory = {
    'basketball' : ['Kobe', 'Jordan', 'James', 'Curry'],
    'soccer' : ['Messi', 'Ronaldo', 'Rooney']
}
sports_directory["soccer"][0] = "Andres"
# print(sports_directory)

z = [ {'x': 10, 'y': 20} ]
z[0]["y"]=30
# print(z)

# 2
students = [
    {'first_name':  'Michael', 'last_name' : 'Jordan'},
    {'first_name' : 'John', 'last_name' : 'Rosales'},
    {'first_name' : 'Mark', 'last_name' : 'Guillen'},
    {'first_name' : 'KB', 'last_name' : 'Tonel'}
]

# def iterateDictionary(students):
    # for x in range(0,len(students)):

    #     print(f"{students[x]['first_name']}  {students[x]['last_name']}")

#     for x in range(0,len(students)):
#         string = ""
#         for z in students[0]:
#             if z == "first_name":
#                 string += f"{z} - {students[x][z]}, "
#             else:
#                 string += f"{z} - {students[x][z]} "
#         print(string)
# iterateDictionary(students)

# 3 Get Values From a List of Dictionaries
# for y in range(0,len(students)):
#     for x in students[y]:
#         if(x == "first_name"):
#             print(students[y][x])

# for y in range(0,len(students)):
#     for x in students[y]:
#         if(x == "last_name"):
#             print(students[y][x])

# 4
dojo = {
   'locations': ['San Jose', 'Seattle', 'Dallas', 'Chicago', 'Tulsa', 'DC', 'Burbank'],
   'instructors': ['Michael', 'Amy', 'Eduardo', 'Josh', 'Graham', 'Patrick', 'Minh', 'Devon']
}

for x in dojo:
    print(f"{len(x)} {x.upper()}")
    for y in range(0,len(dojo[x])):
        print(dojo[x][y])
    print("\n")


import os

def clear():
    for file in os.listdir('.github/workflows'):
        os.remove(f'.github/workflows/{file}')

def list_tasks():
    root_blacklist = ['.py', '.md', '.gitignore']
    tasks = {}

    for root in os.listdir('.'):
        if root.startswith('.'):
            continue
        if any([root.endswith(ext) for ext in root_blacklist]):
            continue
        tasks[root] = []
        for task in os.listdir(root):
            if not task.endswith('.py'):
                continue
            name = task[:-3]
            tasks[root].append(name)

    for _, block in tasks.items():
        block.sort()
    return tasks

if __name__ == '__main__':
    clear()

    template = ''.join(open('.github/.yaml.tmp').readlines())
    tasks = list_tasks()

    for root, block in tasks.items():
        for name in block:
            config = template.format(
                _full_name=f'Task {name} [{root}]',
                _name=name,
                _path=f'{root}/{name}.py',
            )
            with open(f'.github/workflows/{name}.yaml', 'w') as wf:
                print(config.rstrip(), file=wf)


import os, glob
from pytest import raises
import bionetgen as bng
from bionetgen.main import BioNetGenTest

tfold = os.path.dirname(__file__)

def test_bionetgen_help():
    # tests basic command help
    with raises(SystemExit):
        argv = ["--help"]
        with BioNetGenTest(argv=argv) as app:
            app.run()
            assert app.exit_code == 0

def test_bionetgen_input():
    argv = [
        "run",
        "-i",
        os.path.join(tfold, "test.bngl"),
        "-o",
        os.path.join(tfold, "test"),
    ]
    to_match = ["test.xml", "test.cdat", "test.gdat", "test.net"]
    with BioNetGenTest(argv=argv) as app:
        app.run()
        assert app.exit_code == 0
        file_list = os.listdir(os.path.join(tfold, "test"))
        assert file_list.sort() == to_match.sort()

def test_bionetgen_plot():
    argv = [
        "plot",
        "-i",
        os.path.join(*[tfold, "test", "test.gdat"]),
        "-o",
        os.path.join(*[tfold, "test", "test.png"]),
    ]
    with BioNetGenTest(argv=argv) as app:
        app.run()
        assert app.exit_code == 0
        assert os.path.isfile(os.path.join(*[tfold, "test", "test.png"]))

def test_bionetgen_model():
    fpath = os.path.join(tfold, "test.bngl")
    fpath = os.path.abspath(fpath)
    m = bng.bngmodel(fpath)

def test_bionetgen_visualize():
    vis_types = [
        "contactmap",
        "ruleviz_pattern",
        "ruleviz_operation",
        "regulatory",
        "atom_rule",
        "all",
    ]
    for vis_name in vis_types:
        argv = [
            "visualize",
            "-i",
            os.path.join(tfold, "test.bngl"),
            "-o",
            os.path.join(tfold, "viz"),
            "-t",
            vis_name,
        ]
        with BioNetGenTest(argv=argv) as app:
            app.run()
            assert app.exit_code == 0
            # gmls = glob.glob("*.gml")
            graphmls = glob.glob(os.path.join(tfold, "viz") + os.sep + "*.graphml")
            if vis_name == "atom_rule":
                assert any(["regulatory" in i for i in graphmls])
            elif not vis_name == "all":
                assert any([vis_name in i for i in graphmls])
            else:
                assert len(graphmls) == 4

def test_bionetgen_all_model_loading():
    # tests library model loading using many models
    mpattern = os.path.join(tfold, "models") + os.sep + "*.bngl"
    models = glob.glob(mpattern)
    succ = []
    fail = []
    success = 0
    fails = 0
    for model in models:
        try:
            m = bng.bngmodel(model)
            success += 1
            mstr = str(m)
            succ.append(model)
        except:
            print("can't load model {}".format(model))
            fails += 1
            fail.append(model)
    print("succ: {}".format(success))
    print(sorted(succ))
    print("fail: {}".format(fails))
    print(sorted(fail))
    assert fails == 0

def test_action_loading():
    # tests a BNGL file containing all BNG actions
    all_action_model = os.path.join(*[tfold, "models", "actions", "all_actions.bngl"])
    m1 = bng.bngmodel(all_action_model)
    assert len(m1.actions) + len(m1.actions.before_model) == 31

    no_action_model = os.path.join(*[tfold, "models", "actions", "no_actions.bngl"])
    m2 = bng.bngmodel(no_action_model)
    assert len(m2.actions) == 0

def test_bionetgen_info():
    # tests info subcommand
    argv = ["info"]
    with BioNetGenTest(argv=argv) as app:
        app.run()
        assert app.exit_code == 0

def test_model_running_CLI():
    # tests running a list of models using the CLI
    mpattern = os.path.join(tfold, "models") + os.sep + "*.bngl"
    models = glob.glob(mpattern)
    succ = []
    fail = []
    success = 0
    fails = 0
    test_run_folder = os.path.join(tfold, "models", "cli_test_runs")
    if not os.path.isdir(test_run_folder):
        os.mkdir(test_run_folder)
    for model in models:
        model_name = os.path.basename(model).replace(".bngl", "")
        try:
            argv = [
                "run",
                "-i",
                model,
                "-o",
                os.path.join(*[tfold, "models", "cli_test_runs", model_name]),
            ]
            with BioNetGenTest(argv=argv) as app:
                app.run()
                assert app.exit_code == 0
            success += 1
            model = os.path.split(model)
            model = model[1]
            succ.append(model)
        except:
            print("can't run model {}".format(model))
            fails += 1
            model = os.path.split(model)
            model = model[1]
            fail.append(model)
    print("succ: {}".format(success))
    print(sorted(succ))
    print("fail: {}".format(fails))
    print(sorted(fail))
    assert fails == 0

def test_model_running_lib():
    # test running a list of models using the library
    mpattern = os.path.join(tfold, "models") + os.sep + "*.bngl"
    models = glob.glob(mpattern)
    succ = []
    fail = []
    success = 0
    fails = 0
    for model in models:
        if "test_tfun" in model:
            continue
        try:
            bng.run(model)
            success += 1
            model = os.path.split(model)
            model = model[1]
            succ.append(model)
        except:
            print("can't run model {}".format(model))
            fails += 1
            model = os.path.split(model)
            model = model[1]
            fail.append(model)
    print("succ: {}".format(success))
    print(sorted(succ))
    print("fail: {}".format(fails))
    print(sorted(fail))
    assert fails == 0

def test_atomize_flat():
    if not os.path.exists(os.path.join(tfold, "test")):
        os.mkdir(os.path.join(tfold, "test"))
    argv = [
        "atomize",
        "-i",
        os.path.join(tfold, "test_sbml.xml"),
        "-o",
        os.path.join(*[tfold, "test", "test_sbml_flat.bngl"]),
    ]
    to_match = ["test_sbml_flat.bngl"]
    with BioNetGenTest(argv=argv) as app:
        app.run()
        assert app.exit_code == 0
        file_list = os.listdir(os.path.join(tfold, "test"))
        assert file_list.sort() == to_match.sort()

def test_atomize_atomized():
    if not os.path.exists(os.path.join(tfold, "test")):
        os.mkdir(os.path.join(tfold, "test"))
    argv = [
        "atomize",
        "-i",
        os.path.join(tfold, "test_sbml.xml"),
        "-o",
        os.path.join(*[tfold, "test", "test_sbml_atom.bngl"]),
        "-a",
    ]
    to_match = ["test_sbml_atom.bngl"]
    with BioNetGenTest(argv=argv) as app:
        app.run()
        assert app.exit_code == 0
        file_list = os.listdir(os.path.join(tfold, "test"))
        assert file_list.sort() == to_match.sort()

def test_network_parse():
    netfile = os.path.join(tfold, "mockup.net")
    from bionetgen.network.network import Network

    try:
        net = Network(netfile)
        res = True
    except:
        res = False
    assert res is True

def test_pattern_reader():
    patfile = os.path.join(tfold, "patterns.txt")
    from bionetgen.modelapi.pattern_reader import BNGPatternReader

    try:
        with open(patfile, "r") as f:
            patterns = f.readlines()
            for pattern in patterns:
                pat_obj = BNGPatternReader(pattern).pattern
                reparsed_pat = BNGPatternReader(str(pat_obj)).pattern
                if pat_obj != reparsed_pat:
                    raise RuntimeError(
                        f"Pattern can't be reparsed correctly, og: {pat_obj}, reparsed: {reparsed_pat}"
                    )
        res = True
    except:
        res = False
    assert res is True

def test_pattern_canonicalization():
    # for now, if the platform is windows, just skip
    if os.name == "nt":
        assert True is True
    # if pynauty is uninstalled, skip the test
    try:
        import pynauty
    except ImportError:
        assert True is True
        return
    # otherwise we will test canonicalization
    from bionetgen.modelapi.pattern_reader import BNGPatternReader

    # the testing file
    testfile = os.path.join(tfold, "canon_label_testing.txt")
    with open(testfile, "r+") as f:
        tests = f.readlines()
    # loop over tests
    res = True
    for ipat, pat in enumerate(tests):
        pat_splt = pat.split("    ")
        pat1, pat2 = pat_splt[0], pat_splt[1]
        try:
            # read patterns
            pat1_obj = BNGPatternReader(pat1).pattern
            pat2_obj = BNGPatternReader(pat2).pattern
            # compare them
            if pat1_obj != pat2_obj:
                res = False
                break
        except:
            res = False
            break
    # assert that everything matched up
    assert res is True

def test_setup_simulator():
    fpath = os.path.join(tfold, "test.bngl")
    fpath = os.path.abspath(fpath)
    try:
        m = bng.bngmodel(fpath)
        librr_simulator = m.setup_simulator()
        res = librr_simulator.simulate(0, 1, 10)
    except:
        res = None
    assert res is not None

# def test_graphdiff_matrix():
#     valid = []
#     invalid = []
#     argv = [
#         "graphdiff",
#         "-i",
#         os.path.join(*[tfold, "models", "testviz1_cm.graphml"]),
#         "-i2",
#         os.path.join(*[tfold, "models", "testviz2_cm.graphml"]),
#         "-m",
#         "matrix",
#     ]
#     to_validate = ["testviz1_cm_recolored.graphml",
#                 "testviz1_cm_testviz2_cm_diff.graphml",
#                 "testviz2_cm_recolored.graphml",
#                 "testviz2_cm_testviz1_cm_diff.graphml",
#                 ]
#     schema_doc = etree.parse(f)
#     xmlschema = etree.XMLSchema(schema_doc)

#     with BioNetGenTest(argv=argv) as app:
#         app.run()
#         assert app.exit_code == 0
#     for test_graphml in to_validate:
#         doc = etree.parse(test_graphml)
#         result = xmlschema.validate(doc)
#         if result == True: valid.append(test_graphml)
#         else:
#             invalid.append(test_graphml)
#     print(sorted(valid))
#     print(sorted(invalid))
#     # assert len(valid) == 4

# def test_graphdiff_union():
#     argv = [
#         "graphdiff",
#         "-i",
#         os.path.join(tfold, "models", "testviz1_cm.graphml"),
#         "-i2",
#         os.path.join(tfold, "models", "testviz2_cm.graphml"),
#         "-m",
#         "union",
#     ]
#     to_validate = "testviz1_cm_testviz2_cm_union.graphml"
#     # xmlschema_doc = etree.parse("INSERT_xsd_path_HERE.xsd")
#     # xmlschema = etree.XMLSchema(xmlschema_doc)
#     with BioNetGenTest(argv=argv) as app:
#         app.run()
#         assert app.exit_code == 0
#     # xml_doc = etree.parse(to_validate)
#     # result = xmlschema.validate(xml_doc)
#     # assert result == True


from LoadPostgresqlEngine import postgresql_load as pl

# Variables:
csv_path = '/home/project/airflow/dags/trafficproject/staging/transformed_extracted_data.csv'
sql_db_name = 'road_traffic_data'
sql_table_name = 'toll_data'

# Execution:

pl(csv_path, sql_db_name, sql_table_name) # loads the specified CSV file into the specified PostgreSQL database & table name.


from selenium import webdriver

chrome_webdriver_path = "C:/Development/chromedriver"
driver = webdriver.Chrome(executable_path=chrome_webdriver_path)
# driver.get("https://www.flipkart.com/realme-buds-q-bluetooth-headset/p/itm2a9c125711e36?gclid=CjwKCAjwxuuCBhATEiwAIIIz0evRBh-aQFaG4rZauQoMyEDK0e7RruyJQFSH73s8b6sobJo3d6ZzJhoCJ4oQAvD_BwE&pid=ACCFVWN4PGNTEFGY&lid=LSTACCFVWN4PGNTEFGYNDRHV5&marketplace=FLIPKART&cmpid=content_headphone_840394530_g_8965229628_gmc_pla&tgi=sem,1,G,11214002,g,search,,472199938969,,,,c,,,,,,,&ef_id=CjwKCAjwxuuCBhATEiwAIIIz0evRBh-aQFaG4rZauQoMyEDK0e7RruyJQFSH73s8b6sobJo3d6ZzJhoCJ4oQAvD_BwE:G:s&s_kwcid=AL!739!3!472199938969!!!g!1039855654517!&gclsrc=aw.ds")
# price = driver.find_element_by_xpath('//*[@id="container"]/div/div[3]/div[1]/div[2]/div[2]/div/div[4]/div[1]/div/div[1]')
# print(price.text)
# # driver.close()
# # driver.quit()
driver.get(url = "https://www.python.org/")
Upcomin_events = driver.find_element_by_xpath('//*[@id="content"]/div/section/div[3]/div[2]/div/ul')
content = Upcomin_events.text
events = content.split("\n")
# print(events)
dates = [events[i] for i in range(0,len(events),2)]
# print(dates)
events = [events[i] for  i in range(1,len(events), 2)]
# print(events)
dic = {i : [f"time: {dates[i]}, event: {events[i]}"] for i in range(0,len(dates))}
print(dic)


# !/usr/bin/python3
import requests, json
from tkinter import *
import os
import sys
from datetime import datetime

def globals():
    with open('defaults/country.txt', "r") as f:
        globals.city = f.read()
globals()
CITY = globals.city
BASE_URL = "https://api.openweathermap.org/data/2.5/weather?"
URL = "https://api.openweathermap.org/data/2.5/weather?q=+" + CITY + "&units=metric&APPID=0316f9e49bb4c3fe9c8ea0327ea5a71e"
response = requests.get(URL)
#class Crea:
#        y = Tk()
#
 #       y.geometry("500x500")
  #      cvwid2 = 700
   #     cvhei2 = 700
    #    canvasi = Canvas(y, width=cvwid2, height=cvhei2, bg='black')

     #   canvasi.pack(expand=YES, fill=BOTH)

      #  imagei = 'images/home.png'
 #       gif12 = PhotoImage(file=imagei)
#
   #     canvasi.create_image(0, 0, image=gif12, anchor=NW)
  #      e = Entry(y, width=50)
    #    e.place(x=50, y=250)
     #   b = Button(y, text="Choose Country", command=cre)
      #  b.place(x=50, y=300)

def func() :
    def change():
        y = Toplevel()
        y.geometry("200x100")
        en = Entry(y, width=10)
        en.place(x=25, y=25)
        en.focus()

        def getr(e):
            with open('defaults/country.txt', "w") as f:
                f.truncate(0)
                f.write(en.get())

            def restart():
                os.execl(sys.executable, sys.executable, *sys.argv)

            globals.city = en.get()
            restart()

        en.bind("<Return>", getr)
    if response.status_code == 200:

        data = response.json()
        main = data['main']
        temperature = main['temp']
        humidity = main['humidity']
        pressure = main['pressure']
        report = data['weather']
        print(f"{CITY:-^30}")
        print(f"Temperature: {temperature}")
        print(f"Humidity: {humidity}")
        print(f"Pressure: {pressure}")
        print(f"Weather Report: {report[0]['description']}")

        rep = report[0]['main'].lower()
        now = datetime.now()

        time = int(now.strftime("%H"))

        if time >= 21 :
            color = "white"

            if "clear" in rep:
                image = 'images/cleardark.png'
            if "cloud" in rep:
                image = 'images/clouddark.png'
            if "rain" in rep:
                image = 'images/raindark.png'
            if "thunder" in rep:
                image = 'images/thunderdark.png'
            if "mist" in rep:
                image = 'images/mistdark.png'
            if "snow" in rep:
                image = 'images/snowdark.png'
        else :
            color = "white"

            if "clear" in rep:
                image = 'images/sunny.png'
            if "cloud" in rep:
                image = 'images/cloud.png'
            if "rain" in rep:
                image = 'images/rain.png'
            if "thunder" in rep:
                image = 'images/thunder.png'
            if "mist" in rep:
                image = 'images/mist.png'
            if "snow" in rep:
                image = 'images/snow.png'

        x = Tk()
        # Creating Menubar
        menubar = Menu(x)
        menubar.config(bg="#484848", fg="white", font=("Stencil Std", 10))

        # Adding Help Menu
        help_ = Menu(menubar, tearoff=0, bg="#484848", fg="white", font=("Stencil Std", 10))
        menubar.add_cascade(label='Countries', menu=help_)
        help_.add_command(label='Change Current Country', command=change)
        help_.add_command(label='Show Current Country', command=None)
        help_.add_separator()
        help_.add_command(label='Change Timezone', command=None)
        help_.add_command(label='Show Current Timezone', command=None)
        help_.add_separator()
        help_.add_command(label="Exit", command=x.destroy)

        # display Menu
        x.config(menu=menubar)
        x.resizable(False, False)
        gif = PhotoImage(file=image)
        cvwid = gif.width()
        cvhei = gif.height()
        canvas = Canvas(x, width=cvwid, height=cvhei, bg='lightblue')
        canvas.pack(fill=BOTH)

        img = canvas.create_image(0, 0, image=gif, anchor=NW)

        temp = canvas.create_text(cvwid / 2, 350, fill=color, font="Helvetica 30", text=str(int(temperature)) + "°C")
        reportr = canvas.create_text(cvwid / 2, 400, fill=color, font="Helvetica 20", text=report[0]["main"])
        cont = canvas.create_text(cvwid / 2, 200, fill=color, font="Helvetica 20", text=globals.city.title())
        x.title(f"{CITY:-^30}")
        x.mainloop()

func()


import cv2
import time

# record a video: trigger the webcam, keep it on for 3 secs and then stop
video = cv2.VideoCapture(0)

a = 1
while True:
    a = a+1
    check, frame = video.read()
    print(check)
    print(frame)

    # gray = cv2.cvtColor(frame, cv2.COLOR_BayerGR2GRAY)

    cv2.imshow("Capturing", frame)
    key = cv2.waitKey(1)

    if key==ord('q'):
        break

print(a)
video.release()
cv2.destroyAllWindows()

# ### code tried earlier
#
# video = cv2.VideoCapture(0)
#
# check, frame = video.read()
# # print(check)
# # print(frame)
#
# time.sleep(2)
# cv2.imshow("Capturing", frame)
#
# cv2.waitKey(2000)
# video.release()
# cv2.destroyAllWindows()


from stable_baselines3 import PPO
from train import Train
from cyclesgym.utils.utils import _evaluate_policy
from cyclesgym.utils.paths import PROJECT_PATH
from cyclesgym.utils.plot_utils import set_up_plt
import numpy as np
import matplotlib.pyplot as plt
import wandb
from matplotlib.cm import get_cmap

set_up_plt()

def plot_crop_planning_policy_prob(episode_probs):
    color = get_cmap('Accent').colors
    crop_prob = np.array(list(zip(*episode_probs))[0]).squeeze()
    planting_prob = np.array(list(zip(*episode_probs))[1]).squeeze()
    plt.stackplot(1 + np.arange(crop_prob.shape[0]), *crop_prob.T)
    plt.xticks(1 + np.arange(crop_prob.shape[0]))
    plt.xlabel('Years')
    plt.ylabel('Probability')
    plt.xlim(1, crop_prob.shape[0])
    plt.ylim(0, 1)
    plt.show()

    plt.stackplot(1 + np.arange(planting_prob.shape[0]), *planting_prob.T,
                  colors=color[:planting_prob.shape[0]])
    plt.xticks(1 + np.arange(planting_prob.shape[0]))
    plt.xlabel('Years')
    plt.ylabel('Probability')
    plt.xlim(1, planting_prob.shape[0])
    plt.ylim(0, 1)
    plt.show()

def plot_crop_planning_policy_det(episode_actions, episode_rewards, run, eval_env_class, eval_test):
    color = get_cmap('Accent').colors

    if 'Rotation' in eval_env_class:
        title = 'Rotation observations'
    else:
        title = 'SoilN observations'

    episode_actions = episode_actions.squeeze()
    planting_date = episode_actions[:, 1]
    planting_date = 90 + planting_date * 7
    crop = episode_actions[:, 0]
    fig, ax = plt.subplots(2, 1, sharex=True)

    x = 1980 + np.arange(planting_date.size)

    ax[0].bar(x, np.array(episode_rewards)/1000.,
              color=[color[c] for c in crop])
    ax[0].set_ylabel('Year reward [k\$]')
    ax[0].set_title(title)

    ax[1].scatter(x, planting_date, color=[color[c] for c in crop],
                  s=100, marker='o')
    ax[1].set_xticks(x)
    ax[1].set_xlabel('Years')
    ax[1].set_ylabel('Planting date [DOY]')
    ax[1].set_xlim(min(x) + 0.5, max(x) + 0.5)

    fig.autofmt_xdate()

    plt.legend()
    plt.savefig(PROJECT_PATH.joinpath('figures/crop_planning_policies/' + run.path[-1] + '_' +\
                eval_test + '.pdf'), bbox_inches='tight')
    plt.show()

if __name__ == '__main__':

    config = dict(train_start_year=1980, train_end_year=1998, eval_start_year=1998, eval_end_year=2016,
                  total_timesteps=1000000, eval_freq=1000, n_steps=80, batch_size=64, n_epochs=10, run_id=0,
                  norm_reward=True, method="PPO", verbose=1, n_process=8, device='auto')
    api = wandb.Api()

    # Project is specified by <entity/project-name>
    runs = api.runs("koralabs/experiments_crop_planning")

    summary_list, summary_at_max, config_list, name_list = [], [], [], []
    for run in runs:
        dir = [dir for dir in PROJECT_PATH.joinpath('wandb').iterdir() if run.path[-1] in str(dir)]
        if len(dir) > 0:
            print(run)
            dir = dir[0]
            file = dir.joinpath('files/models/eval_det/best_model')
            run_config = run.config
            print(run_config)

            eval_env_class = 'CropPlanningFixedPlanting'
            if run_config.get('non_adaptive', False) == 'True':
                eval_env_class = 'CropPlanningFixedPlantingRotationObserver'

            config['eval_env_class'] = eval_env_class

            envs = Train(config).create_envs()

            model = PPO.load(file, device='cpu')

            def get_plot(model, env, run, eval_env_class, eval_test, deterministic=True):
                mean_reward, std_reward, episode_actions, episode_rewards, episode_probs, episode_action_rewards = \
                    _evaluate_policy(model, env,  n_eval_episodes=1, deterministic=deterministic)
                plot_crop_planning_policy_det(episode_actions, episode_action_rewards, run, eval_env_class, eval_test)

            for env, eval_test in zip(envs, ['train', 'rs98', 'nh98', 'nh15']):
                get_plot(model, env, run, eval_env_class, eval_test)