# coding: utf-8
import bpy
from . import vertexarray
from .. import bl
from pymeshio import englishmap

class Morph(object):
    __slots__=['name', 'type', 'offsets']
    def __init__(self, name, type):
        self.name=name
        self.type=type
        self.offsets=[]

    def add(self, index, offset):
        self.offsets.append((index, offset))

    def sort(self):
        self.offsets.sort(key=lambda e: e[0])

    def __str__(self):
        return "<Morph %s>" % self.name

class SSS(object):
    def __init__(self):
        self.use=1

class DefaultMaterial(dict):
    def __init__(self):
        self.name='default'
        # diffuse
        self.diffuse_color=[1, 1, 1]
        self.alpha=1
        # specular
        self.specular_toon_size=0
        self.specular_hardness=5
        self.specular_color=[1, 1, 1]
        # ambient
        self.mirror_color=[0, 0, 0]
        # flag
        self.subsurface_scattering=SSS()
        # texture
        self.texture_slots=[]

class OneSkinMesh(object):
    __slots__=['vertexArray', 'morphList', 'rigidbodies', 'constraints', 'armatureObj']
    def __init__(self):
        self.vertexArray=vertexarray.VertexArray()
        self.morphList=[]
        self.rigidbodies=[]
        self.constraints=[]
        self.armatureObj=None

    def __str__(self):
        return "<OneSkinMesh %s, morph:%d>" % (
                self.vertexArray,
                len(self.morphList))

    def build(self, node):
        ############################################################
        # search armature modifier
        ############################################################
        for m in node.o.modifiers:
            if bl.modifier.isType(m, 'ARMATURE'):
                armatureObj=bl.modifier.getArmatureObject(m)
                if not self.armatureObj:
                    self.armatureObj=armatureObj
                elif self.armatureObj!=armatureObj:
                    print("warning! found multiple armature. ignored.",
                            armatureObj.name)

        if node.o.type.upper()=='MESH':
            self.addMesh(node.o)

        for child in node.children:
            self.build(child)

    def addMesh(self, obj):
        if not bl.object.isVisible(obj):
            return
        self.__mesh(obj)
        self.__rigidbody(obj)
        self.__constraint(obj)

    def __getWeightMap(self, obj, mesh):
        # bone weight
        weightMap={}
        secondWeightMap={}
        def setWeight(i, name, w):
            if w>0:
                if i in weightMap:
                    if i in secondWeightMap:
                        # 上位２つのweightを採用する
                        if w<secondWeightMap[i][1]:
                            pass
                        elif w<weightMap[i][1]:
                            # ２つ目を入れ替え
                            secondWeightMap[i]=(name, w)
                        else:
                            # １つ目を入れ替え
                            weightMap[i]=(name, w)
                    else:
                        if w>weightMap[i][1]:
                            # 多い方をweightMapに
                            secondWeightMap[i]=weightMap[i]
                            weightMap[i]=(name, w)
                        else:
                            secondWeightMap[i]=(name, w)
                else:
                    weightMap[i]=(name, w)

        # ToDo bone weightと関係ないvertex groupを除外する
        for i, v in enumerate(mesh.vertices):
            if len(v.groups)>0:
                for g in v.groups:
                    setWeight(i, obj.vertex_groups[g.group].name, g.weight)
            else:
                try:
                    setWeight(i, obj.vertex_groups[0].name, 1)
                except:
                    # no vertex_groups
                    pass

        # 合計値が1になるようにする
        for i in range(len(mesh.vertices)):
            if i in secondWeightMap:
                secondWeightMap[i]=(secondWeightMap[i][0], 1.0-weightMap[i][1])
            elif i in weightMap:
                weightMap[i]=(weightMap[i][0], 1.0)
                secondWeightMap[i]=("", 0)
            else:
                print("no weight vertex")
                weightMap[i]=("", 0)
                secondWeightMap[i]=("", 0)

        return weightMap, secondWeightMap

    def __processFaces(self, obj_name, mesh, weightMap, secondWeightMap):
        default_material=DefaultMaterial()
        # 各面の処理
        for i, face in enumerate(mesh.tessfaces):
            faceVertexCount=bl.face.getVertexCount(face)
            try:
                material=mesh.materials[bl.face.getMaterialIndex(face)]
            except IndexError as e:
                material=default_material
            v=[mesh.vertices[index] for index in bl.face.getVertices(face)]
            uv=bl.mesh.getFaceUV(
                    mesh, i, face, bl.face.getVertexCount(face))

            if bl.face.isSmooth(face):
                if faceVertexCount==3:
                    self.__addFaceTriangleSmooth(
                            obj_name, material, v, uv,
                            weightMap, secondWeightMap
                            )
                elif faceVertexCount==4:
                    self.__addFaceQuadrangleSmooth(
                            obj_name, material, v, uv,
                            weightMap, secondWeightMap
                            )
            else:
                if faceVertexCount==3:
                    self.__addFaceTriangleSolid(
                            obj_name, material, v, uv,
                            bl.face.getNormal(face),
                            weightMap, secondWeightMap
                            )
                elif faceVertexCount==4:
                    self.__addFaceQuadrangleSolid(
                            obj_name, material, v, uv,
                            bl.face.getNormal(face),
                            weightMap, secondWeightMap
                            )

    def __addFaceTriangleSmooth(self, obj_name, material, v, uv,
            weightMap, secondWeightMap):
        self.vertexArray.addTriangle(
                obj_name, material.name,
                v[0].index,
                v[1].index,
                v[2].index,
                v[0].co,
                v[1].co,
                v[2].co,
                bl.vertex.getNormal(v[0]),
                bl.vertex.getNormal(v[1]),
                bl.vertex.getNormal(v[2]),
                uv[0],
                uv[1],
                uv[2],
                weightMap[v[0].index][0],
                weightMap[v[1].index][0],
                weightMap[v[2].index][0],
                secondWeightMap[v[0].index][0],
                secondWeightMap[v[1].index][0],
                secondWeightMap[v[2].index][0],
                weightMap[v[0].index][1],
                weightMap[v[1].index][1],
                weightMap[v[2].index][1]
                )

    def __addFaceQuadrangleSmooth(self, obj_name, material, v, uv,
            weightMap, secondWeightMap):
        self.vertexArray.addTriangle(
                obj_name, material.name,
                v[0].index,
                v[1].index,
                v[2].index,
                v[0].co,
                v[1].co,
                v[2].co,
                bl.vertex.getNormal(v[0]),
                bl.vertex.getNormal(v[1]),
                bl.vertex.getNormal(v[2]),
                uv[0],
                uv[1],
                uv[2],
                weightMap[v[0].index][0],
                weightMap[v[1].index][0],
                weightMap[v[2].index][0],
                secondWeightMap[v[0].index][0],
                secondWeightMap[v[1].index][0],
                secondWeightMap[v[2].index][0],
                weightMap[v[0].index][1],
                weightMap[v[1].index][1],
                weightMap[v[2].index][1]
                )
        self.vertexArray.addTriangle(
                obj_name, material.name,
                v[2].index,
                v[3].index,
                v[0].index,
                v[2].co,
                v[3].co,
                v[0].co,
                bl.vertex.getNormal(v[2]),
                bl.vertex.getNormal(v[3]),
                bl.vertex.getNormal(v[0]),
                uv[2],
                uv[3],
                uv[0],
                weightMap[v[2].index][0],
                weightMap[v[3].index][0],
                weightMap[v[0].index][0],
                secondWeightMap[v[2].index][0],
                secondWeightMap[v[3].index][0],
                secondWeightMap[v[0].index][0],
                weightMap[v[2].index][1],
                weightMap[v[3].index][1],
                weightMap[v[0].index][1]
                )

    def __addFaceTriangleSolid(self, obj_name, material, v, uv, normal,
            weightMap, secondWeightMap):
        # flip triangle
        self.vertexArray.addTriangle(
                obj_name, material.name,
                v[0].index,
                v[1].index,
                v[2].index,
                v[0].co,
                v[1].co,
                v[2].co,
                normal,
                normal,
                normal,
                uv[0],
                uv[1],
                uv[2],
                weightMap[v[0].index][0],
                weightMap[v[1].index][0],
                weightMap[v[2].index][0],
                secondWeightMap[v[0].index][0],
                secondWeightMap[v[1].index][0],
                secondWeightMap[v[2].index][0],
                weightMap[v[0].index][1],
                weightMap[v[1].index][1],
                weightMap[v[2].index][1]
                )

    def __addFaceQuadrangleSolid(self, obj_name, material, v, uv, normal,
            weightMap, secondWeightMap):
        self.vertexArray.addTriangle(
                obj_name, material.name,
                v[0].index,
                v[1].index,
                v[2].index,
                v[0].co,
                v[1].co,
                v[2].co,
                normal,
                normal,
                normal,
                uv[0],
                uv[1],
                uv[2],
                weightMap[v[0].index][0],
                weightMap[v[1].index][0],
                weightMap[v[2].index][0],
                secondWeightMap[v[0].index][0],
                secondWeightMap[v[1].index][0],
                secondWeightMap[v[2].index][0],
                weightMap[v[0].index][1],
                weightMap[v[1].index][1],
                weightMap[v[2].index][1]
                )
        self.vertexArray.addTriangle(
                obj_name, material.name,
                v[2].index,
                v[3].index,
                v[0].index,
                v[2].co,
                v[3].co,
                v[0].co,
                normal,
                normal,
                normal,
                uv[2],
                uv[3],
                uv[0],
                weightMap[v[2].index][0],
                weightMap[v[3].index][0],
                weightMap[v[0].index][0],
                secondWeightMap[v[2].index][0],
                secondWeightMap[v[3].index][0],
                secondWeightMap[v[0].index][0],
                weightMap[v[2].index][1],
                weightMap[v[3].index][1],
                weightMap[v[0].index][1]
                )

    def __mesh(self, obj):
        if bl.RIGID_SHAPE_TYPE in obj:
            return
        if bl.CONSTRAINT_A in obj:
            return

        bl.message("export: %s" % obj.name)

        # メッシュのコピーを生成してオブジェクトの行列を適用する
        copyMesh, copyObj=bl.object.duplicate(obj)
        copyObj.name="tmp_object"
        if len(copyMesh.vertices)>0:
            # apply transform
            copyMesh.transform(obj.matrix_world)
            if bl.object.hasShapeKey(copyObj):
                matrix=obj.matrix_world
                for key in copyMesh.shape_keys.key_blocks:
                    for point in key.data:
                        point.co=matrix*point.co
            copyMesh.calc_normals()

            # apply modifier
            for m in [m for m in copyObj.modifiers]:
                if m.type=='SOLIDFY':
                    continue
                elif m.type=='ARMATURE':
                    continue
                elif m.type=='MIRROR':
                    bpy.ops.object.modifier_apply(modifier=m.name)
                else:
                    print(m.type)

            # fix empty tessfaces(from blender2.66?)
            copyMesh.update(calc_tessface=True)

            weightMap, secondWeightMap=self.__getWeightMap(copyObj, copyMesh)
            self.__processFaces(obj.name, copyMesh, weightMap, secondWeightMap)
            self.__weights(copyObj, copyMesh, obj.name)
            self.__skin(copyObj, obj.name)
        bl.object.delete(copyObj)

    def createEmptyBasicSkin(self):
        self.__getOrCreateMorph('base', 0)

    def __skin(self, obj, obj_name):
        if not bl.object.hasShapeKey(obj):
            return

        indexRelativeMap={}
        blenderMesh=bl.object.getData(obj)
        baseMorph=None

        # shape keys
        vg=bl.object.getVertexGroup(obj, bl.MMD_SHAPE_GROUP_NAME)
        if len(vg)==0:
            vg=list(range(len(blenderMesh.vertices)))

        # base
        used=set()
        for b in bl.object.getShapeKeys(obj):
            if b.name==bl.BASE_SHAPE_NAME:
                baseMorph=self.__getOrCreateMorph('base', 0)
                basis=b

                relativeIndex=len(baseMorph.offsets)
                for index in vg:
                    v=bl.shapekey.getByIndex(b, index)
                    pos=[v[0], v[1], v[2]]

                    indices=self.vertexArray.getMappedIndex(obj_name, index)
                    for attribute, i in indices.items():
                        if i in used:
                            continue
                        used.add(i)

                        baseMorph.add(i, pos)
                        indexRelativeMap[i]=relativeIndex
                        relativeIndex+=1

                break
        assert(basis)
        #print(basis.name, len(baseMorph.offsets))

        if len(baseMorph.offsets)==0:
            return

        # shape keys
        for b in bl.object.getShapeKeys(obj):
            if b.name==bl.BASE_SHAPE_NAME:
                continue

            morph=self.__getOrCreateMorph(b.name, 4)
            used=set()
            for index, src, dst in zip(
                    range(len(blenderMesh.vertices)),
                    bl.shapekey.get(basis),
                    bl.shapekey.get(b)):
                offset=[dst[0]-src[0], dst[1]-src[1], dst[2]-src[2]]
                if offset[0]==0 and offset[1]==0 and offset[2]==0:
                    continue
                if index in vg:
                    indices=self.vertexArray.getMappedIndex(obj_name, index)
                    for attribute, i in indices.items():
                        if i in used:
                            continue
                        used.add(i)
                        morph.add(indexRelativeMap[i], offset)
            assert(len(morph.offsets)<=len(baseMorph.offsets))

        # sort skinmap
        original=self.morphList[:]
        def getIndex(morph):
            for i, v in enumerate(englishmap.skinMap):
                if v[0]==morph.name:
                    return i
            #print(morph)
            return len(englishmap.skinMap)
        self.morphList.sort(key=getIndex)

    def __rigidbody(self, obj):
        if not bl.RIGID_SHAPE_TYPE in obj:
            return
        self.rigidbodies.append(obj)

    def __constraint(self, obj):
        if not bl.CONSTRAINT_A in obj:
            return
        self.constraints.append(obj)

    def __getOrCreateMorph(self, name, type):
        for m in self.morphList:
            if m.name==name:
                return m
        m=Morph(name, type)
        self.morphList.append(m)
        return m

    def getVertexCount(self):
        return len(self.vertexArray.positions)

    def __weights(self, obj, mesh, obj_name):
        for v in mesh.vertices:
            for i in self.vertexArray.getMappedIndex2(obj_name, v.index):
                ext_w=self.vertexArray.ext_weight[i]
                ext_w.entries.extend( filter( lambda ent: not ent[0].startswith("_"), \
                    ((obj.vertex_groups[vg.group].name, vg.weight) for vg in v.groups) ) )


