# Prerequisit: selenium and chromedriver
# On Mac:
# Pip3 install -U selenium
# brew  install chromedriver

import time
from sys import exit
import os

try:
	from selenium import webdriver
	from selenium.webdriver.common.by import By
	from selenium.common.exceptions import NoSuchElementException, WebDriverException
except ImportError as e:
	print("Please install selenium")
	exit(1)

chromedriver_location='/usr/local/bin/chromedriver'
initial_url='https://www.cvs.com/immunizations/covid-19-vaccine?icid=cvs-home-hero1-banner-1-link2-coronavirus-vaccine#'

state='California'

chromeOptions = webdriver.ChromeOptions()
chromeOptions.add_experimental_option("prefs", {"profile.managed_default_content_settings.images": 2})
chromeOptions.add_argument("--headless")
chromeOptions.add_argument("--no-sandbox")
chromeOptions.add_argument("--disable-setuid-sandbox")

chromeOptions.add_argument("--remote-debugging-port=0")

chromeOptions.add_argument("--disable-dev-shm-using")
chromeOptions.add_argument("--disable-extensions")
chromeOptions.add_argument("--disable-gpu")
chromeOptions.add_argument("start-maximized")
chromeOptions.add_argument("disable-infobars")
chromeOptions.add_argument(r"user-data-dir=.\cookies\\test")

try:
	driver = webdriver.Chrome(chromedriver_location, options=chromeOptions)
except WebDriverException:
	print("Chromedriver not found. Install chromedriver and set chromedriver_location")
	exit(1)

driver.get(initial_url);
time.sleep(3)

try:
	CA=driver.find_element(By.XPATH,'/html/body/div[3]/div/div[1]/a');
	CA.click();
	time.sleep(5);
except NoSuchElementException:
	pass

try:
	CA=driver.find_element_by_link_text(state);
	CA.click();
except NoSuchElementException:
	driver.quit();

time.sleep(2)

CA_text=driver.find_element(By.XPATH,'/html/body/div[2]/div/div[13]/div/div/div/div/div/div[1]/div[2]/div/div/div[2]/div/div[6]/div/div')
print(CA_text.text)

driver.quit()


#!/usr/bin/env python

import logging

from multiqc.utils import config
from pkg_resources import get_distribution

# Initialise the main MultiQC logger
log = logging.getLogger("multiqc")

# Save this plugin's version number (defined in setup.py) to the MultiQC config
config.multiqc_sav_version = get_distribution("multiqc_sav").version
log.info("Running MultiQC SAV Plugin v{}".format(config.multiqc_sav_version))

def update_config() -> None:
    """
    Update MultiQC config object
    * Update module order
    * Disable unnecessary modules to avoid duplicate data
    * Update search patterns
    """

    log.debug("SAV - Updating config")
    # Add module to module order
    config.module_order.append({"SAV": {"module_tag": ["DNA", "RNA", "BCL", "Demultiplex"]}})

    # Move module to the top
    config.top_modules.append("SAV")

    # Disable InterOp module to avoid duplicate data
    disabled_modules = ["interop"]
    for module in disabled_modules:
        del config.avail_modules[module]

    # Update search patterns
    if "SAV/xml" not in config.sp:
        config.update_dict(config.sp, {"SAV/xml": {"fn_re": ".*([Rr]un[Ii]nfo|[Rr]un[Pp]arameters)\.xml", "shared": True}})
    config.update_dict(config.sp, {"bclconvert/runinfo": {"fn": "RunInfo.xml", "shared": True}})


# -*- coding: utf-8 -*-

import asyncio
import ipaddress
import logging

from pyzwave.message import Message
from pyzwave.commandclass import (
    NetworkManagementInclusion,
    NetworkManagementProxy,
    Zip,
    ZipGateway,
    ZipND,
)
from pyzwave.adapter import TxOptions
from pyzwave.connection import Connection
from pyzwave.zipconnection import ZIPConnection
from pyzwave.types import dsk_t

_LOGGER = logging.getLogger(__name__)