import json
import os
from datetime import datetime
from typing import Optional, Union

from aws_cdk import (
    aws_lambda,
    aws_secretsmanager as secretsmanager,
    aws_rds as rds,
    aws_ec2 as ec2,
    Stack,
    CustomResource,
    custom_resources,
)

from constructs import Construct

class BootstrappedDb(Construct):
    """
    Given an RDS database, connect to DB and create a database, user, and
    password
    """

    def __init__(
        self,
        scope: Construct,
        id: str,
        db: Union[rds.DatabaseInstance, rds.DatabaseInstanceFromSnapshot],
        new_dbname: str,
        new_username: str,
        secrets_prefix: str,
        handler: Union[aws_lambda.Function, aws_lambda.SingletonFunction],
        db_engine: Optional[str] = None,
    ) -> None:
        super().__init__(scope, id)

        if not db.secret:
            raise ValueError("`db` value must have a secret attached.")

        if not db.engine and not db_engine:
            raise ValueError(
                "Either the provided `db` must have access to its `engine` property or"
                " you must provide a value for `db_engine` explicitly."
            )

        self.secret = secretsmanager.Secret(
            self,
            id,
            secret_name=os.path.join(
                secrets_prefix, id.replace(" ", "_"), self.node.id[-8:]
            ),
            generate_secret_string=secretsmanager.SecretStringGenerator(
                secret_string_template=json.dumps(
                    {
                        "dbname": new_dbname,
                        "engine": db_engine if db_engine else db.engine.engine_type,  # type: ignore
                        "port": db.instance_endpoint.port,
                        "host": db.instance_endpoint.hostname,
                        "username": new_username,
                    },
                ),
                generate_string_key="password",
                exclude_punctuation=True,
            ),
            description=f"Deployed by {Stack.of(self).stack_name}",
        )

        self.provider = custom_resources.Provider(
            scope, "BootstrapProvider", on_event_handler=handler
        )

        self.resource = CustomResource(
            scope=scope,
            id="BootstrapHandlerResource",
            service_token=self.provider.service_token,
            properties={
                "conn_secret_arn": db.secret.secret_arn,
                "new_user_secret_arn": self.secret.secret_arn,
                "version": handler.current_version.version,
            },
        )

        # Allow lambda to...
        # read new user secret
        self.secret.grant_read(handler)
        # read database secret
        db.secret.grant_read(handler)
        # connect to database
        db.connections.allow_from(handler, port_range=ec2.Port.tcp(5432))

    def is_required_by(self, construct: Construct):
        return construct.node.add_dependency(self.resource)


import asyncio
from datetime import datetime

from channels.db import database_sync_to_async
from channels.generic.http import AsyncHttpConsumer
from channels.generic.websocket import AsyncJsonWebsocketConsumer

from .models import Chan, Message

class ChatConsumer(AsyncJsonWebsocketConsumer):
    async def connect(self):
        # print(f'{self.scope=}')
        # print(f'{self.channel_name=}')
        self.room_name = self.scope['url_route']['kwargs']['room_name']
        self.room_group_name = f'room_{self.room_name}'
        await self.set_chan()
        await self.channel_layer.group_add(self.room_group_name, self.channel_name)
        await self.accept()
        for message in await self.get_messages():
            await self.send_json(content={'message': message})

    async def disconnect(self, close_code):
        await self.channel_layer.group_discard(self.room_group_name, self.channel_name)

    async def receive_json(self, content):
        await self.channel_layer.group_send(self.room_group_name, {
            'type': 'chati_message',
            'message': content['message']
        })
        await self.add_message(content['message'])

    async def chati_message(self, event):
        await self.send_json(content={'message': event['message']})

    @database_sync_to_async
    def set_chan(self):
        self.chan = Chan.objects.get_or_create(name=self.room_name)[0]

    @database_sync_to_async
    def add_message(self, message):
        if self.scope['user'].is_authenticated:
            Message.objects.create(chan=self.chan, user=self.scope['user'], message=message)

    @database_sync_to_async
    def get_messages(self):
        return list(str(msg) for msg in Message.objects.filter(chan=self.chan))

class ServerSentEventsConsumer(AsyncHttpConsumer):
    async def handle(self, body):
        await self.send_headers(headers=[
            (b'Cache-Control', b'no-cache'),
            (b'Content-Type', b'text/event-stream'),
            (b'Transfer-Encoding', b'chunked'),
        ])
        while True:
            payload = f'data: {datetime.now():%x %X}\n\n'
            await self.send_body(payload.encode('utf-8'), more_body=True)
            await asyncio.sleep(1)


"""
Provides class for scanning ports

"""
from tools.common.port_scan_task import PortScanTask
from tools.masscan.base import MasscanBase
from tools.nmap.tool import NmapTool
from aucote_cfg import cfg
from utils.exceptions import StopCommandException

class MasscanPorts(PortScanTask):
    """
    Scans for open ports using masscan application

    """

    def __init__(self, tcp=True, udp=True):
        super(MasscanPorts, self).__init__(MasscanBase(), tcp=tcp, udp=udp)

    async def prepare_args(self, nodes):
        """
        Prepare args for command execution

        Args:
            nodes (list): nodes from scanning

        Returns:
            list

        """
        args = list(cfg['tools.masscan.args'])

        rate = self.scan_rate()

        args.extend(['--rate', rate])

        include_ports = NmapTool.list_to_ports_string(tcp=self.tcp and cfg['portdetection.tcp.ports.include'],
                                                      udp=self.udp and cfg['portdetection.udp.ports.include'])

        exclude_ports = NmapTool.list_to_ports_string(tcp=self.tcp and cfg['portdetection.tcp.ports.exclude'],
                                                      udp=self.udp and cfg['portdetection.udp.ports.exclude'])

        if not include_ports:
            raise StopCommandException("No ports for scan")
        args.extend(['--ports', include_ports])

        if exclude_ports:
            args.extend(['--exclude-ports', exclude_ports])

        args.extend([str(node.ip) for node in nodes])

        return args


#! /usr/bin/env python3
# _*_ coding: utf8 _*_

import os
import socket
import sys
from multiprocessing import shared_memory, active_children
from builtins import OSError

sharedMemorySize = 20

def create_tubes(path_tube_1, path_tube_2):
    try:
        os.mkfifo(path_tube_1, 0o0600)
        os.mkfifo(path_tube_2, 0o0600)
    except OSError as error:
        print(error)
        sys.exit("Could not create tubes : ")

def create_shared_memory(name, create):
    try:
        return shared_memory.SharedMemory(name, create, sharedMemorySize)
    except (ValueError, FileExistsError, OSError) as error:
        print(error)
        sys.exit("Could not create shared memory : ")

def create_socket():
    created_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    created_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    return created_socket

def fill_shared_memory(shared_memory, data):
    shared_memory.buf[:sharedMemorySize] = data

def free_communication_system(shared_memory_name, path_tube_1, path_tube_2):
    try:
        if(os.path.exists(path_tube_1)):
            os.unlink(path_tube_1)
    except OSError as error:
        print("Warning : ", error)
    try:
        if(os.path.exists(path_tube_2)):
            os.unlink(path_tube_2)
    except OSError as error:
        print("Warning : ", error)
    try:
        if os.path.exists("/run/shm/leclerc"):
            shared_memory_to_delete = shared_memory.SharedMemory(shared_memory_name)
            shared_memory_to_delete.unlink()
    except OSError as error:
        print("Warning : ", error)

def delete_socket(socket_to_delete):
    socket_to_delete.close()
    del socket_to_delete

def terminate_children():
    active_children_list = active_children()
    for child in active_children_list:
        child.terminate()
    return active_children_list


#Importamos los siguientes módulos que nos serán de utilidad para poder leer la información de la página web
import http.client
import json

headers = {'User-Agent': 'http-client'}

conn = http.client.HTTPSConnection("api.fda.gov") #Establecemos conexión con la página solicitada
conn.request("GET", "/drug/label.json?&limit=10", None, headers) #GET: enviamos solicitud
r1 = conn.getresponse() #Obtenemos la respuesta de la solicitud enviada
if r1.status == 404: #Comprobamos si se ha podido encontrar el recurso correctamente (código 200), o si no se ha podido (código 404)
    print("ERROR, recurso no encontrado.")
    exit(1)
print(r1.status, r1.reason) #Imprimimos el código de estado de la respuesta
datos_raw = r1.read().decode("utf-8") #Convertimos la información para que sea legible
conn.close()

info = json.loads(datos_raw)['results'] #Convertimos la información a json

for elem in range(len(info)): #Con esto iteramos sobre los datos de los 10 medicamentos diferentes que queremos
    print('El id del medicamento es:', info[elem]['id']) #Imprimimos todas las id de los medicamentos


# Gan Ming Liang
# TP063338

# Amadea Lim Yi Wen (teammate)
# TP064038

# Program name: AEGIS (Asian Event General Interface Solution)

import datetime # import datetme from python library for later use

def homepage():
    print("=== Welcome to Asian Event Management Service (AEMS) ===")
    print("Please select your position:")
    print("1. Admin")
    print("2. Customer")
    print("3. Exit")
    option = int(input("Please select an option: "))
    if option == 1:
        adminHome()
    elif option == 2:
        guestOption()
    elif option == 3:
        exitPage()
    else:
        print("Please select a valid option")
        homepage()

def guestOption():
    print("\n>>> What would you like to do? \n")
    print("1. View Category")
    print("2. View Event")
    print("3. Log in as a Member")
    print("4. Register as a Member")
    print("5. Exit")
    choice = int(input("Your choice: "))
    if choice == 1:
        guestViewCategory()
    elif choice == 2:
        guestViewEvent()
    elif choice == 3:
        memberLogin()
    elif choice == 4:
        memberSignup()
    elif choice == 5:
        exitPage()
    else:
        print("option not supported, please try again")
        guestOption()

def adminHome():
    print("=== Please select an option below: ===")
    print("1. Admin Login")
    print("2. Admin Registration")
    print("3. Go Back")
    option = int(input("Your choice: "))
    if option == 1:
        adminLogin()
    elif option == 2:
        adminAuth()
    elif option == 3:
        homepage()
    else:
        print("Please select a valid option")
        adminHome()

def adminAuth():
    code = input("Please enter company referral code: ")
    if code != "AEMS0001":
        print("Incorrect referral code.")
        print("do you want to (1) Try Again, or (2) Go Back ?")
        choice = int(input("Your choice: "))
        if choice == 1:
            adminAuth()
        elif choice == 2:
            adminHome()
        else:
            print("option not supported, returning to homepage...")
            homepage()
    else:
        print("Verification successful!")
        adminSignup()

def adminSignup():
    adminHandler = open("adminList.txt", "r")
    print(">>> Welcome to AEMS admin registration page, please follow the instruction below <<<")
    username = input("Enter a username: ")
    password1 = input("Enter a password: ")
    password2 = input("Confirm your password: ")

    # database
    adminUN = []
    adminPW = []
    for i in adminHandler:
        a,b = i.split(", ")
        b = b.strip()
        adminUN.append(a)
        adminPW.append(b)

    if password1 != password2:
        print("Password does not match, please try again")
        adminSignup()
    elif len(password1) <= 8:
        print("Password must be longer than 8 characters, please try again")
        adminSignup()
    elif username in adminUN:
        print("Username already taken, please try again")
        adminSignup()
    else:
        db = open("adminList.txt", "a")
        db.write(username+", "+password1+"\n")
        print("Registration Successful!")
        db.close()
    adminHandler.close()
    adminHome()

def adminLogin():
    tempList = []
    adminHandler = open("adminList.txt", "r")
    while True:
        print(">>> Admin Login Page <<<")
        adminUN = input("Enter your username: ")
        adminPW = input("Enter your password: ")
        for i in adminHandler:
            tempList.append(i)
        if adminUN + ", " + adminPW + "\n" in tempList:
            print("Login successful!")
            print("Welcome back,", adminUN.capitalize())
            adminOption()
        else:
            print("\n >>> invalid credentials... \n")
            option = input("would you like to sign-up? \n [Y] for admin registration \n [N] to retry login \n Your choice: " )
            if option == "N":
                continue #repeat while loop
            elif option == "Y":
                adminAuth()
            else:
                print("invalid option, returning to homepage...")
                homepage()
        break
    adminHandler.close()

def adminOption():
    print("\n What would you like to do? \n")
    print("1. Add event")
    print("2. Modify event records")
    print("3. Display record details")
    print("4. Search specific record")
    print("5. Exit")
    choice = int(input("Your choice: "))
    if choice == 1:
        addEvent()
    elif choice == 2:
        modifyEvent()
    elif choice == 3:
        print("display options: \n a. Event Category \n b. All Events \n c. Registered Customers \n d. Customer Payment")
        selection = str(input("Enter your option: "))
        if selection == "a":
            adminViewCategory()
        elif selection == "b":
            adminViewEvent()
        elif selection == "c":
            adminViewCustomerList()
        elif selection == "d":
            adminViewCustomerPayment()
        else:
            print("option not supported, try again")
            adminOption()
    elif choice == 4:
        print("Please select a search option: \n a. Search Customer \n b. Search Customer's payment")
        option = str(input("Enter your option: "))
        if option == "a":
            adminSearchCustomerInfo()
        elif option == "b":
            adminSearchCustomerPayment()
        else:
            print("option not supported, try again")
            adminOption()
    elif choice == 5:
        exitPage()
    else:
        print("option not supported, try again")
        adminOption()

def addEvent():
    eventHandler = open("eventList.txt", "r")
    print(">>> Welcome to AEMS event page, please select your category of events to add <<<")
    while True: # while loop is used to display the available categories for admin if they decide to add another event later on
        print("Event Category: \n 1. Sports/Martial Arts \n 2. Musical Performance \n 3. Dance/Performing Arts \n 4. Expo/Exhibition \n 5. Competition/Tournament \n 6. Others")
        choice = int(input("Please enter your choice: "))
        if choice == 1:
            eventCat = "Sports & Martial Arts"
            break
        elif choice == 2:
            eventCat = "Musical Performance"
            break
        elif choice == 3:
            eventCat = "Dance & Performing Arts"
            break
        elif choice == 4:
            eventCat = "Expo & Exhibition"
            break
        elif choice == 5:
            eventCat = "Competition & Tournament"
            break
        elif choice == 6:
            newCat = str(input("Enter the name of your category: "))
            eventCat = newCat
            break
        else:
            print("please select a valid option")
            continue

    # to obtain user inputs
    eventName = str(input("Enter event name: "))
    eventOrg = str(input("Enter event organizer: "))
    eventDate = str(input("Enter event start date in this format > [dd/mm/yyyy]: "))
    eventTime = str(input("Enter event start time in 24-hour format [eg: 16:30]: "))
    eventDuration = str(input("Enter event duration [eg: 2 days]: "))
    eventLocation = str(input("Enter the venue of the event: "))

    eventName = eventName.title() # for neatness/presentability purposes
    eventLocation = eventLocation.title() # for neatness/presentability purposes

    while True: # looping while to ask user whether event is free or not
        eventFee = str(input("Is your event free-of-charge? [Y/N]: "))
        if eventFee == "Y":
            eventPrice = "0.00"
            break
        elif eventFee == "N":
            eventPrice = str(input("Enter event price (per person) in RM [eg: 2.00]: ")) #string because we will concatenate it later (float will cause error)
            break
        else:
            print("Error: Please insert either [Y] or [N]")
            continue

    # defining empty list
    eCat = []
    eName = []
    eOrg = []
    eDate = []
    eTime = []
    eDura = []
    eLoca = []
    eFee = []

    # appending individual items into a list
    for i in eventHandler:
        a,b,c,d,e,f,g,h = i.split(", ")
        h = h.strip()
        eCat.append(a)
        eName.append(b)
        eOrg.append(c)
        eDate.append(d)
        eTime.append(e)
        eDura.append(f)
        eLoca.append(g)
        eFee.append(h)

    # appending content of each list into the text document
    db = open("eventList.txt", "a")
    db.write(eventCat+", "+eventName+", "+eventOrg+", "+eventDate+", "+eventTime+", "+eventDuration+", "+eventLocation+", "+eventPrice+"\n")
    print("Event added Successfully!")
    db.close()
    eventHandler.close()

    while True: # option to return to homepage or add another event
        print("Do you want to [1] return to admin homepage, [2] add another event?")
        option = int(input("Your choice: "))
        if option == 1:
            print("returned")
            adminOption()
        elif option == 2:
            addEvent()
        else:
            print("please select another option")
            continue
        break