class ZIPGateway(ZIPConnection):
    """Class for communicating with a zipgateway"""

    def __init__(self, address, psk):
        super().__init__(address, psk)
        self._unsolicitedConnection = Connection()
        self._unsolicitedConnection.onMessage(self.onUnsolicitedMessage)
        self._connections = {}
        self._nodes = {}
        self._nmSeq = 0

    async def addNode(self, txOptions: TxOptions) -> bool:
        self._nmSeq = self._nmSeq + 1
        cmd = NetworkManagementInclusion.NodeAdd(
            seqNo=self._nmSeq,
            mode=NetworkManagementInclusion.NodeAdd.Mode.ANY_S2,
            txOptions=txOptions,
        )
        try:
            # We do not get any immediate response
            await self.send(cmd)
        except asyncio.TimeoutError:
            return False
        return True

    async def addNodeDSKSet(
        self, accept: bool, inputDSKLength: int, dsk: dsk_t
    ) -> bool:
        self._nmSeq = self._nmSeq + 1
        cmd = NetworkManagementInclusion.NodeAddDSKSet(
            seqNo=self._nmSeq, accept=accept, inputDSKLength=inputDSKLength, dsk=dsk,
        )
        try:
            await self.send(cmd)
        except asyncio.TimeoutError:
            return False
        return True

    async def addNodeKeysSet(
        self, grantCSA: bool, accept: bool, grantedKeys: NetworkManagementInclusion.Keys
    ) -> bool:
        self._nmSeq = self._nmSeq + 1
        cmd = NetworkManagementInclusion.NodeAddKeysSet(
            seqNo=self._nmSeq,
            grantCSA=grantCSA,
            accept=accept,
            grantedKeys=grantedKeys,
        )
        try:
            await self.send(cmd)
        except asyncio.TimeoutError:
            return False
        return True

    async def addNodeStop(self) -> bool:
        self._nmSeq = self._nmSeq + 1
        cmd = NetworkManagementInclusion.NodeAdd(
            seqNo=self._nmSeq,
            mode=NetworkManagementInclusion.NodeAdd.Mode.STOP,
            txOptions=TxOptions.NULL,
        )
        try:
            await self.send(cmd)
        except asyncio.TimeoutError:
            return False
        return True

    async def connect(self):
        await super().connect()
        await self.setGatewayMode(1)
        await self.setupUnsolicitedConnection()

    async def connectToNode(self, nodeId) -> ZIPConnection:
        """Returns a connection to the node"""
        if nodeId in self._connections:
            return self._connections[nodeId]

        ipv6 = await self.ipOfNode(nodeId)

        connection = ZIPConnection(ipv6.compressed, self.psk)
        connection.addListener(self)
        await connection.connect()
        self._connections[nodeId] = connection
        return connection

    async def getFailedNodeList(self) -> list:
        self._nmSeq = self._nmSeq + 1
        cmd = NetworkManagementProxy.FailedNodeListGet(seqNo=self._nmSeq,)
        try:
            report = await self.sendAndReceive(
                cmd, NetworkManagementProxy.FailedNodeListReport
            )
        except asyncio.TimeoutError:
            return set()
        return report.failedNodeList

    async def getMultiChannelEndPoints(self, nodeId: int) -> int:
        self._nmSeq = self._nmSeq + 1
        cmd = NetworkManagementProxy.MultiChannelEndPointGet(
            seqNo=self._nmSeq, nodeID=nodeId
        )
        try:
            report = await self.sendAndReceive(
                cmd, NetworkManagementProxy.MultiChannelEndPointReport
            )
        except asyncio.TimeoutError:
            # No response
            return 0
        return report.individualEndPoints + report.aggregatedEndPoints

    async def getMultiChannelCapability(
        self, nodeId: int, endpoint: int
    ) -> NetworkManagementProxy.MultiChannelCapabilityReport:
        self._nmSeq = self._nmSeq + 1
        cmd = NetworkManagementProxy.MultiChannelCapabilityGet(
            seqNo=self._nmSeq, nodeID=nodeId, endPoint=endpoint
        )
        try:
            report = await self.sendAndReceive(
                cmd, NetworkManagementProxy.MultiChannelCapabilityReport
            )
        except asyncio.TimeoutError:
            # No response
            return NetworkManagementProxy.MultiChannelCapabilityReport()
        return report

    async def getNodeList(self) -> set:
        if self._nodes:
            # Return cached list
            return set(self._nodes.keys())
        self._nmSeq = self._nmSeq + 1
        cmd = NetworkManagementProxy.NodeListGet(seqNo=self._nmSeq)
        try:
            report = await self.sendAndReceive(
                cmd, NetworkManagementProxy.NodeListReport
            )
        except asyncio.TimeoutError:
            # No response
            return set()
        self._nodeId = report.nodeListControllerId
        self._nodes = {x: {} for x in report.nodes}
        return report.nodes

    async def getNodeInfo(
        self, nodeId: int
    ) -> NetworkManagementProxy.NodeInfoCachedReport:
        self._nmSeq = self._nmSeq + 1
        cmd = NetworkManagementProxy.NodeInfoCachedGet(
            seqNo=self._nmSeq, maxAge=15, nodeID=nodeId
        )
        try:
            report = await self.sendAndReceive(
                cmd, NetworkManagementProxy.NodeInfoCachedReport
            )
        except asyncio.TimeoutError:
            return NetworkManagementProxy.NodeInfoCachedReport()
        return report

    async def __handleNodeListReport__(
        self, report: NetworkManagementProxy.NodeListReport
    ):
        """Update nodes from a nodeListReport"""
        # Find removed nodes
        for nodeId in list(self._nodes.keys()):
            if nodeId in report.nodes:
                continue
            del self._nodes[nodeId]

        # Find new nodes
        for nodeId in report.nodes:
            if nodeId in self._nodes:
                continue
            # Retrieve ip
            self._nodes[nodeId] = {"ip": await self.ipOfNode(nodeId)}
        self.speak("nodeListUpdated")

    async def ipOfNode(self, nodeId) -> ipaddress.IPv6Address:
        """Returns the IPv6 address of the node"""
        msg = ZipND.ZipInvNodeSolicitation(local=False, nodeId=nodeId)
        self._conn.send(msg.compose())
        response = await self.waitForMessage(ZipND.ZipNodeAdvertisement, timeout=3)
        return response.ipv6

    async def removeFailedNode(
        self, nodeId: int
    ) -> NetworkManagementInclusion.FailedNodeRemoveStatus.Status:
        self._nmSeq = self._nmSeq + 1
        cmd = NetworkManagementInclusion.FailedNodeRemove(
            seqNo=self._nmSeq, nodeID=nodeId
        )
        try:
            # The timeout might need to be increased. The Z-Wave may need to query the
            # network for a response first and this may take time on a large network
            report = await self.sendAndReceive(
                cmd, NetworkManagementInclusion.FailedNodeRemoveStatus, timeout=10
            )
        except asyncio.TimeoutError:
            return NetworkManagementInclusion.FailedNodeRemoveStatus.Status.REMOVE_FAIL
        return report.status

    async def removeNode(self) -> bool:
        self._nmSeq = self._nmSeq + 1
        cmd = NetworkManagementInclusion.NodeRemove(
            seqNo=self._nmSeq, mode=NetworkManagementInclusion.NodeRemove.Mode.ANY
        )
        try:
            # We do not get any immediate response
            await self.send(cmd)
        except asyncio.TimeoutError:
            return False
        return True

    async def removeNodeStop(self) -> bool:
        self._nmSeq = self._nmSeq + 1
        cmd = NetworkManagementInclusion.NodeRemove(
            seqNo=self._nmSeq, mode=NetworkManagementInclusion.NodeRemove.Mode.STOP
        )
        try:
            # We do not get any immediate response
            await self.send(cmd)
        except asyncio.TimeoutError:
            return False
        return True

    def onMessageReceived(self, connection: ZIPConnection, message: Message):
        """Called when a message is received from any node connection. Not unsolicited."""
        sourceEP = 0
        if isinstance(message, Zip.ZipPacket):
            sourceEP = message.sourceEP
            message = message.command
        for nodeId, nodeConnection in self._connections.items():
            if connection != nodeConnection:
                continue
            flags = 0  # Set flags such as encapsulation type
            self.speak("messageReceived", nodeId, sourceEP, message, flags)
            return
        _LOGGER.warning("Got message from unknown sender %s: %s", connection, message)

    def onUnsolicitedMessage(self, pkt, address):
        """
        Called when an unsolicited message is received.
        We do not know the node id the message is from. Only the ip address.
        """
        zipPkt = Message.decode(pkt)
        sourceIp = ipaddress.IPv6Address(address[0])
        sourceEP = zipPkt.sourceEP

        if isinstance(zipPkt.command, NetworkManagementProxy.NodeListReport):
            return asyncio.ensure_future(self.__handleNodeListReport__(zipPkt.command))

        # Find the node this was from
        for nodeId, node in self._nodes.items():
            if node.get("ip") != sourceIp:
                continue
            if zipPkt.ackRequest:
                # This message needs an ack response.
                ackReponse = zipPkt.response(success=True)
                self._unsolicitedConnection.sendTo(ackReponse.compose(), address)

            self.speak(
                "messageReceived",
                nodeId,
                sourceEP,
                zipPkt.command,
                zipPkt.headerExtension,
            )
            return True
        _LOGGER.warning(
            "Got message from unknown sender %s: %s", sourceIp, zipPkt.command
        )
        return False

    async def sendToNode(self, nodeId: int, cmd: Message, **kwargs) -> bool:
        conn = await self.connectToNode(nodeId)
        return await conn.send(cmd, **kwargs)

    async def setGatewayMode(self, mode: int, timeout: int = 3) -> bool:
        """Set gateway to standalone or portal mode"""
        try:
            report = await self.sendAndReceive(
                ZipGateway.GatewayModeGet(),
                ZipGateway.GatewayModeReport,
                timeout=timeout,
            )
            if report.mode != mode:
                await self.send(ZipGateway.GatewayModeSet(mode=mode))
        except asyncio.TimeoutError:
            _LOGGER.error("Got timeout waiting for gateway mode report")
            return False
        return True

    async def setNodeInfo(self, generic, specific, cmdClasses):
        raise NotImplementedError()

    async def setupUnsolicitedConnection(self):
        """
        Setup for listening for unsolicited connections. This function must not be called
        explicitly. It is called by the connect() method automatically
        """
        await self._unsolicitedConnection.listen(self.psk, 4123)
        await self.send(
            ZipGateway.UnsolicitedDestinationSet(
                unsolicitedIPv6Destination=ipaddress.IPv6Address("::ffff:c0a8:31"),
                port=4123,
            )
        )
        # Retrieve node list, and get ip-addresses
        for nodeId in await self.getNodeList():
            if not self._nodes[nodeId].get("ip"):
                self._nodes[nodeId] = {"ip": await self.ipOfNode(nodeId)}