def modifyEvent():
    eventdb = open("eventList.txt", "r")
    counter = 1
    print("Which event would you like to amend?")
    for i in eventdb: # display all available events
        a,b,c,d,e,f,g,h = i.split(", ")
        print(counter,"|", b)
        counter += 1
    eventdb.close()

    selection = int(input("Your choice: ")) # obtain user choice
    selection -= 1 # important: we minus 1 to get the index value (because index starts at 0)

    modifydb = open("eventList.txt", "r")
    modList = modifydb.readlines() # readlines() let us transfer the data from files into a temporary list
    editList = [] # empty string to be used later
    newList = modList # newlist copies modlist (for later use)
    tempIndex = modList[selection] # temp index finds the index of the selected event
    modifydb.close()

    print("\n>>> Current Event Details:") # display the selected events for users to refer to when modifying content(s)
    print(tempIndex)

    while True: # feature to display available categories presets
        print("Select New Event Category: \n 1. Sports/Martial Arts \n 2. Musical Performance \n 3. Dance/Performing Arts \n 4. Expo/Exhibition \n 5. Competition/Tournament \n 6. Others")
        choice = int(input("Please enter your choice: "))
        if choice == 1:
            mod1 = "Sports & Martial Arts"
            break
        elif choice == 2:
            mod1 = "Musical Performance"
            break
        elif choice == 3:
            mod1 = "Dance & Performing Arts"
            break
        elif choice == 4:
            mod1 = "Expo & Exhibition"
            break
        elif choice == 5:
            mod1 = "Competition & Tournament"
            break
        elif choice == 6:
            modCat = input("Enter the name of your category: ")
            mod1 = modCat
            break
        else:
            print("option not supported, try again")
            continue

    # obtain new details for the modified events
    mod2 = input("New event name: ")
    mod3 = input("New event organizer: ")
    mod4 = input("New event start date [eg: dd/mm/yyyy]: ")
    mod5 = input("New event start time [eg: 16:30]: ")
    mod6 = input("New event duration [eg: 2 days]: ")
    mod7 = input("New venue of the event: ")
    mod8 = input("New event price: ")

    # replace all changes in empty list
    editList.append(mod1)
    editList.append(mod2)
    editList.append(mod3)
    editList.append(mod4)
    editList.append(mod5)
    editList.append(mod6)
    editList.append(mod7)
    editList.append(mod8+"\n")
    finalEdit = ', '.join(editList) #join function to combine all strings into one string

    # delete the old event at the specific index and replace it with a new event at the same index (modification)
    del newList[selection]
    newList.insert(selection, finalEdit)

    # save changes into the .txt file
    db = open("eventList.txt", "w")
    for x in newList:
        db.write(x)
    db.close()
    print("Modification Successful!")
    adminOption()

def adminViewCategory():
    eventdb = open("eventList.txt", "r")
    # category counters are declared here
    counterCat1 = 0
    counterCat2 = 0
    counterCat3 = 0
    counterCat4 = 0
    counterCat5 = 0
    counterCat6 = 0
    for i in eventdb: # counter that display the total event in each cateogory
        a,b,c,d,e,f,g,h = i.split(", ")
        if "Sports & Martial Arts" in a:
            counterCat1 += 1
        elif "Musical Performance" in a:
            counterCat2 += 1
        elif "Dance & Performing Arts" in a:
            counterCat3 += 1
        elif "Expo & Exhibition" in a:
            counterCat4 += 1
        elif "Competition & Tournament" in a:
            counterCat5 += 1
        else:
            counterCat6 += 1

    print("Here are all the available Categories:")
    print("\n 1. Sports & Martial Arts\n", "Number of event in this Cat =", counterCat1)
    print("\n 2. Musical Performance\n", "Number of event in this Cat =", counterCat2)
    print("\n 3. Dance & Performing Arts\n", "Number of event in this Cat =", counterCat3)
    print("\n 4. Expo & Exhibition\n", "Number of event in this Cat =", counterCat4)
    print("\n 5. Competition & Tournament\n", "Number of event in this Cat =", counterCat5)
    print("\n 6. Others\n", "Number of event in this Cat =", counterCat6)
    eventdb.close()
    adminOption()

def adminViewEvent():
    eventdb = open("eventList.txt", "r")
    counter = 1
    print("here are all the event & their details:")
    for i in eventdb: # a clean ui that presents all available event in the eventList.txt file
        a,b,c,d,e,f,g,h = i.split(", ")
        print(counter,"|", b, "\nCategory:", a, "\nOrganizer:", c, "\nDate:", d, "\nTime:", e, "\nDuration:", f, "\nVenue:", g, "\nPrice (RM):", h, "\n")
        counter += 1
    eventdb.close()
    adminOption()

def adminViewCustomerList():
    memberdb = open("memberList.txt", "r")
    counter = 1
    print("here are all the members:")
    for i in memberdb:
        a,b = i.split(", ")
        print(counter,"|", a)
        counter += 1
    memberdb.close()
    adminOption()

def adminViewCustomerPayment():
    paymentdb = open("cartList.txt", "r")
    counter = 1
    print("here are all the payment details:")
    for i in paymentdb:
        a,b,c = i.split(", ")
        print(counter,"|", "\nMember Name:", a, "\nEvent Registered:", b, "\nPayment details:", c)
        counter += 1
    paymentdb.close()
    adminOption()

def adminSearchCustomerInfo():
    search = input("Enter customer username to search: ")
    searchdb = open("memberList.txt", "r")
    searchList = searchdb.readlines()
    flag = False
    searchdb.close()
    for i in range(0, len(searchList)): # looping algorithm to find the sequence where memberName is present
        searchTemp = searchList[i].split(", ")
        if search in searchTemp:
            flag = True
        else:
            pass

    if flag:
        print(search, "is a member of Asian Event Management Service")
    else:
        print(search, "is NOT a member of Asian Event Management Service")
    adminOption()

def adminSearchCustomerPayment():
    search = input("Enter customer username to search payment details: ")
    search = search.capitalize() # all usernames are saved with capitalize in events by default
    checkIndexList = []
    a = '1' # these are used as positive flags
    b = '0' # these are used as negative flags
    print("\n=== Here are the payment details for", search, "===")
    checkdb = open("cartList.txt", "r")
    checkList = checkdb.readlines()
    checkdb.close()
    for i in range(0, len(checkList)): # looping algorithm to find the sequence where memberName is present
        tempCheck = checkList[i].split(", ")
        if search in tempCheck:
            checkIndexList.append(a)
        else:
            checkIndexList.append(b)
    for i in range(0, len(checkIndexList)):
        if '1' in checkIndexList:
            x = checkIndexList.index('1')
            print(checkList[x].replace('\n',''))
            checkIndexList[x] = '0'
        else:
            pass
    adminOption()

def guestViewEvent():
    eventdb = open("eventList.txt", "r")
    counter = 1
    print("\nhere are all the event & their details: \n")
    for i in eventdb:
        a,b,c,d,e,f,g,h = i.split(", ")
        print(counter,"|", b, "\nCategory:", a, "\nOrganizer:", c, "\nDate:", d, "\nTime:", e, "\nDuration:", f, "\nVenue:", g, "\nPrice (RM):", h, "\n")
        counter += 1
    eventdb.close()
    back = input("press <enter> to return")
    if back == "":
        guestOption()
    else:
        guestOption()

def guestViewCategory():
    print("\nhere are the available event categories: \n")
    print("1. Sports & Martial Arts")
    print("2. Musical Performance")
    print("3. Dance & Performing Arts")
    print("4. Expo & Exhibition")
    print("5. Competition & Tournament")
    print("6. Others\n")
    back = input("press <enter> to return")
    if back == "":
        guestOption()
    else:
        guestOption()

def memberSignup():
    memberHandler = open("memberList.txt", "r")
    print(">>> Welcome to AEMS member registration page, please follow the instruction below <<<")
    username = input("Enter a username: ")
    password1 = input("Enter a password: ")
    password2 = input("Confirm your password: ")

    # database
    memberUN = []
    memberPW = []
    for i in memberHandler:
        a,b = i.split(", ")
        b = b.strip()
        memberUN.append(a)
        memberPW.append(b)

    if password1 != password2:
        print("Password does not match, please try again")
        memberSignup()
    elif len(password1) <= 8:
        print("Password must be longer than 8 characters, please try again")
        memberSignup()
    elif username in memberUN:
        print("Username already taken, please try again")
        memberSignup()
    else:
        db = open("memberList.txt", "a")
        db.write(username+", "+password1+"\n")
        print("Registration Successful!")
        db.close()
    memberHandler.close()
    guestOption()

def memberLogin():
    dt_today = str(datetime.datetime.today())
    tempList = []
    memberHandler = open("memberList.txt", "r")
    while True:
        print(">>> Member Login Page <<<")
        memberUN = input("Enter your username: ")
        memberPW = input("Enter your password: ")
        for i in memberHandler: # search database for users
            tempList.append(i)
        if memberUN + ", " + memberPW + "\n" in tempList:
            print("Login successful!")
            print("Welcome back,", memberUN.capitalize())
            memberName = memberUN.capitalize() # we saved their username as memberName
            cartItems = []
            cartTotal = 0

            while True:
                # option
                print("\nwhat would you like?")
                print("1. Add events to Shopping Cart")
                print("2. View purchased events")
                print("3. Exit")
                answer = int(input("Your Choice: "))

                if answer == 1: #add + payment + write
                    while True:
                        counter = 1
                        print("Which event would you like to add?")
                        eventdb = open("eventList.txt", "r")
                        for i in eventdb:
                            a,b,c,d,e,f,g,h = i.split(", ")
                            print(counter,"|", b)
                            counter += 1
                        eventdb.close()

                        # obtain user choice
                        try:
                            selection = int(input("Your choice: "))
                            if selection in range(0, counter):
                                selection -= 1
                                pass
                            else:
                                print("\n>>> selected value out of bound, try again\n")
                                continue

                        except ValueError:
                            print("\n>>> please insert an integer value\n")
                            continue

                        # open the eventlist to extract that specific event
                        itemdb = open("eventList.txt", "r")
                        itemList = itemdb.readlines()
                        itemIndex = itemList[selection].split(", ")
                        addItem = itemIndex[1]
                        itemPrice = itemIndex[7].replace('\n','') # prevents double spacing
                        itemPrice = float(itemPrice)
                        itemdb.close()

                        cartItems.append(addItem)
                        cartTotal += itemPrice
                        choose = input("do you want to add more items? <Y/N>")
                        if choose == "Y":
                            continue
                        elif choose == "N":
                            print("proceeding to payment...")
                            break
                        else:
                            print("option not supported, proceeding to payment")
                            break # add cart

                    while True:
                        print("total amount dued: ", cartTotal)
                        try:
                            payment = float(input("please enter your payment amount: "))
                            if payment == cartTotal:
                                print("payment successful!")
                                summaryPrice = str(cartTotal)
                                balance = 0.00
                                break
                            elif payment < cartTotal:
                                print("insufficient amount, please try again")
                                continue
                            elif payment > cartTotal:
                                balance = payment - cartTotal
                                print("payment successful! RM", balance, "have been returned to your account")
                                summaryPrice = str(cartTotal)
                                break
                            else:
                                print("please insert a valid number")
                                continue # payment
                        except ValueError:
                            print("\n>>> please insert a valid amount!\n")
                            continue

                    print("\nOrder Summary:")
                    print("You bought:", cartItems)
                    print("Total cost:", cartTotal)
                    print("You paid:", payment)
                    print("Balance returned:", balance)
                    print("order completed! thank you for your support!")
                    print('')
                    eventdb.close()

                    cartdb = open("cartList.txt", "a")
                    for i in cartItems:
                        cartdb.write(memberName+", "+i+", "+"paid on "+dt_today+"\n")
                    cartdb.close()
                    continue

                elif answer == 2:
                    checkIndexList = []
                    a = '1' # these are used as positive flags
                    b = '0' # these are used as negative flags
                    print("\n=== Here are all your registered events ===")
                    checkdb = open("cartList.txt", "r")
                    checkList = checkdb.readlines()
                    checkdb.close()
                    for i in range(0, len(checkList)): # looping algorithm to find the sequence where memberName is present
                        tempCheck = checkList[i].split(", ")
                        if memberName in tempCheck:
                            checkIndexList.append(a)
                        else:
                            checkIndexList.append(b) # output is a list like this [1,0,0,1,0,1] where 1 means member is present in record

                    for i in range(0, len(checkIndexList)):
                        if '1' in checkIndexList:
                            x = checkIndexList.index('1') # with the algorithm, we can simply print the line where the corresponding memberName is present
                            print(checkList[x].replace('\n','')) # this is to remove to 'new line' feature to prevent double spacing during output
                            checkIndexList[x] = '0' # then we replace the '1' in the algorithm to '0' after printing the values
                        else:
                            pass
                    continue

                elif answer == 3:
                    exitPage()

                else:
                    print("choice not supported, try again")
                    continue

                break
        else:
            print("\n >>> invalid credentials... \n")
            option = input("would you like to sign-up? \n [Y] for membership registration \n [N] to retry login \n Your choice: " )
            if option == "N":
                continue #repeat while loop
            elif option == "Y":
                memberSignup()
            else:
                print("invalid option, returning to homepage...")
                homepage()
        break
    memberHandler.close()