#!/usr/bin/python3
# -*- coding: utf-8 -*-
#
# guio-ping.py
#
# 17 de nov. 2022  <adria@molevol-OptiPlex-9020>

"""
1. Envia una ordre de 'mtr' al sistema amb el mòdul 'os'.
2. Recull el resultat (en format csv?) amb pandas dins un dataframe.
3. Elimina i afegeix info per ajustar a les necessitats.
4. Append a un file.csv per guardar les anàlisis.
"""

import sys
import os
import pandas as pd

# Recull la data de les anàlisis de ping...
import datetime

# Funció per fer Sleep...
import time

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

def data(f):
    """
    Retorna la data d'ara amb el format indicat. Les opcions son:
    + f = 'd'; '11-Sep-2022'
    + f = 'h'; '10:56'
    """
    # Imprimeix-la segons el format que indica als documents...
    # <https://docs.python.org/3/library/datetime.html#strftime-strptime-behavior>

    ara = datetime.datetime.now()
    if f=='d':
        # Prén la data 'avui'.
        return ara.strftime('%d-%b-%Y')
    elif f=='h':
        # Prén la hora 'ara'.
        return ara.strftime('%H:%M')

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

# Si es crida com a script:
if __name__ == '__main__':

    ### PARSE ARGUMENTS ###
    import argparse

    parser = argparse.ArgumentParser(
        description='Analyse the network via `mtr` for a period of time (by default, a day)')
    # file-name: positional arg.
    parser.add_argument('hostnames', type=str,
    help='Path to hostnames file (each row should correspond to a singular hostname)'
                        )
    # file-name: optional required argument.
    parser.add_argument('-o', '--outfile', type=str,
        help='Path and filename where output should be written (will append to the end)')
    # integer: not required.
    parser.add_argument('-n', '--numb',
            type=int, default=int(24), required=False,
            help="Amount of packets sent while performing the analyses")

    args = parser.parse_args()
    # call a value: args.operacio or args.filename.

    # init the dataframe to store all hostnames' traceroutes:
    df = pd.DataFrame(columns=[
        'Start_Time',
        'Status',
        'Host',
        'Hop',
        'Ip',
        'Loss%',
        'Best',
        'Avg',
        'Wrst',
        'StDev',
    ])

    with open(args.hostnames) as hfile:
        for hname in hfile:
            hname = hname.strip()
            print(f'-- Pinging to `{hname}`')
            # Make sure `mtr` is installed in the command-line.
            # Creates a tmp file (traceroute.tmp.csv) with the analysis results.
            command = f"mtr -c {args.numb} --csv -o 'LBAWV' {hname} > traceroute.tmp.csv"

            # -c 10 should send {args.numb} packets.
            # --csv: output in csv format.
            # -o 'lBAWV': output these fields only.

            os.system(command)
            # Concatena el dataframe `df` amb el resultat de la comanda
            # anterior.
            # elimina la primera i última columna (.iloc[:,1:-1])
            # la primera te la versió del soft. i la última és buida.
            df = pd.concat([df,
                    pd.read_csv('traceroute.tmp.csv').iloc[:,1:-1].assign(Hora=data('h'))])

    print(f'-- Writing pd.DataFrame() to `{args.outfile}`')
    # Imprimeix el header si el fitxer no existeix.
    # mode 'append' to already existing file.
    df.to_csv(args.outfile, mode='a', header=not os.path.exists(args.outfile))

    # Imprimeix els resultats finals en pantalla.
    print('-- Final dataframe:'); print()
    print(df.info())
    # remove tmp file
    os.system('rm --force traceroute.tmp.csv')
    print (f'-- temp. file traceroute.tmp.csv has been removed')


from lib.GameBase import GameBase
from lib.mylogging import log

class ObjectMeta(object):
    def __init__(self, ob : GameBase, level : int, friend : bool, enemy : bool, name : str) -> None:
        self.ob = ob
        self.level = level
        self.enemy = enemy
        self.friend = friend
        self.name = name

class GameObjectKeeper(object):
	OBJECT_LIST : list = []

	@classmethod
	def special_setup(cls, ob : GameBase, level : int, friend=False, enemy=False, name=None) -> None:
		""" used only when level is special, like for the game background """
		log.debug("Setup for: {0}".format(ob))
		cls.OBJECT_LIST.append(ObjectMeta(ob, level, friend, enemy, name))
		cls.sortobjects()

	@classmethod
	def setup(cls, ob : GameBase, level : int, friend : bool = False, enemy : bool = False, name : str = None) -> None:
		if (level < 1):
			raise ValueError("Object Level is below 1, must be 1 or greater!")
		cls.special_setup(ob, level, friend, enemy, name)

	@classmethod
	def setupfriendly(cls, ob : GameBase , level : int) -> None:
		cls.setup(ob, level, friend=True)

	@classmethod
	def setupenemy(cls, ob : GameBase, level : int) -> None:
		cls.setup(ob, level, enemy=True)

	@classmethod
	def sortobjects(cls) -> None:
		log.info("Sorting Game Stage ...")
		cls.OBJECT_LIST.sort( key=lambda ob: ob.level)

	@classmethod
	def runables(cls) -> list:
		return [ item.ob for item in cls.OBJECT_LIST ]

	@classmethod
	def friendlies(cls)-> list:
		return [ item.ob for item in cls.OBJECT_LIST if item.friend ]

	@classmethod
	def enemies(cls)-> list:
		return [ item.ob for item in cls.OBJECT_LIST if item.enemy ]

	@classmethod
	def get_by_name(cls, ob_name):
		for item in cls.OBJECT_LIST:
			if item.name == ob_name:
				return item.ob
		return None

	@classmethod
	def remove(cls, ob):
		for item in cls.OBJECT_LIST:
			if (item.ob == ob):
				if (item.level < 1):
					log.debug("Cant remove special items")
					return
				cls.OBJECT_LIST.remove(item)
				log.debug("Removing {}".format(item))
				return
		raise ValueError("Item {0} not found in list.".format(ob))

	@classmethod
	def setupmisc(cls, ob: GameBase, level: int) -> None:
		cls.setup(ob,level)


import numpy as np
import pandas as pd
import yfinance as yf
import xlsxwriter
import math
import time

# Scrape the list of S&P500 companies from Wikipedia
table = pd.read_html('https://en.wikipedia.org/wiki/List_of_S%26P_500_companies')
stocks = table[0]
print(stocks)

#Wiki gives us a lot of crap, we just need the symbol
stocks = stocks[['Symbol']]
stocks.columns = ['Ticker']

#yfinance requires secondary assets such as BRK.B to be listed as BRK-B
stocks['Ticker'] = stocks['Ticker'].str.replace('.', '-')

my_columns = ['Ticker', 'Price','Market Capitalization', 'Number Of Shares to Buy']
final_dataframe = pd.DataFrame(columns = my_columns)

for symbol in stocks['Ticker']:
    print(f"Fetching data for {symbol}")
    tickerData = yf.Ticker(symbol)
    retries = 5  # adjustable retry total
    for i in range(retries):
        try:
            temp_df = pd.DataFrame([
                {
                    'Ticker': symbol,
                    'Price': tickerData.info['previousClose'],
                    'Market Capitalization': tickerData.info['marketCap'],
                    'Number Of Shares to Buy': 'N/A'
                }
            ])
            final_dataframe = pd.concat([final_dataframe, temp_df], ignore_index=True)
            print(f"Data fetched for {symbol}")
            break
        except KeyError:
            print(f'Data not found for {symbol}, retrying ({i+1}/{retries})...')
            time.sleep(1)  # adjustable delay
    else:
        print(f'Failed to fetch data for {symbol} after {retries} retries, skipping.')