def exitPage():
    print("\nYou have exited the application")
    print("Thank you for using our services!")

homepage() #initiate this upon launching AEGIS
# admin authentication referral code = AEMS0001
# total function = 20
# total lines = 717


from torch.utils.data import Dataset, DataLoader
import torch
from torchtext.datasets import BABI20

def dataloader(batch_size, memory_size, task, joint, tenK):
    train_iter, valid_iter, test_iter = BABI20.iters(
        batch_size=batch_size, memory_size=memory_size, task=task, joint=joint, tenK=tenK, device=torch.device("cpu"))
    return train_iter, valid_iter, test_iter, train_iter.dataset.fields['query'].vocab

class makeBatch:
    def __init__(self,q,c,s_idx,e_idx,padding_idx=0):
        self.q=q
        self.c=c

        self.s_idx=s_idx
        self.e_idx=e_idx

    def __getitem__(self, index):
        return self.q[index], self.c[index],self.s_idx[index],self.e_idx[index]

    def __len__(self):
        return len(self.q)

def pad_sequence(batch):

    Q_batch, C_batch,s_ix,e_ix = zip(*batch)

    batch_size=len(Q_batch)

    Q_max_seq_length = max([len(x) for x in Q_batch])
    Q_res = []

    for seq in Q_batch:
        if len(seq) < Q_max_seq_length:
            pad_seq = torch.LongTensor(seq + [0] * (Q_max_seq_length - len(seq)))
            Q_res.append(pad_seq)
        else:
            Q_res.append(torch.LongTensor(seq))
    ##
    C_max_seq_length = max([len(x) for x in C_batch])
    C_res = []

    for seq in C_batch:
        if len(seq) < C_max_seq_length:
            pad_seq = torch.LongTensor(seq + [0] * (C_max_seq_length - len(seq)))
            C_res.append(pad_seq)
        else:
            C_res.append(torch.LongTensor(seq))

    return torch.cat(Q_res).reshape(batch_size, Q_max_seq_length), torch.cat(C_res).reshape(batch_size,C_max_seq_length),\
          torch.LongTensor(s_ix).reshape(batch_size),torch.LongTensor(e_ix).reshape(batch_size)

def num_parameter(model):
    sum=0
    for p in model.parameters():
        if p.requires_grad:
            sum+=p.numel()
    return sum


#!/usr/bin/env python

import category_encoders as ce
from pandas import concat, Series
from time import time
from pandas.core.frame import DataFrame
from sklearn.pipeline import Pipeline
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import StandardScaler
from sklearn.compose import ColumnTransformer
from sklearn.metrics import f1_score
from sklearn.model_selection import train_test_split
from scipy.sparse import hstack, csr_matrix, vstack
import numpy as np
from sklearn.utils import resample

# generating training and validation data sets from sparse matrices
def train_val_upsampling_split(train_values_df, train_labels_df, upsampling=False):
    X_train, X_val, y_train, y_val = train_test_split(
        train_values_df, train_labels_df, test_size=0.3, random_state=42)
    if upsampling:
        X = hstack((X_train, y_train)).toarray()
        level_list = []
        for level in range(1, 4):
            level_filter = X[:, -1] == level
            level_X = X[level_filter, 0:-1]
            level_y = X[level_filter, -1].ravel()
            level_list.append([level_X, level_y])
        level_low, level_medium, level_high = level_list
        # medium level has the highest count, so let's increase the other two by up-sampling
        upsampled_list = []
        for upsampled in [level_low, level_high]:
            tmp_upsampled_list = []
            for arr in upsampled:
                tmp_upsampled_list.append(resample(arr,
                                          replace=True,  # sample with replacement
                                          n_samples=len(level_medium[1]),  # match number in medium level
                                          random_state=33))  # reproducible results
            upsampled_list.append(tmp_upsampled_list)  # type: ignore
        upsampled_list.append(level_medium)  # notice: append works in place
        mat_x_list, mat_y_list = [], []
        for mat_x, mat_y in upsampled_list:
            mat_x_list.append(csr_matrix(mat_x))
            mat_y_list.append(mat_y)
        X_train = vstack(mat_x_list)
        y_train = Series(np.concatenate(mat_y_list, axis=0).ravel())
        y_val = y_val.iloc[:, 0]
    print(f'X_train.shape: {X_train.shape}')
    print(f'y_train.shape: {y_train.shape}')
    print(f'X_val.shape: {X_val.shape}')
    print(f'y_val.shape: {y_val.shape}\n')
    return X_train, X_val, y_train, y_val

# one-hot encodes categorical columns and create mean-target encoding columns in dataframe
def target_encode_multiclass(train_values_df, train_labels_df, test_values_df=None):
    onehot_enc = ce.OneHotEncoder()
    train_labels_onehot_df = onehot_enc.fit_transform(train_labels_df)
    class_names = train_labels_onehot_df.columns
    cat_train_values_df = train_values_df.select_dtypes('category')
    num_train_values_df = train_values_df.select_dtypes(exclude='category')
    num_pipeline = Pipeline([('imputer', SimpleImputer(strategy='median')),
                             ('std_scaler', StandardScaler())])
    num_train_values_arr = num_pipeline.fit_transform(num_train_values_df)
    num_train_values_df = DataFrame(num_train_values_arr, columns=num_train_values_df.columns,
                                    index=train_values_df.index)
    if test_values_df is not None:
        cat_test_values_df = test_values_df.select_dtypes('category')
        num_test_values_df = test_values_df.select_dtypes(exclude='category')
        num_test_values_arr = num_pipeline.fit_transform(num_test_values_df)
        num_test_values_df = DataFrame(num_test_values_arr, columns=num_test_values_df.columns,
                                       index=test_values_df.index)
    for class_name in class_names:
        enc = ce.target_encoder.TargetEncoder(min_samples_leaf=10, smoothing=0.1)
        enc.fit(cat_train_values_df, train_labels_onehot_df[class_name])
        temp_train_df = enc.transform(cat_train_values_df)
        temp_train_df.columns = [str(col)+'_'+str(class_name) for col in temp_train_df.columns]
        num_train_values_df = concat([num_train_values_df, temp_train_df], axis=1)
        if test_values_df is not None:
            temp_test_df = enc.transform(cat_test_values_df)  # type: ignore
            temp_test_df.columns = [str(col)+'_'+str(class_name) for col in temp_test_df.columns]
            num_test_values_df = concat([num_test_values_df, temp_test_df], axis=1)  # type: ignore
    if test_values_df is not None:
        return num_train_values_df, num_test_values_df  # type: ignore
    else:
        return num_train_values_df

# multi-category encoder function to test category functions in category_encoders with earthquake data
def test_category_encoders(classifier, X_strat_train, y_strat_train, X_strat_val, y_strat_val, num_attrib, cat_attrib):
    encoder_list = [
                    ce.backward_difference.BackwardDifferenceEncoder,
                    ce.basen.BaseNEncoder,
                    ce.binary.BinaryEncoder,
                    ce.cat_boost.CatBoostEncoder,  # didn't work with earthquake data
                    ce.hashing.HashingEncoder,  # didn't work with earthquake data
                    ce.helmert.HelmertEncoder,
                    ce.james_stein.JamesSteinEncoder,
                    ce.one_hot.OneHotEncoder,  # didn't work with earthquake data
                    ce.leave_one_out.LeaveOneOutEncoder,  # didn't work with earthquake data
                    ce.m_estimate.MEstimateEncoder,
                    ce.ordinal.OrdinalEncoder,
                    ce.polynomial.PolynomialEncoder,
                    ce.sum_coding.SumEncoder,
                    ce.target_encoder.TargetEncoder,  # didn't work with earthquake data
                    ce.woe.WOEEncoder
                    ]
    for encoder in encoder_list:
        t0 = time()
        numeric_transformer = Pipeline(steps=[('imputer', SimpleImputer(strategy='median')),
                                              ('scaler', StandardScaler())])
        categorical_transformer = Pipeline(steps=[('imputer', SimpleImputer(strategy='constant',
                                                  fill_value='missing')), ('woe', encoder())])

        preprocessor = ColumnTransformer(transformers=[('num', numeric_transformer, num_attrib),
                                                       ('cat', categorical_transformer, cat_attrib)], n_jobs=-1)

        pipe = Pipeline(steps=[('preprocessor', preprocessor), ('classifier', classifier)])
        print(f'Fitting encoder: {encoder}')
        model = pipe.fit(X_strat_train, y_strat_train)

        y_pred = model.predict(X_strat_val)
        print(f'''Time elapsed: {time() - t0:.4f} sec, micro-averaged F1 score: {f1_score(y_strat_val,y_pred,
        average='micro'):.8f}''')