portfolio_size = input("Enter the value of your portfolio:")

try:
    val = float(portfolio_size)
except ValueError:
    print("That's not a number! \n Try again:")
    portfolio_size = input("Enter the value of your portfolio:")

position_size = float(portfolio_size) / len(final_dataframe.index)
for i in range(0, len(final_dataframe['Ticker'])-1):
    final_dataframe.loc[i, 'Number Of Shares to Buy'] = math.floor(position_size / final_dataframe['Price'][i])

writer = pd.ExcelWriter('recommended_trades.xlsx', engine='xlsxwriter')
final_dataframe.to_excel(writer, sheet_name='Recommended Trades', index = False)

background_color = '#0a0a23'
font_color = '#ffffff'

string_format = writer.book.add_format(
        {
            'font_color': font_color,
            'bg_color': background_color,
            'border': 1
        }
    )

dollar_format = writer.book.add_format(
        {
            'num_format':'$0.00',
            'font_color': font_color,
            'bg_color': background_color,
            'border': 1
        }
    )

integer_format = writer.book.add_format(
        {
            'num_format':'0',
            'font_color': font_color,
            'bg_color': background_color,
            'border': 1
        }
    )

column_formats = {
                    'A': ['Ticker', string_format],
                    'B': ['Price', dollar_format],
                    'C': ['Market Capitalization', dollar_format],
                    'D': ['Number of Shares to Buy', integer_format]
                    }

for column in column_formats.keys():
    writer.sheets['Recommended Trades'].set_column(f'{column}:{column}', 18, column_formats[column][1])
    writer.sheets['Recommended Trades'].write(f'{column}1', column_formats[column][0], column_formats[column][1])

writer.close()


import os
from PIL import Image
import numpy as np
import sys

class Carrier:

    def __init__(self, image_path):
        if os.path.splitext(image_path)[1].lower() != ".png":
            # validating image format (png only)
            print("Image fromat error\nexitting...")
            sys.exit(1)
        self.name = os.path.basename(image_path)
        self.path = os.path.dirname(image_path)
        try:
            image = Image.open(image_path)
        except FileNotFoundError:
            print('Error loading image\nexitting...')
            sys.exit(1)
        self.mat = np.array(image)[..., :3]
        image.close()
        self.height = self.mat.shape[0]
        self.width = self.mat.shape[1]

    def create_image(self):
        carrier_image = Image.new('RGB', (self.width, self.height))
        for row in range(self.height):
            for col in range(self.width):
                carrier_image.putpixel((col, row), tuple(self.mat[row][col]))
        carrier_image.save('./OUT_' + self.name)
        carrier_image.show()


from datetime import date
from django.db import transaction
from rest_framework.exceptions import NotFound
import datetime

from .models import Asset, RepairingStock
from ..orders.models import Customer
from ..products.models import Product, Category
from utils.exceptionhandler import CustomException

class AssetService:
    """Performs asset related operations like add new asset for a customer,
    update asset details"""

    @transaction.atomic()
    def create(self, validated_data, organisation_uid):
        """Creates new Asset from the given data"""

        try:
            product = Product.objects.get(
                organisation_id=organisation_uid, product_uid=validated_data["product"],
            )
            customer = Customer.objects.get(
                organisation_id=organisation_uid,
                customer_uid=validated_data["customer"],
            )

            try:
                asset = Asset.objects.get(
                    product_id=product.id,
                    serial_no=validated_data["serial_no"],
                    is_active=True,
                )
                raise CustomException(400, "This product is already assigned")
            except Asset.DoesNotExist:
                pass

            if product.available_stock <= 0:
                raise CustomException(400, "Product is out of Stock")
            new_asset = Asset.objects.create(
                name=validated_data["name"],
                serial_no=validated_data["serial_no"],
                customer_id=validated_data["customer"],
                organisation_id=organisation_uid,
                product_id=validated_data["product"],
            )
            product.available_stock -= 1
            product.save()
            return new_asset
        except KeyError as exc:
            raise CustomException(400, "Exception in Asset Service")
        except Product.DoesNotExist:
            raise CustomException(400, "Invalid Product")
        except Customer.DoesNotExist:
            raise CustomException(400, "Invalid Customer")

    def update(self, instance, request):
        """Updates the Asset from the given data"""

        try:
            if not instance.is_active:
                raise CustomException(400, "Only active assets can be updated")
            customer = Customer.objects.get(
                customer_uid=request["customer"], organisation_id=instance.organisation
            )
            product = Product.objects.get(
                product_uid=request["product"], organisation_id=instance.organisation
            )
            instance.updated_date = date.today()
            if product.id != instance.product_id:
                if product.available_stock <= 0:
                    raise CustomException(400, "Product is out of stock")
                product.available_stock -= 1
                product.save()
                new_product = Product.objects.get(product_uid=instance.product_id)
                new_product.available_stock += 1
                new_product.save()
            return instance
        except Customer.DoesNotExist:
            raise CustomException(404, "Invalid Customer")
        except Product.DoesNotExist:
            raise CustomException(404, "Invalid Product")
        except KeyError:
            raise CustomException(400, "Product and Customer is mandatory for updating")

    @transaction.atomic()
    def close_asset(self, asset_details, data):
        """Update Asset status to False"""

        try:
            is_active = asset_details.is_active
            response = {}
            if not is_active:
                response = {"message": "It is already not active"}
            elif is_active:
                asset_details.is_active = False
                asset_details.updated_date = date.today()

                try:
                    returned_date = datetime.datetime.strptime(
                        data["return_date"], "%Y-%m-%d"
                    )
                    if returned_date > datetime.datetime.today():
                        raise CustomException(
                            400, "Returned Date cannot be after today"
                        )
                except KeyError:
                    data["return_date"] = datetime.datetime.today()

                asset_details.return_date = data["return_date"]
                asset_details.save()
                response = {"message": "Assigned asset is closed"}
            return response
        except NotFound:
            raise CustomException(
                400, "Internal error in updating active status in asset"
            )

class RepairingStockService:
    """Performs Repairing Stock related operations like add new repairing stock for an asset,
        update repairing stock details"""

    @transaction.atomic()
    def create(self, validated_data, organisation_uid):
        """Creates new Repairing Stock for the given Asset"""

        try:
            asset = Asset.objects.get(
                organisation_id=organisation_uid, asset_uid=validated_data["asset"]
            )

            try:
                repairing_stock = RepairingStock.objects.get(
                    asset_id=validated_data["asset"], is_active=True
                )
                raise CustomException(400, "This product is already in repairing stock")
            except RepairingStock.DoesNotExist:
                pass

            if asset.is_active:
                raise CustomException(
                    400, "Cannot be created, Assigned is still active"
                )

            new_repairing_stock = RepairingStock.objects.create(
                serial_no=asset.serial_no,
                asset_id=validated_data["asset"],
                product_id=asset.product_id,
                organisation_id=organisation_uid,
            )
            return new_repairing_stock
        except KeyError as exc:
            raise CustomException(400, "Exception in Repairing Stock Service")
        except Asset.DoesNotExist:
            raise CustomException(400, "Invalid Asset")

    def update(self, instance, request):
        """Updates Repairing Asset for the given data"""

        try:
            if not instance.is_active:
                raise CustomException(
                    400, "Only active repairing stocks can be updated"
                )
            asset = Asset.objects.get(
                asset_uid=request["asset"],
                product_id=request["product"],
                organisation_id=instance.organisation,
            )
            instance.updated_date = date.today()
            return instance
        except Asset.DoesNotExist:
            raise CustomException(404, "Invalid Asset")

    @transaction.atomic()
    def close_repairing_stock(self, repairing_stock_details, data):
        """Update Reparing status to False and reflects to the product accordingly"""

        try:
            is_active = repairing_stock_details.is_active
            response = {}
            if not is_active:
                response = {"message": "It is already not active"}
            elif is_active:
                repairing_stock_details.is_active = False
                repairing_stock_details.updated_date = date.today()

                try:
                    closed_date = datetime.datetime.strptime(
                        data["closed_date"], "%Y-%m-%d"
                    )
                    if closed_date > datetime.datetime.today():
                        raise CustomException(400, "Closed Date cannot be after today")
                except KeyError:
                    data["closed_date"] = datetime.datetime.today()

                repairing_stock_details.closed_date = data["closed_date"]
                repairing_stock_details.save()
                product = Product.objects.get(
                    product_uid=repairing_stock_details.product_id
                )
                product.available_stock = product.available_stock + 1
                product.save()
                response = {"message": "Repairing Stock asset is closed"}
            return response
        except NotFound:
            raise CustomException(
                400, "Internal error in updating active status in repairing stock"
            )