import blenderproc as bproc
import dataclasses
import dcargs
import json
import numpy as np
import os
from PIL import Image
import shutil
from typing import Literal
import imageio

from blenderproc.python.camera.CameraUtility import get_intrinsics_as_K_matrix

# Object to shapenet id mappings
obj_to_shapenet_ids = {
    "Airplane": {
        "used_synset_id": "02691156",
        "used_source_id": "8f4e31ee9912f54e77fd7318510b8627",
    },
    "Bag": {
        "used_synset_id": "02773838",
        "used_source_id": "4e4fcfffec161ecaed13f430b2941481",
    },
    "Car": {
        "used_synset_id": "02958343",
        "used_source_id": "1ae9732840a315afab2c2809513f396e",
    },
    "Guitar": {
        "used_synset_id": "03467517",
        "used_source_id": "4ff4b6305e3d5e2ad57700c05b1862d8",
    },
    "Lamp": {
        "used_synset_id": "03636649",
        "used_source_id": "8ef9c1ffaa6f7292bd73284bc3c3cbac",
    },
    "Cap": {
        "used_synset_id": "02954340",
        "used_source_id": "188702a3bb44f40c284432ce2f42f498",
    },
    "Motorbike": {
        "used_synset_id": "03790512",
        "used_source_id": "6bf1f988493dc23752ee90e577613070",
    },
    "Skateboard": {
        "used_synset_id": "04225987",
        "used_source_id": "619b49bae27807fb1082f2ea630bf69e",  #
    },
    "Camera": {
        "used_synset_id": "02942699",
        "used_source_id": "97690c4db20227d248e23e2c398d8046",
    },
}

@dataclasses.dataclass
class ViewPlanner:
    candidate_view_radius: float = (
        1.3  # heuristic: account for workspace size and arm kinematics
    )
    candidate_view_type: Literal["hemisphere", "circle", "sphere"] = "sphere"
    num_cam_positions: int = 100

@dataclasses.dataclass
class Args:
    #############################
    # Blenderproc rendering args #
    #############################
    view_planner: ViewPlanner = None
    shapenet_path: str = ""  # Path to the downloaded shape net core v2 dataset, get it from http://www.shapenet.org/
    blender_path: str = ""  # Path to the blender obj
    offline_gym_data_dir: str = "../active-nerf/offline_gym_data"  # TODO KL update Path to where the final files will be saved
    save_data_type: Literal["train", "val"] = "val"
    save_ray_info: bool = False  # Ray info (w.r.t a frame) consists of ray_coord, ray_length and ray weight
    convert_background_to_white: bool = False
    shapenet_obj: Literal[
        "Airplane",
        "Bag",
        "Car",
        "Guitar",
        "Lamp",
        "Cap",
        "Motorbike",
        "Skateboard",
        "Camera",
    ] = "Airplane"

##################### active nerf utils ###############################
def fibonacci_sphere(samples: int) -> np.ndarray:
    """Fibonacci sphere algorithm for uniform sampling on a sphere. Returns array with
    shape (samples, 3).

    Adapted from:
    https://stackoverflow.com/questions/9600801/evenly-distributing-n-points-on-a-sphere"""
    phi = np.pi * (3.0 - np.sqrt(5.0))  # Golden angle in radians.
    i = np.arange(samples)
    y = 1.0 - (i / float(samples - 1.0)) * 2.0  # y goes from 1 to -1.
    radius = np.sqrt(1 - y * y)  # Radius at y.
    theta = phi * i  # Golden angle increment.
    x = np.cos(theta) * radius
    z = np.sin(theta) * radius

    return np.array([x, y, z]).T

def get_candidate_camera_positions_circle(
    radius: float,
    cam_z: float,
    num_cam_positions: int,
    center_x: float = 0,
    center_y: float = 0,
) -> dict:
    """Returns a dictionary with keys as camera angles and values as camera positions."""
    cam_positions = {}
    single_angle = 360 / num_cam_positions
    for i in range(num_cam_positions):
        x = radius * np.cos(2 * np.pi / num_cam_positions * i) + center_x
        y = radius * np.sin(2 * np.pi / num_cam_positions * i) + center_y
        cam_positions[int(single_angle * i)] = np.array((x, y, cam_z))
    return cam_positions

def get_candidate_views(
    object_bounds: dict,
    num_cam_positions: int,
    candidate_view_radius: float = 0.8,
    candidate_view_type: str = "sphere",
):
    """Returns a list of openGL camera poses that point towards the object.
    Radius should come from object scene bounds
    """
    poi = object_bounds["poi"]
    size = object_bounds["size"]
    assert candidate_view_radius > size * np.sqrt(
        2
    ), "Sphere radius must be larger than object size"

    if candidate_view_type == "hemisphere":
        sphere_radius = candidate_view_radius
        fib_xyzs = fibonacci_sphere(2 * num_cam_positions)
        # heuristic: filter out values whose z value is below e.g. 0.25 to look from above
        filtered_xyzs = fib_xyzs[np.where(fib_xyzs[:, -1] > 0.4)]
        rescaled_xyzs = sphere_radius * filtered_xyzs
    elif candidate_view_type == "circle":
        circle_radius = candidate_view_radius * (
            object_bounds["xmax"] - object_bounds["xmin"]
        )  # heuristic: extra distance from object
        cam_z = poi[2]
        rescaled_xyzs = get_candidate_camera_positions_circle(
            circle_radius, cam_z, num_cam_positions
        )
        rescaled_xyzs = np.array(list(rescaled_xyzs.values()))
    elif candidate_view_type == "sphere":
        sphere_radius = candidate_view_radius
        fib_xyzs = fibonacci_sphere(num_cam_positions)
        rescaled_xyzs = sphere_radius * fib_xyzs

    world_xyzs = rescaled_xyzs + poi
    # calculate the camera poses
    openGL_cam_positions = []
    for loc in world_xyzs:
        rotation_mat = bproc.camera.rotation_from_forward_vec(poi - loc)
        openGL_cam_positions.append(
            bproc.math.build_transformation_mat(loc, rotation_mat)
        )
    return openGL_cam_positions

def get_obj_bounds(shapenet_obj):
    poi = np.zeros(3)
    size = 1
    return {
        "poi": poi,
        "size": size,
        "xmin": poi[0] - 2 * size,
        "xmax": poi[0] + 2 * size,
        "ymin": poi[1] - 2 * size,
        "ymax": poi[1] + 2 * size,
        "zmin": poi[2] - 2 * size,
        "zmax": poi[2] + 2 * size,
    }  # 2 * is rough heuristic

    blender_obj = shapenet_obj.blender_obj
    poi = blender_obj.location[:]
    bound_vals = blender_obj.bound_box[:]
    size = np.array([np.array(i) for i in list(bound_vals)]).max()

    return {
        "poi": poi,
        "size": size,
        "xmin": poi[0] - 2 * size,
        "xmax": poi[0] + 2 * size,
        "ymin": poi[1] - 2 * size,
        "ymax": poi[1] + 2 * size,
        "zmin": poi[2] - 2 * size,
        "zmax": poi[2] + 2 * size,
    }  # 2 * is rough heuristic

def get_transformations_template(
    fl_x=None, fl_y=None, c_x=None, c_y=None, aabb_scale=None, frames=[]
):
    transformations = {
        "fl_x": fl_x,
        "fl_y": fl_y,
        "c_x": c_x,
        "c_y": c_y,
        "aabb_scale": aabb_scale,
        "frames": frames,
    }
    return transformations

def openGL_to_openCV(cam2world_matrix):
    tmat = np.array(
        [
            [1.0, 0.0, 0.0, 0.0],
            [-0.0, -1.0, -0.0, -0.0],
            [-0.0, -0.0, -1.0, -0.0],
            [0.0, 0.0, 0.0, 1.0],
        ]
    )
    return np.matmul(cam2world_matrix, tmat)

############################# end of active nerf utils ################################

def main(args):
    obj_name = (
        args.shapenet_obj
        if args.shapenet_path != ""
        else args.blender_path.split("/")[-1].split(".")[0]
    )
    offline_gym_obj_dir = os.path.join(args.offline_gym_data_dir, obj_name)
    # if os.path.isdir(offline_gym_obj_dir):
    #     shutil.rmtree(offline_gym_obj_dir)
    if not os.path.isdir(offline_gym_obj_dir):
        os.makedirs(offline_gym_obj_dir)

    bproc.init()

    intrinsics = get_intrinsics_as_K_matrix()
    transformations_template = get_transformations_template(
        fl_x=intrinsics[0][0],
        fl_y=intrinsics[1][1],
        c_x=intrinsics[0][2],
        c_y=intrinsics[1][2],
    )

    if args.shapenet_path != "":
        # Load the ShapeNet object into the scene
        shapenet_obj_ids = obj_to_shapenet_ids[args.shapenet_obj]
        obj = bproc.loader.load_shapenet(
            args.shapenet_path,
            used_synset_id=shapenet_obj_ids["used_synset_id"],
            used_source_id=shapenet_obj_ids["used_source_id"],
            move_object_origin=False,
        )
    elif args.blender_path != "":
        # Load the Blender object into the scene
        obj = bproc.loader.load_blend(args.blender_path)
        obj = bproc.loader.load_blend(args.blender_path)

    # Define lights and set location and energy level
    light1 = bproc.types.Light()
    light1.set_type("POINT")
    light1.set_location([0, 0, 5])
    light1.set_energy(200)

    light2 = bproc.types.Light()
    light2.set_type("POINT")
    light2.set_location([0, 5, 0])
    light2.set_energy(200)

    light3 = bproc.types.Light()
    light3.set_type("POINT")
    light3.set_location([0, -5, 0])
    light3.set_energy(200)

    light4 = bproc.types.Light()
    light4.set_type("POINT")
    light4.set_location([5, 0, 0])
    light4.set_energy(200)

    light5 = bproc.types.Light()
    light5.set_type("POINT")
    light5.set_location([-5, 0, 0])
    light5.set_energy(200)

    # Calculate the camera poses
    object_bounds = get_obj_bounds(obj)
    openGL_cam_positions = get_candidate_views(
        object_bounds,
        args.view_planner.num_cam_positions,
        args.view_planner.candidate_view_radius,
        args.view_planner.candidate_view_type,
    )

    # Add camera poses to scene
    for i in range(len(openGL_cam_positions)):
        openGL_transform_matrix = openGL_cam_positions[i]
        bproc.camera.add_camera_pose(openGL_transform_matrix)

    # Render the whole pipeline
    # bproc.renderer.set_output_format(enable_transparency=True)
    bproc.renderer.enable_depth_output(activate_antialiasing=False)
    data = bproc.renderer.render()

    image_dir = f"{offline_gym_obj_dir}/{args.save_data_type}"
    os.makedirs(image_dir)  # making directory for each image

    for i in range(len(openGL_cam_positions)):
        rgb = np.array(data["colors"][i])  # [..., :3] # remove alpha channel
        depth = np.array(data["depth"][i])
        distance = bproc.postprocessing.depth2dist(depth).astype(np.float32)

        if args.convert_background_to_white:
            rgb[depth > 1e8] = 255

        depth[depth > 1e8] = 0
        distance[distance > 1e8] = 0

        rgb_png = Image.fromarray(rgb)
        rgb_path = f"{args.save_data_type}/im_{i}.png"
        rgb_png.save(os.path.join(offline_gym_obj_dir, rgb_path))

        depth_exr = depth
        depth_path = f"{args.save_data_type}/im_{i}_depth.exr"
        imageio.imwrite(os.path.join(offline_gym_obj_dir, depth_path), depth_exr)

        distance_exr = distance
        distance_path = f"{args.save_data_type}/im_{i}_distance.exr"
        imageio.imwrite(os.path.join(offline_gym_obj_dir, distance_path), distance_exr)

        transform_dct = {
            "file_path": rgb_path,
            "depth_path": depth_path,
            "distance_path": distance_path,
            "transform_matrix": openGL_cam_positions[i].tolist(),
        }

        if args.save_ray_info:
            ray_lengths_path = f"{args.save_data_type}/ray_lengths_{i}.npy"
            ray_coords_path = f"{args.save_data_type}/ray_coords_{i}.npy"
            ray_weights_path = f"{args.save_data_type}/ray_weights_{i}.npy"
            ray_lengths = distance.copy()
            ray_coords = np.meshgrid(
                np.arange(distance.shape[0]), np.arange(distance.shape[1])
            )
            ray_weights = np.ones_like(distance)
            ray_weights[distance == 0] = 0  # do not supervise inf distance rays
            ray_info_dct = {
                "ray_lengths_path": ray_lengths_path,
                "ray_coords_path": ray_coords_path,
                "ray_weights_path": ray_weights_path,
            }

            np.save(os.path.join(offline_gym_obj_dir, ray_lengths_path), ray_lengths)
            np.save(os.path.join(offline_gym_obj_dir, ray_coords_path), ray_coords)
            np.save(os.path.join(offline_gym_obj_dir, ray_weights_path), ray_weights)

            transform_dct.update(ray_info_dct)

        transformations_template["frames"].append(transform_dct)

    with open(f"{offline_gym_obj_dir}/transforms_{args.save_data_type}.json", "w") as f:
        json.dump(transformations_template, f)

if __name__ == "__main__":
    args = dcargs.parse(Args)
    main(args)


import sys
input = sys.stdin.readline
from collections import deque

n, m = map(int, input().split())
d = {x+1:deque([0 for _ in range(20)]) for x in range(n)}
for _ in range(m):
    o = list(map(int, input().split()))
    if len(o) == 3:
        d[o[1]][o[2]-1] = (o[0]-1)^1
    elif o[0] == 3:
        d[o[1]].rotate()
        d[o[1]][0] = 0
    else:
        d[o[1]][0] = 0
        d[o[1]].rotate(-1)
log = set()
for k in d.keys():
    log.add(int(''.join(map(str, d[k])),2))
print(len(log))

백준/Silver/15787. 기차가 어둠을 헤치고 은하수를/기차가 어둠을 헤치고 은하수를.py

기차가 어둠을 헤치고 은하수를.py


from LogRegression import MyLogisticRegression
from utils import loadData, zScoreNormalization, plotData
from sklearn import linear_model
import numpy as np

def accuracy(real, computed):
    return sum([1 if real[i] == computed[i] else 0 for i in range(len(real))]) / len(real)

if __name__ == '__main__':
    inputs, outputs, labels, feature1, feature2, feature3, feature4 = loadData()

    numericalLabels = [i for i in range(len(labels))]
    numericalOutputs = [0 for i in range(len(outputs))]
    for i in range(len(labels)):
        for j in range(len(outputs)):
            if outputs[j] == labels[i]:
                numericalOutputs[j] = i

    np.random.seed(5)
    indexes = [i for i in range(len(inputs))]
    trainSample = np.random.choice(indexes, int(0.8 * len(inputs)), replace=False)  # 80% train data
    testSample = [i for i in indexes if i not in trainSample]  # 20% test data

    trainInputs = [inputs[i] for i in trainSample]
    trainOutputs = [numericalOutputs[i] for i in trainSample]

    testInputs = [inputs[i] for i in testSample]
    testOutputs = [numericalOutputs[i] for i in testSample]

    # print(trainInputs)
    # print(testInputs)
    trainInputs, testInputs = \
        zScoreNormalization(trainInputs, testInputs)
    # print(trainInputs)
    # print(testInputs)

    trainFeature1 = [sample[0] for sample in trainInputs]
    trainFeature2 = [sample[1] for sample in trainInputs]
    trainFeature3 = [sample[2] for sample in trainInputs]
    trainFeature4 = [sample[3] for sample in trainInputs]

    plotData(trainFeature1, trainFeature2, trainFeature3, trainFeature4, "Train data")

    # tool
    classifier = linear_model.LogisticRegression(max_iter=1000)
    classifier.fit(trainInputs, trainOutputs)
    print("-----------tool-----------")
    print("Real: " + str(testOutputs))
    print("Comp: " + str(list(classifier.predict(testInputs))))
    print("Accuracy: " + str(accuracy(testOutputs, list(classifier.predict(testInputs)))))

    # manual

    classifierIrisSetosa = MyLogisticRegression()
    classifierIrisVersicolor = MyLogisticRegression()
    classifierIrisVirginica = MyLogisticRegression()

    trainOutputSetosa = [0 if sample != 0 else 1 for sample in trainOutputs]
    trainOutputVersicolor = [0 if sample != 1 else 1 for sample in trainOutputs]
    trainOutputVirginica = [0 if sample != 2 else 1 for sample in trainOutputs]

    classifierIrisSetosa.fit(trainInputs, trainOutputSetosa)
    classifierIrisVersicolor.fit(trainInputs, trainOutputVersicolor)
    classifierIrisVirginica.fit(trainInputs, trainOutputVirginica)

    probabilitiesSetosa = classifierIrisSetosa.predict(testInputs)
    probabilitiesVersicolor = classifierIrisVersicolor.predict(testInputs)
    probabilitiesVirginica = classifierIrisVirginica.predict(testInputs)

    # print(probabilitiesSetosa)
    # print(probabilitiesVersicolor)
    # print(probabilitiesVirginica)
    computedProbabilities = [[probabilitiesSetosa[i], probabilitiesVersicolor[i], probabilitiesVirginica[i]] for i in range(len(testOutputs))]

    # print(computedProbabilities)
    computedOutputs = [numericalLabels[np.argmax(sample)] for sample in computedProbabilities]

    print("----------manual----------")
    print("Real: " + str(testOutputs))
    print("Comp: " + str(computedOutputs))
    print("Accuracy: " + str(accuracy(testOutputs, computedOutputs)))

Machine Learning/Logistic Regression algorithm/main.py


import concurrent.futures
import re
import time
import xml.etree.ElementTree as ET

import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry

class NetworkHandler:
    """
    Abstracts the creation of session with specific retry strategy and multithreading
    """

    def __init__(self):
        self.session = self.mount_session()
        self.executor = concurrent.futures.ThreadPoolExecutor(max_workers=5)

    def mount_session(self):
        retry_strategy = Retry(
            total=5,
            respect_retry_after_header=True,
            backoff_factor=0.1,
            status_forcelist=[429, 500, 502, 503, 504, 520],
            allowed_methods=["GET", "POST"],
        )
        retry_strategy.DEFAULT_BACKOFF_MAX = 5
        adapter = HTTPAdapter(max_retries=retry_strategy)
        session = requests.Session()
        session.mount(prefix="https://", adapter=adapter)
        session.mount(prefix="http://", adapter=adapter)
        return session

class Archiver:
    """
    Used for authenticating and interacting with the archive.org API.
    """

    def __init__(self, s3_access_key, s3_secret_key):
        """
        Initialize the object
        :param s3_access_key: s3_access_key
        :param s3_secret_key: s3_secret_key
        """

        self.s3_access_key = s3_access_key
        self.s3_secret_key = s3_secret_key
        self.session = NetworkHandler().session
        self.executor = NetworkHandler().executor

        headers = {
            "Accept": "application/json",
            "Authorization": f"LOW {self.s3_access_key}:{self.s3_secret_key}",
        }
        self.session.headers.update(headers)

    def save_pages(
        self,
        pages: list,
        capture_all=False,
        capture_outlinks=False,
        capture_screenshot=False,
        force_get=False,
        skip_first_archive=True,
        outlinks_availability=False,
        email_result=False,
    ):
        """
        Save a list of webpages to the archive.org API using multithreading and automatic retries
        """

        results = []
        failures = []
        with self.executor as executor:
            future_to_url = {
                executor.submit(
                    self.save_page,
                    url,
                    capture_all=capture_all,
                    capture_outlinks=capture_outlinks,
                    capture_screenshot=capture_screenshot,
                    force_get=force_get,
                    skip_first_archive=skip_first_archive,
                    outlinks_availability=outlinks_availability,
                    email_result=email_result,
                ): url
                for url in pages
            }
            for future in concurrent.futures.as_completed(future_to_url):
                url = future_to_url[future]
                try:
                    results.append(future.result())
                except Exception as exc:
                    failures.append(url)
            if failures:
                results.extend(
                    self.save_pages(
                        failures,
                        capture_all=capture_all,
                        capture_outlinks=capture_outlinks,
                        capture_screenshot=capture_screenshot,
                        force_get=force_get,
                        skip_first_archive=skip_first_archive,
                        outlinks_availability=outlinks_availability,
                        email_result=email_result,
                    )
                )
            return results

    def save_page(
        self,
        url,
        capture_all=False,
        capture_outlinks=False,
        capture_screenshot=False,
        force_get=False,
        skip_first_archive=True,
        outlinks_availability=False,
        email_result=False,
    ):
        """
        Save a single webpage to archive.org
        """

        save_url = f"https://web.archive.org/save/{url}"
        response = self.session.post(
            url=save_url,
            data={
                "url": url,
                "capture_all": capture_all,
                "capture_outlinks": capture_outlinks,
                "force_get": force_get,
                "skip_first_archive": skip_first_archive,
                "capture_screenshot": capture_screenshot,
                "outlinks_availability": outlinks_availability,
                "email_result": email_result,
            },
        )
        if response.status_code == 200:
            data = response.json()
            if data.get("status") is None and data.get("job_id"):
                status = "submitted"
            else:
                status = data.get("status")

            formatted_response = {
                "url": url,
                "job_id": data.get("job_id"),
                "message": data.get("message"),
                "status": status,
                "full_response": data,
            }
            return formatted_response

        else:
            formatted_response = {
                "url": url,
                "status_code": response.status_code,
                "full_response": response.text,
            }
            return formatted_response

    def get_save_status(self, job_id: str):
        """
        Given a job_id, get the save status of the job.
        :param job_id: job_id
        :return: save_status
        """
        url = f"https://web.archive.org/save/status/{job_id}?_t={int(time.time())}"
        response = self.session.get(url=url)
        if response.status_code == 200:
            data = response.json()
            if data.get("status") == "error":
                return self.get_save_status(job_id=job_id)
            else:
                return data
        else:
            return response.text

    def get_user_status_request(self):
        """
        Get the current number of active and available session of the user account.
        """
        url = f"https://web.archive.org/save/status/user?_t={int(time.time())}"
        response = self.session.get(url=url)
        if response.status_code == 200:
            try:
                return response.json()
            except:
                if "Too Many Requests" in response.text:
                    return 429, "Too Many Requests"
                return response.text
        else:
            return response.status_code, response.text