# -*- coding: utf-8 -*-
"""
Created on Tue Apr  9 18:07:47 2019

Chapter 6 Praktikum

@author: Bakti Qilan
"""
from matplotlib import pyplot as plt

def pie(mod):
    if mod == 2:
        merk= [5,10,2,3]
        prog = [7,5,6,1]
        jns_merk = ['Acer','Asus','Lenovo','HP']
        programming = ['Perl','Java','C++','Python']
        cols = ['silver','lime','gold','aqua']
        plt.subplot(121)
        plt.pie(merk,
                 labels=jns_merk,
                 colors=cols,
                 startangle=0,
                 shadow= True,
                 explode=(0.2,0,0,0),
                 autopct='%1.1f%%')
        plt.title('Pie Laptop')

        plt.subplot(122)
        plt.pie(prog,
                 labels=programming,
                 colors=cols,
                 startangle=90,
                 shadow=True,
                 explode=(.1,0,0,0),
                 autopct='%1.1f%%')
        plt.title('Pie Programming')
        plt.show()
    else:
        print("Data tidak ada")

npm = input("Masukkan NPM Anda: ")
modnpm = int(npm)%3+2
print(modnpm)

if modnpm == 4:
    print("Data tidak ada")
elif modnpm == 3:
    print("Data tidak ada")
elif modnpm == 2:
    pie(2)
elif modnpm == 1:
    print("Data tidak ada")
else:
    print("Data tidak Valid")


import math

import paddle
import paddle.fluid as fluid
from paddle.fluid.param_attr import ParamAttr
from paddle.fluid.layer_helper import LayerHelper
from paddle.fluid.dygraph.nn import Conv2D, Pool2D, Linear
from paddle.fluid.initializer import Normal
from paddle.nn import SyncBatchNorm as BatchNorm

from dygraph.cvlibs import manager

__all__ = [
    "HRNet_W18_Small_V1", "HRNet_W18_Small_V2", "HRNet_W18", "HRNet_W30",
    "HRNet_W32", "HRNet_W40", "HRNet_W44", "HRNet_W48", "HRNet_W60", "HRNet_W64"
]

class HRNet(fluid.dygraph.Layer):
    """
    HRNet：Deep High-Resolution Representation Learning for Visual Recognition
    https://arxiv.org/pdf/1908.07919.pdf.

    Args:
        stage1_num_modules (int): number of modules for stage1. Default 1.
        stage1_num_blocks (list): number of blocks per module for stage1. Default [4].
        stage1_num_channels (list): number of channels per branch for stage1. Default [64].
        stage2_num_modules (int): number of modules for stage2. Default 1.
        stage2_num_blocks (list): number of blocks per module for stage2. Default [4, 4]
        stage2_num_channels (list): number of channels per branch for stage2. Default [18, 36].
        stage3_num_modules (int): number of modules for stage3. Default 4.
        stage3_num_blocks (list): number of blocks per module for stage3. Default [4, 4, 4]
        stage3_num_channels (list): number of channels per branch for stage3. Default [18, 36, 72].
        stage4_num_modules (int): number of modules for stage4. Default 3.
        stage4_num_blocks (list): number of blocks per module for stage4. Default [4, 4, 4, 4]
        stage4_num_channels (list): number of channels per branch for stage4. Default [18, 36, 72. 144].
        has_se (bool): whether to use Squeeze-and-Excitation module. Default False.
    """

    def __init__(self,
                 stage1_num_modules=1,
                 stage1_num_blocks=[4],
                 stage1_num_channels=[64],
                 stage2_num_modules=1,
                 stage2_num_blocks=[4, 4],
                 stage2_num_channels=[18, 36],
                 stage3_num_modules=4,
                 stage3_num_blocks=[4, 4, 4],
                 stage3_num_channels=[18, 36, 72],
                 stage4_num_modules=3,
                 stage4_num_blocks=[4, 4, 4, 4],
                 stage4_num_channels=[18, 36, 72, 144],
                 has_se=False):
        super(HRNet, self).__init__()

        self.stage1_num_modules = stage1_num_modules
        self.stage1_num_blocks = stage1_num_blocks
        self.stage1_num_channels = stage1_num_channels
        self.stage2_num_modules = stage2_num_modules
        self.stage2_num_blocks = stage2_num_blocks
        self.stage2_num_channels = stage2_num_channels
        self.stage3_num_modules = stage3_num_modules
        self.stage3_num_blocks = stage3_num_blocks
        self.stage3_num_channels = stage3_num_channels
        self.stage4_num_modules = stage4_num_modules
        self.stage4_num_blocks = stage4_num_blocks
        self.stage4_num_channels = stage4_num_channels
        self.has_se = has_se

        self.conv_layer1_1 = ConvBNLayer(
            num_channels=3,
            num_filters=64,
            filter_size=3,
            stride=2,
            act='relu',
            name="layer1_1")

        self.conv_layer1_2 = ConvBNLayer(
            num_channels=64,
            num_filters=64,
            filter_size=3,
            stride=2,
            act='relu',
            name="layer1_2")

        self.la1 = Layer1(
            num_channels=64,
            num_blocks=self.stage1_num_blocks[0],
            num_filters=self.stage1_num_channels[0],
            has_se=has_se,
            name="layer2")

        self.tr1 = TransitionLayer(
            in_channels=[self.stage1_num_channels[0] * 4],
            out_channels=self.stage2_num_channels,
            name="tr1")

        self.st2 = Stage(
            num_channels=self.stage2_num_channels,
            num_modules=self.stage2_num_modules,
            num_blocks=self.stage2_num_blocks,
            num_filters=self.stage2_num_channels,
            has_se=self.has_se,
            name="st2")

        self.tr2 = TransitionLayer(
            in_channels=self.stage2_num_channels,
            out_channels=self.stage3_num_channels,
            name="tr2")
        self.st3 = Stage(
            num_channels=self.stage3_num_channels,
            num_modules=self.stage3_num_modules,
            num_blocks=self.stage3_num_blocks,
            num_filters=self.stage3_num_channels,
            has_se=self.has_se,
            name="st3")

        self.tr3 = TransitionLayer(
            in_channels=self.stage3_num_channels,
            out_channels=self.stage4_num_channels,
            name="tr3")
        self.st4 = Stage(
            num_channels=self.stage4_num_channels,
            num_modules=self.stage4_num_modules,
            num_blocks=self.stage4_num_blocks,
            num_filters=self.stage4_num_channels,
            has_se=self.has_se,
            name="st4")

    def forward(self, x, label=None, mode='train'):
        input_shape = x.shape[2:]
        conv1 = self.conv_layer1_1(x)
        conv2 = self.conv_layer1_2(conv1)

        la1 = self.la1(conv2)

        tr1 = self.tr1([la1])
        st2 = self.st2(tr1)

        tr2 = self.tr2(st2)
        st3 = self.st3(tr2)

        tr3 = self.tr3(st3)
        st4 = self.st4(tr3)

        x0_h, x0_w = st4[0].shape[2:]
        x1 = fluid.layers.resize_bilinear(st4[1], out_shape=(x0_h, x0_w))
        x2 = fluid.layers.resize_bilinear(st4[2], out_shape=(x0_h, x0_w))
        x3 = fluid.layers.resize_bilinear(st4[3], out_shape=(x0_h, x0_w))
        x = fluid.layers.concat([st4[0], x1, x2, x3], axis=1)

        return x