class Sitemap:
    def __init__(self, sitemap_URL):
        self.location = sitemap_URL
        self.LOCAL_PREFIX = "file://"
        self.local_sitemap = self._sitemap_is_local()
        self.content = self._load_sitemap()
        self.encoded_content = ET.fromstring(self.content)
        self.namespace = self._get_namespace()
        self.type = self._get_sitemap_type()

    def _sitemap_is_local(self):
        """
        Returns True if we believe a URI to be local, False otherwise.
        """
        return self.location.startswith(self.LOCAL_PREFIX) or self.location.startswith(
            "/"
        )

    def _load_sitemap(self):
        """Loads a sitemap from a local file or download it from the internet."""
        if self.local_sitemap:
            sitemap_filepath = sitemap_filepath[len(self.LOCAL_PREFIX) :]

            # Try to open the file, error on failure
            try:
                with open(sitemap_filepath, "r") as fp:
                    contents = fp.read()
            except IOError as e:
                print(e)
                raise
            return contents

        else:
            response = requests.get(self.location)
            try:
                # Raise `requests.exceptions.HTTPError` if 4XX or 5XX status
                response.raise_for_status()
            except requests.exceptions.HTTPError as e:
                print(e)
                raise
            else:
                return response.text.encode("utf-8")

    def _get_sitemap_type(self):
        if "sitemapindex" in self.encoded_content.tag:
            return "sitemapindex"
        elif "urlset" in self.encoded_content.tag:
            return "urlset"
        else:
            return None

    def _get_namespace(self):
        """Extract the namespace using a regular expression."""
        match = re.match(r"{.*}", self.encoded_content.tag)
        return match.group(0) if match else ""

    def extract_pages_from_sitemap(self):
        """
        Extract the various pages from the sitemap text.
        """
        if self.type == "urlset":
            urls = []
            for loc_node in self.encoded_content.findall(f".//{self.namespace}loc"):
                urls.append(loc_node.text)

            return list(set(urls))
        elif self.type == "sitemapindex":
            raise NotImplementedError(
                "sitemapindex not implemented yet.\nPlease retry with a urlset sitemap."
            )
        else:
            raise ValueError(f"Unknown sitemap type: {self.type}")


# -*- coding: utf-8 -*-
from django.contrib import admin

from .models import Team, Project

@admin.register(Team)
class TeamAdmin(admin.ModelAdmin):

    list_display = (

        'title',
        'description',
        'date_created',
        'id',
        'slug',
        'published',
        'reviewed',
        'token',
    )
    list_filter = ('date_created', 'published', 'reviewed')
    raw_id_fields = ('members',)
    search_fields = ('slug',)

@admin.register(Project)
class ProjectAdmin(admin.ModelAdmin):

    list_display = (
        'title',
        'date_created',
        'slug',

        'access_token',
        'id',

        'image',
        'logo',
        'published',
        'reviewed',
    )
    list_filter = ('date_created', 'published', 'reviewed')
    search_fields = ('slug',)


from collections import deque # 덱 불러옴(BFS에 이용)
import sys
input = sys.stdin.readline

# DFS
def dfs(graph, v, visited): # graph(이차원리스트), 시작점, 방문처리여부리스트

    visited[v] = True # 현재 노드를 방문처리
    print(v, end=' ') # v를 출력하는데, 띄어쓰기를 해주면서 출력한다.

    # 현재 노드와 연결된 다른 노드를 재귀적으로 방문
    for i in graph[v]:
        if not visited[i]: # 방문하지않은 노드에대해서
            dfs(graph, i, visited) # dfs를 재귀적으로 실행시킨다.

def bfs(graph, v, visited): # graph(이차원리스트), 시작점, 방문처리여부리스트
    queue = deque([v]) # 덱으로 큐를 구현한다.
    visited[v] = True

    while queue: # 큐가 빌 때까지 반복
        now = queue.popleft() # 큐에서 하나의 원소를 뽑아서 출력
        print(now, end=' ')

        for i in graph[now]: # 해당 원소와 연결된것들중에서
            if not visited[i]: # 방문하지 않은 원소들을
                queue.append(i) # 큐에 삽입
                visited[i] = True # 방문처리

n, m, v = map(int, input().split()) # 정점의 개수, 간선의 개수, 탐색시작번호
graph = [[] for _ in range(n+1)] # graph를 정점의 개수만큼 초기화(이차원리스트로)
for _ in range(m): # 간선의 개수만큼반복
    a, b = map(int, input().split()) # 정점 연결관계 받아줌
    # 양방향 간선이니깐 양방향으로 다 append
    graph[a].append(b)
    graph[b].append(a)

# 정점 낮은번호부터 먼저 방문해야 하니깐 오름차순으로 정렬
for i in range(1, n+1):
    graph[i].sort()

visited = [False] * (n+1) # 방문을 다 false로 초기화
dfs(graph, v, visited) # 그래프, v(처음 출발지점), visited(다 false로 초기화 되어있는)
print() # 중간에 개행해줘야해서
visited = [False] * (n+1) # 방문을 다 false로 초기화
bfs(graph, v, visited) # 그래프, v(처음 출발지점), visited(다 false로 초기화 되어있는)


from selenium import webdriver

import sys
sys.path.append('./config')
import config as config

from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains
from selenium.common.exceptions import TimeoutException
import time

# Replace the path with the path to your Chrome driver
driver = webdriver.Chrome('/drivers/chromedriver')

# maximize the browser window
driver.maximize_window()

# Open the website
driver.get(config.url_superadmin)

# Find the email and password fields and enter your credentials
email_field = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CSS_SELECTOR, "input[type='text']")))
email_field.send_keys("superadmin@gmail.com")

password_field = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CSS_SELECTOR, "input[type='password']")))
password_field.send_keys('Password@1234')

button = driver.find_element(By.CSS_SELECTOR, ".MuiButton-containedPrimary")
button.click()

# Wait for the page to load
time.sleep(5)

# get the current URL of the web page
current_url = driver.current_url

# check if the URL contains the expected text (in this case, "/dashboard")
if "dashboard" in current_url:
    print("Successfully redirected to dashboard page.")
else:
    print("Error: failed to redirect to dashboard page.")

# clicking  menus
wait = WebDriverWait(driver, 10)
routes_menu = wait.until(EC.element_to_be_clickable((By.XPATH, "//span[contains(text(), 'Users')]")))
routes_menu.click()

time.sleep(2)

# Find the button element by class name and text
button = driver.find_element(By.XPATH, "//button[contains(@class, 'MuiButton-root') and span[text()='+']]")
button.click()

#fill the form
input_element = driver.find_element(By.CSS_SELECTOR, "input[placeholder='Enter First Name']")
input_element.send_keys("Robin")

input_element = driver.find_element(By.CSS_SELECTOR, "input[placeholder='Enter Last Name']")
input_element.send_keys("Charm")

input_element = driver.find_element(By.CSS_SELECTOR, "input[placeholder='Enter Your Email']")
input_element.send_keys("sachintendulkar@usa.com")

input_element = driver.find_element(By.CSS_SELECTOR, "input[placeholder='1 (702) 123-4567']")
input_element.send_keys("987658742")

# #checkbox selection.
# checkbox = driver.find_element(By.CLASS_NAME, "jss1320")
# is_checked = checkbox.is_selected()

# if not is_checked:
#     checkbox.click()

#  Keep the browser open
input("Press Enter to close the browser...")

# Close the browser
driver.quit()


'''
프로그래머스 팀에서는 기능 개선 작업을 수행 중입니다.
각 기능은 진도가 100%일 때 서비스에 반영할 수 있습니다.

또, 각 기능의 개발속도는 모두 다르기 때문에 뒤에 있는 기능이 앞에 있는 기능보다 먼저 개발될 수 있고,
이때 뒤에 있는 기능은 앞에 있는 기능이 배포될 때 함께 배포됩니다.

먼저 배포되어야 하는 순서대로 작업의 진도가 적힌 정수 배열 progresses와
각 작업의 개발 속도가 적힌 정수 배열 speeds가 주어질 때
각 배포마다 몇 개의 기능이 배포되는지를 return 하도록 solution 함수를 완성하세요.
'''
from collections import deque
from operator import add

def solution(progresses, speeds):
    answer = []

    que_progresses = deque(progresses)  # 작업 개수 리스트를 큐로 변환
    que_speeds = deque(speeds)  # 작업 속도 리스트를 큐로 변환

    while que_progresses:
        count = 0  # 배포마다 기능이 몇 개인지 저장하는 변수
        que_len = len(que_progresses)

        # 기능 개발이 한개만 남았을 경우 날짜와 상관없이 무조건
        # 하나만 배포하므로 answer에 1을 추가해주고 종료
        if que_len == 1:
            answer.append(1)
            break

        # 개발 진행도 + 개발 속도 -> 개발 진행도 갱신
        que_progresses = deque(map(add, que_progresses, que_speeds))

        # 개발진행이 완료 되었으면 배포
        while que_progresses:
            if que_progresses[0] >= 100:
                que_progresses.popleft()
                que_speeds.popleft()
                count += 1
            else:
                break

        if count != 0:
            answer.append(count)
    print(answer)
    return answer

if __name__ == '__main__':
    progresses = [95, 90, 99, 99, 80, 99]
    speeds = [1, 1, 1, 1, 1, 1]
    solution(progresses,speeds)