class ConvBNLayer(fluid.dygraph.Layer):
    def __init__(self,
                 num_channels,
                 num_filters,
                 filter_size,
                 stride=1,
                 groups=1,
                 act="relu",
                 name=None):
        super(ConvBNLayer, self).__init__()

        self._conv = Conv2D(
            num_channels=num_channels,
            num_filters=num_filters,
            filter_size=filter_size,
            stride=stride,
            padding=(filter_size - 1) // 2,
            groups=groups,
            param_attr=ParamAttr(
                initializer=Normal(scale=0.001), name=name + "_weights"),
            bias_attr=False)
        bn_name = name + '_bn'
        self._batch_norm = BatchNorm(
            num_filters,
            weight_attr=ParamAttr(
                name=bn_name + '_scale',
                initializer=fluid.initializer.Constant(1.0)),
            bias_attr=ParamAttr(
                bn_name + '_offset',
                initializer=fluid.initializer.Constant(0.0)))
        self.act = act

    def forward(self, input):
        y = self._conv(input)
        y = self._batch_norm(y)
        if self.act == 'relu':
            y = fluid.layers.relu(y)
        return y

class Layer1(fluid.dygraph.Layer):
    def __init__(self,
                 num_channels,
                 num_filters,
                 num_blocks,
                 has_se=False,
                 name=None):
        super(Layer1, self).__init__()

        self.bottleneck_block_list = []

        for i in range(num_blocks):
            bottleneck_block = self.add_sublayer(
                "bb_{}_{}".format(name, i + 1),
                BottleneckBlock(
                    num_channels=num_channels if i == 0 else num_filters * 4,
                    num_filters=num_filters,
                    has_se=has_se,
                    stride=1,
                    downsample=True if i == 0 else False,
                    name=name + '_' + str(i + 1)))
            self.bottleneck_block_list.append(bottleneck_block)

    def forward(self, input):
        conv = input
        for block_func in self.bottleneck_block_list:
            conv = block_func(conv)
        return conv

class TransitionLayer(fluid.dygraph.Layer):
    def __init__(self, in_channels, out_channels, name=None):
        super(TransitionLayer, self).__init__()

        num_in = len(in_channels)
        num_out = len(out_channels)
        self.conv_bn_func_list = []
        for i in range(num_out):
            residual = None
            if i < num_in:
                if in_channels[i] != out_channels[i]:
                    residual = self.add_sublayer(
                        "transition_{}_layer_{}".format(name, i + 1),
                        ConvBNLayer(
                            num_channels=in_channels[i],
                            num_filters=out_channels[i],
                            filter_size=3,
                            name=name + '_layer_' + str(i + 1)))
            else:
                residual = self.add_sublayer(
                    "transition_{}_layer_{}".format(name, i + 1),
                    ConvBNLayer(
                        num_channels=in_channels[-1],
                        num_filters=out_channels[i],
                        filter_size=3,
                        stride=2,
                        name=name + '_layer_' + str(i + 1)))
            self.conv_bn_func_list.append(residual)

    def forward(self, input):
        outs = []
        for idx, conv_bn_func in enumerate(self.conv_bn_func_list):
            if conv_bn_func is None:
                outs.append(input[idx])
            else:
                if idx < len(input):
                    outs.append(conv_bn_func(input[idx]))
                else:
                    outs.append(conv_bn_func(input[-1]))
        return outs

class Branches(fluid.dygraph.Layer):
    def __init__(self,
                 num_blocks,
                 in_channels,
                 out_channels,
                 has_se=False,
                 name=None):
        super(Branches, self).__init__()

        self.basic_block_list = []

        for i in range(len(out_channels)):
            self.basic_block_list.append([])
            for j in range(num_blocks[i]):
                in_ch = in_channels[i] if j == 0 else out_channels[i]
                basic_block_func = self.add_sublayer(
                    "bb_{}_branch_layer_{}_{}".format(name, i + 1, j + 1),
                    BasicBlock(
                        num_channels=in_ch,
                        num_filters=out_channels[i],
                        has_se=has_se,
                        name=name + '_branch_layer_' + str(i + 1) + '_' +
                        str(j + 1)))
                self.basic_block_list[i].append(basic_block_func)

    def forward(self, inputs):
        outs = []
        for idx, input in enumerate(inputs):
            conv = input
            for basic_block_func in self.basic_block_list[idx]:
                conv = basic_block_func(conv)
            outs.append(conv)
        return outs

class BottleneckBlock(fluid.dygraph.Layer):
    def __init__(self,
                 num_channels,
                 num_filters,
                 has_se,
                 stride=1,
                 downsample=False,
                 name=None):
        super(BottleneckBlock, self).__init__()

        self.has_se = has_se
        self.downsample = downsample

        self.conv1 = ConvBNLayer(
            num_channels=num_channels,
            num_filters=num_filters,
            filter_size=1,
            act="relu",
            name=name + "_conv1",
        )
        self.conv2 = ConvBNLayer(
            num_channels=num_filters,
            num_filters=num_filters,
            filter_size=3,
            stride=stride,
            act="relu",
            name=name + "_conv2")
        self.conv3 = ConvBNLayer(
            num_channels=num_filters,
            num_filters=num_filters * 4,
            filter_size=1,
            act=None,
            name=name + "_conv3")

        if self.downsample:
            self.conv_down = ConvBNLayer(
                num_channels=num_channels,
                num_filters=num_filters * 4,
                filter_size=1,
                act=None,
                name=name + "_downsample")

        if self.has_se:
            self.se = SELayer(
                num_channels=num_filters * 4,
                num_filters=num_filters * 4,
                reduction_ratio=16,
                name=name + '_fc')

    def forward(self, input):
        residual = input
        conv1 = self.conv1(input)
        conv2 = self.conv2(conv1)
        conv3 = self.conv3(conv2)

        if self.downsample:
            residual = self.conv_down(input)

        if self.has_se:
            conv3 = self.se(conv3)

        y = fluid.layers.elementwise_add(x=conv3, y=residual, act="relu")
        return y

class BasicBlock(fluid.dygraph.Layer):
    def __init__(self,
                 num_channels,
                 num_filters,
                 stride=1,
                 has_se=False,
                 downsample=False,
                 name=None):
        super(BasicBlock, self).__init__()

        self.has_se = has_se
        self.downsample = downsample

        self.conv1 = ConvBNLayer(
            num_channels=num_channels,
            num_filters=num_filters,
            filter_size=3,
            stride=stride,
            act="relu",
            name=name + "_conv1")
        self.conv2 = ConvBNLayer(
            num_channels=num_filters,
            num_filters=num_filters,
            filter_size=3,
            stride=1,
            act=None,
            name=name + "_conv2")

        if self.downsample:
            self.conv_down = ConvBNLayer(
                num_channels=num_channels,
                num_filters=num_filters * 4,
                filter_size=1,
                act="relu",
                name=name + "_downsample")

        if self.has_se:
            self.se = SELayer(
                num_channels=num_filters,
                num_filters=num_filters,
                reduction_ratio=16,
                name=name + '_fc')

    def forward(self, input):
        residual = input
        conv1 = self.conv1(input)
        conv2 = self.conv2(conv1)

        if self.downsample:
            residual = self.conv_down(input)

        if self.has_se:
            conv2 = self.se(conv2)

        y = fluid.layers.elementwise_add(x=conv2, y=residual, act="relu")
        return y

class SELayer(fluid.dygraph.Layer):
    def __init__(self, num_channels, num_filters, reduction_ratio, name=None):
        super(SELayer, self).__init__()

        self.pool2d_gap = Pool2D(pool_type='avg', global_pooling=True)

        self._num_channels = num_channels

        med_ch = int(num_channels / reduction_ratio)
        stdv = 1.0 / math.sqrt(num_channels * 1.0)
        self.squeeze = Linear(
            num_channels,
            med_ch,
            act="relu",
            param_attr=ParamAttr(
                initializer=fluid.initializer.Uniform(-stdv, stdv),
                name=name + "_sqz_weights"),
            bias_attr=ParamAttr(name=name + '_sqz_offset'))

        stdv = 1.0 / math.sqrt(med_ch * 1.0)
        self.excitation = Linear(
            med_ch,
            num_filters,
            act="sigmoid",
            param_attr=ParamAttr(
                initializer=fluid.initializer.Uniform(-stdv, stdv),
                name=name + "_exc_weights"),
            bias_attr=ParamAttr(name=name + '_exc_offset'))

    def forward(self, input):
        pool = self.pool2d_gap(input)
        pool = fluid.layers.reshape(pool, shape=[-1, self._num_channels])
        squeeze = self.squeeze(pool)
        excitation = self.excitation(squeeze)
        excitation = fluid.layers.reshape(
            excitation, shape=[-1, self._num_channels, 1, 1])
        out = input * excitation
        return out

class Stage(fluid.dygraph.Layer):
    def __init__(self,
                 num_channels,
                 num_modules,
                 num_blocks,
                 num_filters,
                 has_se=False,
                 multi_scale_output=True,
                 name=None):
        super(Stage, self).__init__()

        self._num_modules = num_modules

        self.stage_func_list = []
        for i in range(num_modules):
            if i == num_modules - 1 and not multi_scale_output:
                stage_func = self.add_sublayer(
                    "stage_{}_{}".format(name, i + 1),
                    HighResolutionModule(
                        num_channels=num_channels,
                        num_blocks=num_blocks,
                        num_filters=num_filters,
                        has_se=has_se,
                        multi_scale_output=False,
                        name=name + '_' + str(i + 1)))
            else:
                stage_func = self.add_sublayer(
                    "stage_{}_{}".format(name, i + 1),
                    HighResolutionModule(
                        num_channels=num_channels,
                        num_blocks=num_blocks,
                        num_filters=num_filters,
                        has_se=has_se,
                        name=name + '_' + str(i + 1)))

            self.stage_func_list.append(stage_func)

    def forward(self, input):
        out = input
        for idx in range(self._num_modules):
            out = self.stage_func_list[idx](out)
        return out

class HighResolutionModule(fluid.dygraph.Layer):
    def __init__(self,
                 num_channels,
                 num_blocks,
                 num_filters,
                 has_se=False,
                 multi_scale_output=True,
                 name=None):
        super(HighResolutionModule, self).__init__()

        self.branches_func = Branches(
            num_blocks=num_blocks,
            in_channels=num_channels,
            out_channels=num_filters,
            has_se=has_se,
            name=name)

        self.fuse_func = FuseLayers(
            in_channels=num_filters,
            out_channels=num_filters,
            multi_scale_output=multi_scale_output,
            name=name)

    def forward(self, input):
        out = self.branches_func(input)
        out = self.fuse_func(out)
        return out

class FuseLayers(fluid.dygraph.Layer):
    def __init__(self,
                 in_channels,
                 out_channels,
                 multi_scale_output=True,
                 name=None):
        super(FuseLayers, self).__init__()

        self._actual_ch = len(in_channels) if multi_scale_output else 1
        self._in_channels = in_channels

        self.residual_func_list = []
        for i in range(self._actual_ch):
            for j in range(len(in_channels)):
                residual_func = None
                if j > i:
                    residual_func = self.add_sublayer(
                        "residual_{}_layer_{}_{}".format(name, i + 1, j + 1),
                        ConvBNLayer(
                            num_channels=in_channels[j],
                            num_filters=out_channels[i],
                            filter_size=1,
                            stride=1,
                            act=None,
                            name=name + '_layer_' + str(i + 1) + '_' +
                            str(j + 1)))
                    self.residual_func_list.append(residual_func)
                elif j < i:
                    pre_num_filters = in_channels[j]
                    for k in range(i - j):
                        if k == i - j - 1:
                            residual_func = self.add_sublayer(
                                "residual_{}_layer_{}_{}_{}".format(
                                    name, i + 1, j + 1, k + 1),
                                ConvBNLayer(
                                    num_channels=pre_num_filters,
                                    num_filters=out_channels[i],
                                    filter_size=3,
                                    stride=2,
                                    act=None,
                                    name=name + '_layer_' + str(i + 1) + '_' +
                                    str(j + 1) + '_' + str(k + 1)))
                            pre_num_filters = out_channels[i]
                        else:
                            residual_func = self.add_sublayer(
                                "residual_{}_layer_{}_{}_{}".format(
                                    name, i + 1, j + 1, k + 1),
                                ConvBNLayer(
                                    num_channels=pre_num_filters,
                                    num_filters=out_channels[j],
                                    filter_size=3,
                                    stride=2,
                                    act="relu",
                                    name=name + '_layer_' + str(i + 1) + '_' +
                                    str(j + 1) + '_' + str(k + 1)))
                            pre_num_filters = out_channels[j]
                        self.residual_func_list.append(residual_func)

    def forward(self, input):
        outs = []
        residual_func_idx = 0
        for i in range(self._actual_ch):
            residual = input[i]
            residual_shape = residual.shape[-2:]
            for j in range(len(self._in_channels)):
                if j > i:
                    y = self.residual_func_list[residual_func_idx](input[j])
                    residual_func_idx += 1

                    y = fluid.layers.resize_bilinear(
                        input=y, out_shape=residual_shape)
                    residual = fluid.layers.elementwise_add(
                        x=residual, y=y, act=None)
                elif j < i:
                    y = input[j]
                    for k in range(i - j):
                        y = self.residual_func_list[residual_func_idx](y)
                        residual_func_idx += 1

                    residual = fluid.layers.elementwise_add(
                        x=residual, y=y, act=None)

            layer_helper = LayerHelper(self.full_name(), act='relu')
            residual = layer_helper.append_activation(residual)
            outs.append(residual)

        return outs

class LastClsOut(fluid.dygraph.Layer):
    def __init__(self,
                 num_channel_list,
                 has_se,
                 num_filters_list=[32, 64, 128, 256],
                 name=None):
        super(LastClsOut, self).__init__()

        self.func_list = []
        for idx in range(len(num_channel_list)):
            func = self.add_sublayer(
                "conv_{}_conv_{}".format(name, idx + 1),
                BottleneckBlock(
                    num_channels=num_channel_list[idx],
                    num_filters=num_filters_list[idx],
                    has_se=has_se,
                    downsample=True,
                    name=name + 'conv_' + str(idx + 1)))
            self.func_list.append(func)

    def forward(self, inputs):
        outs = []
        for idx, input in enumerate(inputs):
            out = self.func_list[idx](input)
            outs.append(out)
        return outs

@manager.BACKBONES.add_component
def HRNet_W18_Small_V1(**kwargs):
    model = HRNet(
        stage1_num_modules=1,
        stage1_num_blocks=[1],
        stage1_num_channels=[32],
        stage2_num_modules=1,
        stage2_num_blocks=[2, 2],
        stage2_num_channels=[16, 32],
        stage3_num_modules=1,
        stage3_num_blocks=[2, 2, 2],
        stage3_num_channels=[16, 32, 64],
        stage4_num_modules=1,
        stage4_num_blocks=[2, 2, 2, 2],
        stage4_num_channels=[16, 32, 64, 128],
        **kwargs)
    return model

@manager.BACKBONES.add_component
def HRNet_W18_Small_V2(**kwargs):
    model = HRNet(
        stage1_num_modules=1,
        stage1_num_blocks=[2],
        stage1_num_channels=[64],
        stage2_num_modules=1,
        stage2_num_blocks=[2, 2],
        stage2_num_channels=[18, 36],
        stage3_num_modules=1,
        stage3_num_blocks=[2, 2, 2],
        stage3_num_channels=[18, 36, 72],
        stage4_num_modules=1,
        stage4_num_blocks=[2, 2, 2, 2],
        stage4_num_channels=[18, 36, 72, 144],
        **kwargs)
    return model

@manager.BACKBONES.add_component
def HRNet_W18(**kwargs):
    model = HRNet(
        stage1_num_modules=1,
        stage1_num_blocks=[4],
        stage1_num_channels=[64],
        stage2_num_modules=1,
        stage2_num_blocks=[4, 4],
        stage2_num_channels=[18, 36],
        stage3_num_modules=4,
        stage3_num_blocks=[4, 4, 4],
        stage3_num_channels=[18, 36, 72],
        stage4_num_modules=3,
        stage4_num_blocks=[4, 4, 4, 4],
        stage4_num_channels=[18, 36, 72, 144],
        **kwargs)
    return model

@manager.BACKBONES.add_component
def HRNet_W30(**kwargs):
    model = HRNet(
        stage1_num_modules=1,
        stage1_num_blocks=[4],
        stage1_num_channels=[64],
        stage2_num_modules=1,
        stage2_num_blocks=[4, 4],
        stage2_num_channels=[30, 60],
        stage3_num_modules=4,
        stage3_num_blocks=[4, 4, 4],
        stage3_num_channels=[30, 60, 120],
        stage4_num_modules=3,
        stage4_num_blocks=[4, 4, 4, 4],
        stage4_num_channels=[30, 60, 120, 240],
        **kwargs)
    return model

@manager.BACKBONES.add_component
def HRNet_W32(**kwargs):
    model = HRNet(
        stage1_num_modules=1,
        stage1_num_blocks=[4],
        stage1_num_channels=[64],
        stage2_num_modules=1,
        stage2_num_blocks=[4, 4],
        stage2_num_channels=[32, 64],
        stage3_num_modules=4,
        stage3_num_blocks=[4, 4, 4],
        stage3_num_channels=[32, 64, 128],
        stage4_num_modules=3,
        stage4_num_blocks=[4, 4, 4, 4],
        stage4_num_channels=[32, 64, 128, 256],
        **kwargs)
    return model

@manager.BACKBONES.add_component
def HRNet_W40(**kwargs):
    model = HRNet(
        stage1_num_modules=1,
        stage1_num_blocks=[4],
        stage1_num_channels=[64],
        stage2_num_modules=1,
        stage2_num_blocks=[4, 4],
        stage2_num_channels=[40, 80],
        stage3_num_modules=4,
        stage3_num_blocks=[4, 4, 4],
        stage3_num_channels=[40, 80, 160],
        stage4_num_modules=3,
        stage4_num_blocks=[4, 4, 4, 4],
        stage4_num_channels=[40, 80, 160, 320],
        **kwargs)
    return model

@manager.BACKBONES.add_component
def HRNet_W44(**kwargs):
    model = HRNet(
        stage1_num_modules=1,
        stage1_num_blocks=[4],
        stage1_num_channels=[64],
        stage2_num_modules=1,
        stage2_num_blocks=[4, 4],
        stage2_num_channels=[44, 88],
        stage3_num_modules=4,
        stage3_num_blocks=[4, 4, 4],
        stage3_num_channels=[44, 88, 176],
        stage4_num_modules=3,
        stage4_num_blocks=[4, 4, 4, 4],
        stage4_num_channels=[44, 88, 176, 352],
        **kwargs)
    return model

@manager.BACKBONES.add_component
def HRNet_W48(**kwargs):
    model = HRNet(
        stage1_num_modules=1,
        stage1_num_blocks=[4],
        stage1_num_channels=[64],
        stage2_num_modules=1,
        stage2_num_blocks=[4, 4],
        stage2_num_channels=[48, 96],
        stage3_num_modules=4,
        stage3_num_blocks=[4, 4, 4],
        stage3_num_channels=[48, 96, 192],
        stage4_num_modules=3,
        stage4_num_blocks=[4, 4, 4, 4],
        stage4_num_channels=[48, 96, 192, 384],
        **kwargs)
    return model

@manager.BACKBONES.add_component
def HRNet_W60(**kwargs):
    model = HRNet(
        stage1_num_modules=1,
        stage1_num_blocks=[4],
        stage1_num_channels=[64],
        stage2_num_modules=1,
        stage2_num_blocks=[4, 4],
        stage2_num_channels=[60, 120],
        stage3_num_modules=4,
        stage3_num_blocks=[4, 4, 4],
        stage3_num_channels=[60, 120, 240],
        stage4_num_modules=3,
        stage4_num_blocks=[4, 4, 4, 4],
        stage4_num_channels=[60, 120, 240, 480],
        **kwargs)
    return model

@manager.BACKBONES.add_component
def HRNet_W64(**kwargs):
    model = HRNet(
        stage1_num_modules=1,
        stage1_num_blocks=[4],
        stage1_num_channels=[64],
        stage2_num_modules=1,
        stage2_num_blocks=[4, 4],
        stage2_num_channels=[64, 128],
        stage3_num_modules=4,
        stage3_num_blocks=[4, 4, 4],
        stage3_num_channels=[64, 128, 256],
        stage4_num_modules=3,
        stage4_num_blocks=[4, 4, 4, 4],
        stage4_num_channels=[64, 128, 256, 512],
        **kwargs)
    return model


"""change text field

Revision ID: ee8bc685d824
Revises: 9b0da34cd0dc
Create Date: 2023-07-18 11:49:04.006166

"""
import sqlalchemy as sa
from alembic import op

# revision identifiers, used by Alembic.
revision = "ee8bc685d824"
down_revision = "9b0da34cd0dc"
branch_labels = None
depends_on = None

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.create_unique_constraint(None, "posts", ["text"])
    # ### end Alembic commands ###

def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_constraint(None, "posts", type_="unique")
    # ### end Alembic commands ###