__author__ = 'Dawson'
import wpilib
import math

BELT_BROKEN = False

class HolonomicDrive():

    #PLEASE READ:
    #Right side driving forward is assumed to be +1
    #Turning counter-clockwise is assumed to be +1
    #Meet these requriements and THEN use invertDrive() if it is all backwards.
    #Summary:
    #Turn should be passed in as -Joystick.getX, most likely

    class DriveMode:
        VOLTAGE = 1
        SPEED = 2
        JEFF = 3

    def __init__(self, fl, fr, bl, br):
        self.FL = fl
        self.FR = fr
        self.BL = bl
        self.BR = br
        self.FL.setPID(1.0, 0.0, 3.0, 0.0)
        self.FR.setPID(1.0, 0.0, 3.0, 0.0)
        self.BL.setPID(1.0, 0.0, 3.0, 0.0)
        self.BR.setPID(1.0, 0.0, 3.0, 0.0)

        self.stores = [0.0, 0.0, 0.0, 0.0]
        self.encoderTargets = [0.0, 0.0, 0.0, 0.0]
        self.wheelOffset = math.pi / 4
        self.invert = 1 # can be 1 or -1
        self.maxVelocity = 80 * 5 #MAX VELOCITY IS FOR JEFF MODE (AKA INTEGRAL VELOCITY) AND IS MODIFIED FOR VELOCITY MODE
        self.slowModeMaxVelocity = 50
        self.previousDriveMode = HolonomicDrive.DriveMode.VOLTAGE
        self.driveMode = HolonomicDrive.DriveMode.VOLTAGE

        self.usingInputAccelerationControl = True
        self.maximumAccelDistance = .08
        self.previousX = 0.0
        self.previousY = 0.0
        self.previousTurn = 0.0

    def accelerationFilter(self, magnitude, direction, turn):
        newX = magnitude * math.cos(direction)
        newY = magnitude * math.sin(direction)
        distanceToNew = math.sqrt( (newX - self.previousX) * (newX - self.previousX) + (newY - self.previousY) * (newY - self.previousY) )
        finalTurn = turn
        if not abs(self.previousTurn - turn) <= self.maximumAccelDistance:
            if turn > self.previousTurn:
                finalTurn = self.previousTurn + self.maximumAccelDistance
            else:
                finalTurn = self.previousTurn - self.maximumAccelDistance

        if (distanceToNew <= self.maximumAccelDistance):
            self.previousX = newX
            self.previousY = newY
            self.previousTurn = finalTurn
            return [magnitude, direction, finalTurn]

        #Alternate Return for strafe fail to pass
        directionToNew = math.atan2(newY - self.previousY, newX - self.previousX)
        finalX = self.previousX + math.cos(directionToNew) * self.maximumAccelDistance
        finalY = self.previousY + math.sin(directionToNew) * self.maximumAccelDistance
        self.previousX = finalX
        self.previousY = finalY
        self.previousTurn = finalTurn
        return [math.sqrt(finalX * finalX + finalY * finalY), math.atan2(finalY, finalX), finalTurn]

    #USE THESE FEW FUNCTIONS BELOW

    # use the variables DriveMode.VOLTAGE, DriveMode.SPEED, etc. in this function
    # and NOT their values (1, 2, ...) -- those could change in the future
    def setDriveMode(self, mode):
        self.driveMode = mode

    def getDriveMode(self):
        return self.driveMode

    # a generic drive() function that calls the corresponding driveVoltage(),
    # driveSpeed(), etc. based on what the current driveMode is.
    def drive(self, magnitude, direction, turn):
        if self.driveMode == HolonomicDrive.DriveMode.VOLTAGE:
            self.driveVoltage(magnitude, direction, turn)
        elif self.driveMode == HolonomicDrive.DriveMode.SPEED:
            self.driveSpeed(magnitude, direction, turn)
        elif self.driveMode == HolonomicDrive.DriveMode.JEFF:
            self.driveSpeedJeffMode(magnitude, direction, turn)

    # these functions ignore the current driveMode setting

    def driveVoltage(self, magnitude, direction, turn):
        self.ensureControlMode(wpilib.CANTalon.ControlMode.PercentVbus)
        self.calcWheels(magnitude, direction, turn)
        self.setWheels()
        self.previousDriveMode = HolonomicDrive.DriveMode.VOLTAGE
        #self.logCurrent()

    def driveSpeed(self, magnitude, direction, turn):
        self.ensureControlMode(wpilib.CANTalon.ControlMode.Speed)
        self.calcWheels(magnitude, direction, turn)
        self.scaleToMax()
        self.setWheels()
        self.previousDriveMode = HolonomicDrive.DriveMode.SPEED
        #self.logCurrent()

    def driveSpeedJeffMode(self, inMagnitude, inDirection, inTurn, inAggressivePID = False): #Increments position to mock speed mode
        # if (turn == 0 and magnitude == 0):
        #     self.disableTalons()
        # elif self.FL.getControlMode() == wpilib.CANTalon.ControlMode.Disabled and\
        #      self.FR.getControlMode() == wpilib.CANTalon.ControlMode.Disabled and\
        #      self.BL.getControlMode() == wpilib.CANTalon.ControlMode.Disabled and\
        #      self.BR.getControlMode() == wpilib.CANTalon.ControlMode.Disabled:
        #     self.enableTalons()
        #     self.zeroEncoderTargets()

        magnitude = inMagnitude
        direction = inDirection
        turn = inTurn
        aggressivePID = inAggressivePID

        if self.usingInputAccelerationControl:
            filteredResults = self.accelerationFilter(magnitude, direction, turn)
            magnitude = filteredResults[0]
            direction = filteredResults[1]
            turn = filteredResults[2]

        self.ensureControlMode(wpilib.CANTalon.ControlMode.Position)
        if not self.previousDriveMode == 3:
            self.zeroEncoderTargets()
        self.calcWheels(magnitude, direction, turn)
        if aggressivePID:

            self.FL.setPID(12.0, 0.0, 15.0, 0.0)
            self.FR.setPID(12.0, 0.0, 15.0, 0.0)
            self.BL.setPID(12.0, 0.0, 15.0, 0.0)
            self.BR.setPID(12.0, 0.0, 15.0, 0.0)
            self.scaleToMaxJeffMode()
        else:
            self.FL.setPID(1.0, 0.0, 3.0, 0.0)
            self.FR.setPID(1.0, 0.0, 3.0, 0.0)
            self.BL.setPID(1.0, 0.0, 3.0, 0.0)
            self.BR.setPID(1.0, 0.0, 3.0, 0.0)
            self.scaleToMaxJeffMode()
        self.incrementEncoderTargets()
        #self.ensureSafeDistance()
        self.setWheelsJeffMode()
        self.previousDriveMode = HolonomicDrive.DriveMode.JEFF
    def invertDrive(self, enabled=True):
        self.invert = -1 if enabled else 1

    def setWheelOffset(self, angleInRadians):
        self.wheelOffset = angleInRadians

    def setMaxVelocity(self, velocity):
        self.maxVelocity = velocity

    #DO NOT USE THESE FUNCTIONS

    def calcWheels(self, magnitude, direction, turn):
        self.stores = [0.0, 0.0, 0.0, 0.0]
        self.addStrafe(magnitude, direction)
        if BELT_BROKEN:
            self.stores[1] *= 2#Now add 1/3 of FR strafe value to entire robots turn, in correct direction
        if not BELT_BROKEN:
            self.addTurn(turn)
        else:
            self.addTurn(turn - self.stores[1]/8)#1/6 start
        self.scaleNumbers()

    def addStrafe(self, magnitude, direction):
        if magnitude > 1.0:
            fixedMagnitude = 1.0
        else:
            fixedMagnitude = magnitude
        #self.stores[0] += fixedMagnitude
        self.stores[0] += fixedMagnitude * (math.sin(direction + self.wheelOffset)) * -1 #FL
        self.stores[1] += fixedMagnitude * (math.sin((direction - self.wheelOffset))) #FR
        self.stores[2] += fixedMagnitude * (math.sin((direction - self.wheelOffset))) * -1 #BL
        self.stores[3] += fixedMagnitude * (math.sin((direction + self.wheelOffset))) #FR

    def addTurn(self, turn):
        for i in range (0,4):
            self.stores[i] += turn

    def scaleNumbers(self):
        largest = max(self.stores)
        if largest > 1:
            for number in self.stores:
                number = number / largest

    def incrementEncoderTargets(self):
        if not abs(self.FL.getEncPosition() - self.encoderTargets[0]) > 4000: #Started @ 1000
            print(self.FL.getEncPosition())
            self.encoderTargets[0] += self.stores[0] * self.invert
        if not abs(self.FR.getEncPosition() - self.encoderTargets[1]) > 4000:
            #print("incrementing")
            self.encoderTargets[1] += self.stores[1] * self.invert
        if not abs(self.BL.getEncPosition() - self.encoderTargets[2]) > 4000:
            #print("incrementing")
            self.encoderTargets[2] += self.stores[2] * self.invert
        if not abs(self.BR.getEncPosition() - self.encoderTargets[3]) > 4000:
            #print("incrementing")
            self.encoderTargets[3] += self.stores[3] * self.invert

    def setWheels(self):
        self.FL.set(self.stores[0] * self.invert)
        self.FR.set(self.stores[1] * self.invert)
        self.BL.set(self.stores[2] * self.invert)
        self.BR.set(self.stores[3] * self.invert)
        #print(str(self.stores[0])+ "     "+str(self.stores[1]) + "     "+ str(self.stores[2])+ "     " + str(self.stores[3]))

    def setWheelsJeffMode(self):
        self.FL.set(self.encoderTargets[0])
        self.FR.set(self.encoderTargets[1])
        self.BL.set(self.encoderTargets[2])
        self.BR.set(self.encoderTargets[3])

    def scaleToMax(self):
        for i in range (0,4):
            self.stores[i] *= self.maxVelocity * 5

    def scaleToMaxJeffMode(self):
        for i in range (0,4):
            self.stores[i] *= self.maxVelocity

    def ensureControlMode(self, controlMode):
        if self.FL.getControlMode()\
           == self.FR.getControlMode()\
           == self.BL.getControlMode()\
           == self.BR.getControlMode()\
           == controlMode:
            return
        print("SETTING CONTROL MODE")
        self.FL.changeControlMode(controlMode)
        self.FR.changeControlMode(controlMode)
        self.BL.changeControlMode(controlMode)
        self.BR.changeControlMode(controlMode)

    def logCurrent(self):
        print("FL Current: " + str(self.FL.getOutputCurrent()))
        print("FR Current: " + str(self.FR.getOutputCurrent()))
        print("BL Current: " + str(self.BL.getOutputCurrent()))
        print("BR Current: " + str(self.BR.getOutputCurrent()))

    def zeroEncoderTargets(self):
        self.encoderTargets[0] = self.FL.getEncPosition()
        self.encoderTargets[1] = self.FR.getEncPosition()
        self.encoderTargets[2] = self.BL.getEncPosition()
        self.encoderTargets[3] = self.BR.getEncPosition()

    def ensureSafeDistance(self):
        # TODO: add counts per rev. variable, and max velocity variable
        flposition = self.FL.getEncPosition()
        if abs(flposition - self.encoderTargets[0]) > 4000:
            if (self.encoderTargets[0] > flposition):
                self.encoderTargets[0] = flposition + 4000
            else:
                self.encoderTargets[0] = flposition - 4000

        frposition = self.FL.getEncPosition()
        if abs(frposition - self.encoderTargets[0]) > 4000:
            if (self.encoderTargets[0] > frposition):
                self.encoderTargets[0] = frposition + 4000
            else:
                self.encoderTargets[0] = frposition - 4000

        blposition = self.FL.getEncPosition()
        if abs(blposition - self.encoderTargets[0]) > 4000:
            if (self.encoderTargets[0] > blposition):
                self.encoderTargets[0] = blposition + 4000
            else:
                self.encoderTargets[0] = blposition - 4000

        brposition = self.FL.getEncPosition()
        if abs(brposition - self.encoderTargets[0]) > 4000:
            if (self.encoderTargets[0] > brposition):
                self.encoderTargets[0] = brposition + 4000
            else:
                self.encoderTargets[0] = brposition - 4000

    def enableTalons(self):
        self.FL.enable()
        self.FR.enable()
        self.BL.enable()
        self.BR.enable()

    def disableTalons(self):
        self.FL.disable()
        self.FR.disable()
        self.BL.disable()
        self.BR.disable()

    def scaleToMaxJeffModeSlowMode(self):
        for i in range (0,4):
            self.stores[i] *= self.slowModeMaxVelocity


import time
import board
import pulseio
from adafruit_motor import servo
import touchio

touch_A5 = touchio.TouchIn(board.A5) #setting up wire in pin
touch_A4 = touchio.TouchIn(board.A4) #setting up wire in pin
touch = touchio.TouchIn

pwm = pulseio.PWMOut(board.A2, duty_cycle=2 ** 15, frequency=50) #setting up pwm
my_servo = servo.Servo(pwm)

angle = 0 #amgle starts at zero

while True:
    my_servo.angle = angle
    if touch_A4.value: #if wire 4 gets touched
        print("Touched A4")
        if angle < 180: #if angle is less then 180 add 1 to angle
         angle += 1
        time.sleep(0.05)
    if touch_A5.value: #if wire 5 gets touched
        print("Touched A5")
        if angle > 0: #if wire is less then subtract 1
         angle -= 1
        time.sleep(0.05)


def main():
    book_path = "books/frankenstein.txt.save"
    text = get_book_text(book_path)
    num_words = get_num_words(text)
    num_chars = get_num_chars(text)
    sum_chars = get_sum_chars (text)
    print(f"{num_words} words found in the document")
    print(f"{sum_chars} letters found in the document")

def get_book_text(path):
    with open(path) as f:
        return f.read()

def get_num_words(text):
    words = text.split()
    return len(words)

def get_num_chars(text):
    chars = {}
    for c in text:
        lowered = c.lower()
        if lowered in chars:
            chars [lowered] += 1
        else:
            chars [lowered] = 1
    return chars

def get_sum_chars (text):
      words = text.split()
      return len(words)

main()


"""
It is only for the refrence purpose.
Use the management commands instead of using it.
"""
import scrapy
from scrapy.crawler import CrawlerProcess
from scrapy.utils.log import configure_logging

from crawlers.spiders.wiki import WikiSpider

process = CrawlerProcess({
    'BOT_NAME': 'majdoor',
    'USER_AGENT': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/534.55.3 (KHTML, like Gecko) Version/5.1.3 Safari/534.53.10',
    'RANDOMIZE_DOWNLOAD_DELAY': True,
    'COOKIES_ENABLED': False,
    'LOG_LEVEL': 'INFO',
    'DOWNLOAD_TIMEOUT': 20,
    'REDIRECT_ENABLED': False
})

process.crawl(WikiSpider)
#process.crawl('wikipedia', urls='https://en.wikipedia.org/wiki/Gulzar')
process.start() # the script will block here until the crawling is finished


# This files contains your custom actions which can be used to run
# custom Python code.
#
# See this guide on how to implement these action:
# https://rasa.com/docs/rasa/custom-actions

# This is a simple example for a custom action which utters "Hello World!"

from typing import Any, Text, Dict, List

from rasa_sdk import Action, Tracker
from rasa_sdk.executor import CollectingDispatcher

courses=['Data Science','Full Stack Development', 'Java Developer Program','Data Analytics']
class ActionHelloWorld(Action):

    def name(self) -> Text:
        return "fees_enquiry"

    def run(self, dispatcher: CollectingDispatcher,
            tracker: Tracker,
            domain: Dict[Text, Any]) -> List[Dict[Text, Any]]:

        course_n=next(tracker.get_latest_entity_values("course_name"),None)
        # course_n =tracker.latest_message.get('entities')[0].get("value")

        if "Data Science" in course_n:
            dispatcher.utter_message(text="The fees of Data Science Course is Rs. 1,60,000")
        elif "Full Stack Development" in course_n:
            dispatcher.utter_message(text="The fees of Full Stack Development Course is Rs. 1,50,000")
        elif "Java Developer" in course_n:
            dispatcher.utter_message(text="The fees of Java Developer Program is Rs. 1,00,000")
        elif "Data Analytics" in course_n:
            dispatcher.utter_message(text="The fees of Data Analytics course is Rs. 50,000")
        else:
            dispatcher.utter_message(text="We do not provide training for this course")

        return []


from pages.login_page import LoginPage
from pages.device_search_page import SearchPage
from pages.device_card_page import CardPage

class Test_Enter(LoginPage):
    login = LoginPage()
    login.login_as('inv_operator_01_pechora', '1')

class Test_Grid(SearchPage):
    def test_text_navigation(self):
        exist = self.menu_not_available()
        assert 0 == exist
        #нужно проверить что отстуствует меню ресурсы/главная/настройки/отсутствует опция для создания площадок/оборудование
    def test_card_open(self):
        #нужно сделать выборку по сетевым девайсам
        self.enable_filter()
        self.open_device_card()

class Test_Card(CardPage):

   card = CardPage()
        # Check names for card's menu
        #не должно быть вкладки доступ/кнопок
        # проверить названия закладок

   def test_ua_text(self):
        self.check_refresh()
        self.ua_text()
        self.change_language_to_ru()
        self.ru_text()
        self.change_language_to_en()
        self.en_text()
        self.change_language_to_ua()
        assert 0 == self.switch_between_tabs()

   def test_ru_text(self):
        self.change_language_to_ru()
        self.ru_text()
        self.change_language_to_ru()
        self.ru_text()
        self.check_refresh()
        self.change_language_to_en()
        self.en_text()
        self.change_language_to_ua()
        self.check_refresh()
        assert 0 == self.switch_between_tabs()

   def test_en_text(self):
       self.change_language_to_en()
       self.en_text()
       self.change_language_to_ru()
       self.ru_text()
       self.change_language_to_ua()
       self.check_refresh()
       assert 0 == self.switch_between_tabs()
       self.close()

   def ua_text(self):
       assert "ПАРАМЕТРИ" == self.check_text_parameters()
       assert 0 == self.menu_parameters_not_available('ua')
       assert 0 == self.edit_button_not_available()

   def ru_text(self):
       assert "ПАРАМЕТРЫ" == self.check_text_parameters()
       assert 0 == self.menu_parameters_not_available('ua')
       assert 0 == self.edit_button_not_available()

   def en_text(self):
       assert "PARAMETERS" == self.check_text_parameters()
       assert 0 == self.menu_parameters_not_available('en')
       assert 0 == self.edit_button_not_available()


def recPed(nombresTodasComidas):

    comida = ""
    cantidad = 0
    while(True):
        comida = input("Ingrese plato: ")
        if(comida.lower() in nombresTodasComidas):
            break
        else:
            print("Error: Ingresar de nuevo")

    while(True):
        try:
            cantidad = int(input(">>Cantidad de platos: "))
            if(int(cantidad) >= 1):
                break
            else:
                print("debe ingresar un valor mayor o igual a 1")
        except:
            print("ingrese valor entero")

    return [comida.capitalize(), cantidad]

class Comida:

    def __init__(self, nombreComida, precio):
        self.nombreComida = nombreComida
        self.precio = precio

    def getNombre(self):
        return self.nombreComida

    def getPrecio(self):
        return self.precio

    def __str__(self):
        return f"{self.nombreComida.capitalize()}, ${self.precio}"

    def __repr__(self):
        return str(self.__dict__)

def diccionarioTotal(dicc1, dicc2):
    mezcla = {**dicc1, **dicc2}
    return mezcla

def menu():
    diccionarioComidas = {"Segundo":[], "Sopas":[], "Entradas":[]}
    diccionarioEspeciales = {"Especialidad del chef":[]}

    arregloCriollo = diccionarioComidas.get("Segundo")
    arregloCriollo.append(Comida("pollo frito", 5))
    arregloCriollo.append(Comida("Encebollado", 5))
    arregloCriollo.append(Comida("Bollo", 5))
    arregloSopas = diccionarioComidas.get("Sopas")
    arregloSopas.append(Comida("sopa crema", 5))
    arregloSopas.append(Comida("fideo", 5))
    arregloSopas.append(Comida("sopa de pollo", 5))
    arregloPostres = diccionarioComidas.get("Entradas")
    arregloPostres.append(Comida("croissant", 5))
    arregloPostres.append(Comida("pie", 5))
    arregloPostres.append(Comida("Batido", 5))
    arregloChef = diccionarioEspeciales.get("Especialidad del chef")
    arregloChef.append(Comida("Huevo frito",7 ))
    arregloChef.append(Comida("Chancho", 8))
    arregloChef.append(Comida("Bolon", 7))

    diccionarioFinal = diccionarioTotal(diccionarioComidas, diccionarioEspeciales)

    resultado = []
    for valor1 in diccionarioFinal.values():
        for valor2 in valor1:
            resultado.append(valor2.getNombre().lower())
    todasComidas = resultado

    resultado = []
    for valor1 in diccionarioEspeciales.values():
        for valor2 in valor1:
            resultado.append(valor2.getNombre().lower())
    todasEspeciales = resultado

    diccionarioNuevo = {}

    for valor1 in diccionarioFinal.values():
        for valor2 in valor1:
            diccionarioNuevo[valor2.getNombre().lower()] = valor2.getPrecio()

    todosPrecios = diccionarioNuevo

    return diccionarioFinal, todasComidas, todasEspeciales, todosPrecios

diccionarioFinal, todasComidas, todasEspeciales, todosPrecios = menu()

def calPre(misPedidos, todosPrecios, comidasEspeciales):

    tamanioPedido = 0
    precioInicial = 0
    cantidadDeEspeciales = 0
    recargoPorEspeciales = 0

    for pedido in misPedidos:
        nombre = pedido[0]
        cantidad = pedido[1]
        precioUnitario = todosPrecios.get(nombre.lower())

        print(f"Platos: {nombre}, cantidad: {cantidad}, precio por unidad: ${todosPrecios.get(nombre.lower())}")
        precioInicial = precioInicial + (precioUnitario*cantidad)
        tamanioPedido = tamanioPedido + cantidad

        if(nombre.lower() in comidasEspeciales):
            cantidadDeEspeciales = cantidadDeEspeciales + cantidad
            recargoPorEspeciales = recargoPorEspeciales + 0.05*(cantidad*precioUnitario)

    print(f"\nNumero de platos: {tamanioPedido}.  Precio standard: ${'{:.2f}'.format(precioInicial)}.")

    if(tamanioPedido <= 100):

        if((tamanioPedido > 5) and ( tamanioPedido <= 10)):
            precioInicial = precioInicial*0.9
            print(f"\nSe pidieron entre 5 y 10 comidas (-10%): ${'{:.2f}'.format(precioInicial)}")

        if((tamanioPedido > 10)):
            precioInicial = precioInicial*0.8
            print(f"\nSe pidieron mas de 10 comidas (-20%): ${'{:.2f}'.format(precioInicial)}")

        if((precioInicial > 50) and (precioInicial <= 100)):
            precioInicial = precioInicial-10
            print(f"\nCosto entre $50 y $100 (-10$): ${'{:.2f}'.format(precioInicial)}")

        if(precioInicial > 100):
            precioInicial = precioInicial-25
            print(f"\nCosto mayor a $100 (-25$): ${'{:.2f}'.format(precioInicial)}")

        if(cantidadDeEspeciales>0):
            precioInicial = precioInicial+recargoPorEspeciales
            print(f"\nSe pidio {cantidadDeEspeciales} platos especiales (+5% del valor de cada plato especial -> +{'{:.2f}'.format(recargoPorEspeciales)}): ${'{:.2f}'.format(precioInicial)}")

        return round(precioInicial, 2)

    else:
        return -1

def inicio():

    diccionarioComidasporTipo, nombresTodasComidas, nombresEspeciales, NombreyPrecioTodos = menu()

    print("Bienvenido , este es nuestro menu: \n")

    for valor1 in diccionarioComidasporTipo.keys():
        print(f"***********{valor1.upper()}***********")
        for valor2 in diccionarioComidasporTipo.get(valor1):
            print(valor2.getNombre() + " -> " + str(valor2.getPrecio()) + "$")
        print("\n")

    print("¿Desea hacer un pedido?, Si/No")

    pedido = "No"

    while(True):
        pedir = input("Ingrese opción: ")
        try:
            if( str(pedir).upper() == "SI"):
                pedido = "SI"
                break
            elif( str(pedir).upper() == "NO" ):
                pedido = "NO"
                break
            else:
                print("Opcion no valida, intente nuevamente")
        except:
            print("Ingrese solo (Si o No)")

    hacePed = pedido

    if(hacePed == "SI"):
        print("\n")

        pedidos = []
        pedido = recPed(nombresTodasComidas)
        pedidos.append(pedido)

        print("\nGustaria seguir pidiendo?, Si/No")

        while(True):
            sigue = input("     >>Ingrese opcion: ")

            if( str(sigue).upper() == "SI"):
                print("\n")
                pedido = recPed(nombresTodasComidas)
                pedidos.append(pedido)
                print("\n       Quiere pedir mas?, Si/No")
            elif( str(sigue).upper() == "NO" ):
                break
            else:
                print("     Error: intente de nuevo")

        misPedidos = pedidos

        print("\n****precio de pedido*******")
        totalPagar = calPre(misPedidos, NombreyPrecioTodos, nombresEspeciales)
        if(totalPagar > 0):
            print(f"\nTotal= ${'{:.2f}'.format(totalPagar)}")

            while(True):
                comprar = input("\n>>¿Confirmar?: si/no ")
                try:
                    if( str(comprar).upper() == "SI" ):
                        print(f"\nCompra de ${'{:.2f}'.format(totalPagar)} registrada, pronto podra retirarla")
                        print("\n")
                        print("Gracias, vuelva pronto")
                        break
                    elif( str(comprar).upper() == "NO" ):
                        print("Cancelado.")
                        print("\n")
                        print("Gracias, vuelva pronto")
                        break
                    else:
                        print("\nError: por favor escoja una opcion valida")
                except:
                    print("\nIngrese Si o No")

        else:
            print("\nEl maximo permitido es 100.")
    else:
        print("\n")
        print("Gracias, vuelva pronto")

#inicio()


from django.conf import settings
from django.http import HttpResponse, JsonResponse
from django.shortcuts import redirect, render
from cart.models import *
from userprofile.models import*
from django.template.loader import render_to_string
from io import BytesIO
import razorpay
from xhtml2pdf import pisa
from .models import*
from django.shortcuts import get_object_or_404
from decimal import Decimal

# Create your views here.

def checkout(request,add_id):
    user_address= get_object_or_404(User_address, id= add_id, user= request.user)
    carts = get_object_or_404(Cart,user=request.user)
    # item =  CartItems.objects.filter(cart=carts)
    # original=0
    # for  single in item:
    #   original = original + single.item_price

    # total_price = carts.get_total_price()

    # total_price= request.session.get('coupon_applied_total',0)
    # discount= request.session.get('discount',0)
    # coupon= request.session.get('selected_coupon',0)
    # total= request.session.get('total',0)
    total_price = Decimal(request.session.get('total', '0'))

    final_price = Decimal(request.session.get('final', '0'))
    coupon = Decimal(request.session.get('coupon', '0'))

    if total_price>500:
        total_price_delivery=final_price
    else:
        total_price_delivery=final_price + 40

    request.session['final_price'] = str(total_price_delivery)

    return render(request,'final_checkout.html',{'user_address': user_address, 'carts':carts, 'total_price_delivery':total_price_delivery,'total_price':total_price,  'coupon':coupon , 'final':final_price })

def placeorder(request, add_id):

    user_address= get_object_or_404(User_address, id= add_id, user= request.user)
    carts = get_object_or_404(Cart,user=request.user)
    item =  CartItems.objects.filter(cart=carts)
    if item.exists():

            original=0
            for  single in item:
              original = original + single.item_price
            # total_price = sum(item.price * item.quantity for item in item)
            request.session['original'] = str(original)
            coupon = Decimal(request.session.get('coupon', '0'))
            total_price=  Decimal(request.session.get('final_price', '0'))
            final_price = Decimal(request.session.get('final', '0'))

            order = Order.objects.create(
                user=request.user,
                address=user_address,
                total_price=final_price,
                original_price= original,
                coupon=coupon,
                payment_status='ORDERED',
                payment_method='CASH_ON_DELIVERY',
            )

            for cart_item in item:
                OrderItem.objects.create(
                    order=order,
                    product=cart_item.product,
                    price=cart_item.price,
                    quantity=cart_item.quantity
                )
                variant = cart_item.product
                variant.stock -= cart_item.quantity
                variant.save()
            item.delete()

            return render(request,'orderplaced.html')
    else:
        return render(request,'orderplaced.html')

def orders(request):
    orders= Order.objects.filter(user= request.user).order_by('-id')

    return render(request,'ordertable.html',{'orders':orders})

def order_view(request,order_id):
    orderr= Order.objects.get(id=order_id)
    order_item = OrderItem.objects.filter(order=orderr)

    discount= orderr.original_price-(orderr.total_price+orderr.coupon)
    if orderr.total_price <=500:
      actuall_total=orderr.total_price +40
      shipping=40
    else:
      actuall_total=orderr.total_price
      shipping = 0

    return render(request,'orderview.html',{'order_item':order_item ,'orderr':orderr,'discount':discount,'actuall_total':actuall_total,'shipping':shipping})

def cancel_orderss(request,order_id):
    order = get_object_or_404(Order, id=order_id)
    if order.payment_status != 'CANCELLED':
          if order.payment_method=='RAZORPAY':
            user = order.user
            refund= Decimal(order.total_price)
            user_wallet = get_object_or_404(Wallet,user= user)
            user_wallet.balance += refund
            user_wallet.save()

          order_items = OrderItem.objects.filter(order=order)

          for item in order_items:
              variant= item.product
              variant.stock = variant.stock + item.quantity
              variant.save()

          order.payment_status = 'CANCELLED'
          order.save()

    return redirect('orders')

def Return_orderss(request,order_id):
    order = get_object_or_404(Order, id=order_id)
    user = order.user
    refund= Decimal(order.total_price)
    user_wallet = get_object_or_404(Wallet,user= user)
    user_wallet.balance += refund
    user_wallet.save()

    if order.payment_status != 'CANCELLED':
          order_items = OrderItem.objects.filter(order=order)

          for item in order_items:
              variant= item.product
              variant.stock = variant.stock + item.quantity
              variant.save()

          order.payment_status = 'RETURNED'
          order.save()

    return redirect('orders')

def initiate_payment(request):

    if request.method == 'POST':
        # Retrieve the total price and other details from the backend
        # cart = Cart.objects.get(user_id=request.user)
        # cart_items = cart.cartitems_set.all()

        total_price_str = request.session.get('final_price', '0.00')
        total_price = Decimal(total_price_str)

        total_amount_in_cents = int(total_price*100)

        client = razorpay.Client(auth=(settings.RAZOR_KEY_ID, settings.RAZOR_KEY_SECRET))
        payment = client.order.create({

            'amount': total_amount_in_cents,
            'currency': 'INR',
            'payment_capture': 1

        })

        response_data = {
            'order_id': payment['id'],
            'amount': payment['amount'],
            'currency': payment['currency'],
            'key': settings.RAZOR_KEY_ID,

        }
        return JsonResponse(response_data)

    # Return an error response if the request method is not POST
    return JsonResponse({'error': 'Invalid request method'})

def online_payment_order(request, add_id):
    if request.method == 'POST':

        payment_id = request.POST.getlist('payment_id')[0]
        orderId = request.POST.getlist('orderId')[0]
        signature = request.POST.getlist('signature')[0]
        user_address = get_object_or_404(User_address, id=add_id, user=request.user)
        cart = Cart.objects.get(user_id=request.user)
        cart_items = cart.cartitems_set.all()

        final_price = Decimal(request.session.get('final', '0'))
        coupon = Decimal(request.session.get('coupon', '0'))
        # total_price_str = request.session.get('final_price', '0.00')
        total_price = Decimal(final_price)
        original_price=  Decimal(request.session.get('final_price', '0'))
        order = Order.objects.create(
            user=request.user,
            address=user_address,
            total_price=total_price,
            original_price= original_price,
            payment_status='ORDERED',
            payment_method='RAZORPAY',
            coupon=coupon,
            razor_pay_payment_id=payment_id,
            razor_pay_payment_signature=signature,
            razor_pay_order_id=orderId,

        )

        for cart_item in cart_items:
            OrderItem.objects.create(
                order=order,
                product=cart_item.product,
                price=cart_item.price,
                quantity=cart_item.quantity
            )
            variant = cart_item.product
            variant.stock -= cart_item.quantity
            variant.save()

        cart_items.delete()
        orderId = order.id

        return JsonResponse({'message': 'Order placed successfully', 'orderId': orderId})
    else:
        # Handle invalid request method (GET, etc.)
        return JsonResponse({'error': 'Invalid request method'})

# def invoice_download(request,order_id):
#     orderr= Order.objects.get(id=order_id)
#     order_item = OrderItem.objects.filter(order=orderr)
#     discount= orderr.original_price-orderr.total_price
#     actuall_total=orderr.total_price-orderr.coupon

#     return render(request,'show_invoice.html',{'order_item':order_item ,'orderr':orderr,'discount':discount,'actuall_total':actuall_total})
def invoice_download_start(request,order_id):
    orderr= Order.objects.get(id=order_id)
    order_item = OrderItem.objects.filter(order=orderr)
    discount= orderr.original_price-orderr.total_price
    actuall_total=orderr.total_price-orderr.coupon

    html_content = render_to_string('invoice_download.html', {'order_item':order_item ,'orderr':orderr,'discount':discount,'actuall_total':actuall_total})

    # Set the response content type as 'application/pdf' to indicate that it's a PDF file
    response = HttpResponse(content_type='application/pdf')

    # Set the filename for the downloaded file
    response['Content-Disposition'] = 'attachment; filename="Invoice.pdf"'

    # Generate the PDF content from the HTML using xhtml2pdf
    pdf = pisa.pisaDocument(BytesIO(html_content.encode("UTF-8")), response)

    if pdf.err:
        return HttpResponse('Error generating PDF', status=500)

    return response


'''
You are given a positive integer array skill of even length n where skill[i] denotes the skill of the ith player. Divide the players into n / 2 teams of size 2 such that the total skill of each team is equal.

The chemistry of a team is equal to the product of the skills of the players on that team.

Return the sum of the chemistry of all the teams, or return -1 if there is no way to divide the players into teams such that the total skill of each team is equal.

Example 1:

Input: skill = [3,2,5,1,3,4]
Output: 22
Explanation:
Divide the players into the following teams: (1, 5), (2, 4), (3, 3), where each team has a total skill of 6.
The sum of the chemistry of all the teams is: 1 * 5 + 2 * 4 + 3 * 3 = 5 + 8 + 9 = 22.
Example 2:

Input: skill = [3,4]
Output: 12
Explanation:
The two players form a team with a total skill of 7.
The chemistry of the team is 3 * 4 = 12.
Example 3:

Input: skill = [1,1,2,3]
Output: -1
Explanation:
There is no way to divide the players into teams such that the total skill of each team is equal.

Constraints:

2 <= skill.length <= 105
skill.length is even.
1 <= skill[i] <= 1000
'''
import unittest

from typing import *
from collections import Counter
class Solution:
    def dividePlayers(self, skill: List[int]) -> int:
        total = sum(skill)
        team = len(skill) // 2
        per_sum = total // team
        if per_sum * team != total:
            return -1
        counter = Counter(skill)
        counter_new = Counter()

        res = 0
        for n in skill:
            counter_new[n] += 1
            counter_new[per_sum - n] += 1
            res += n * (per_sum - n)

        if counter + counter == counter_new:
            return res // 2
        return -1

class TestSolution(unittest.TestCase):

    def test_case(self):
        examples = (
            (([3,2,5,1,3,4],),22),
        )
        for first, second in examples:
            self.assert_function(first, second)

    def assert_function(self, first, second):
        self.assertEqual(Solution().dividePlayers(*first), second,
                         msg="first: {}; second: {}".format(first, second))

unittest.main()

Leetcode/2491. Divide Players Into Teams of Equal Skill.py


def day2dayOfWeek(nDay):
    aDays = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
    "Friday", "Saturday"]
    return aDays[nDay - 1]

try:
    nDay = int(input("Enter a day of the week ... 1 for Sunday: "))
    sDayOfWeek = day2dayOfWeek(nDay)
    print("The", nDay, "of the week is", sDayOfWeek)
except:
    print("please enter a day from 1-7")


# import pdb; pdb.set_trace()
class  graph:
    def __init__(self):
        self.matrix = []
        self.vertexCount = 0

    def clear(self):
        self.__init__()

    def add(self, edge1, edge2):
        edge1 = int(edge1)
        edge2 = int(edge2)
        if edge1 >= self.vertexCount:
            for i in range(edge2 - self.vertexCount + 1):
                self.matrix.append([])
            # self.matrix.append([] * (edge1 - self.vertexCount + 1))
            self.vertexCount = len(self.matrix)
        if edge2 >= self.vertexCount:
            for i in range(edge2 - self.vertexCount + 1):
                self.matrix.append([])
            self.vertexCount = len(self.matrix)
        self.matrix[edge1].append(edge2)
        self.matrix[edge2].append(edge1)

    def dfs(self, v, used):
        used[v] = 1
        print(v)
        for i in range(len(self.matrix[v])):
            next = self.matrix[v][i]
            if used[next] == 0:
                self.dfs(next, used)
        return

    def bfs(self, v):
        queue = []
        queue.append(v)
        used = [0] * gr.vertexCount
        used[v] = 1
        while len(queue) != 0:
            v = queue.pop(0)
            print(v)
            for i in range(len(self.matrix[v])):
                next = self.matrix[v][i]
                if used[next] == 0:
                    used[next] = 1
                    queue.append(next)

gr = graph()
s = input().split()
for i in range(0, len(s), 2):
    gr.add(s[i], s[i + 1])
# print(gr.matrix)
used = [0] * gr.vertexCount
# print(used)
# gr.dfs(0, used)
gr.bfs(0)


from math import *

def ngto(n):

    for i in range(2,isqrt(n)+1):
        if(n%i==0): return 0
    return n>1

def solve(s):
    st=s[-4:]
    if(ngto(int(st))): print('YES')
    else:print('NO')

t=int(input())
for _ in range(t):
    s=input()
    solve(s)


import pytube.exceptions
from pytube import YouTube
import tkinter
from tkinter import *
from tkinter import messagebox
fileSizeInBytes = 0
MaxFileSize = 0
def Downloader():
    def Download_full():
        def download():
            try:
                if len(B1.get())>1:
                    link =B1.get()
                    yt= YouTube(link)
                    title= yt.title
                    view= yt.views
                    ys = yt.streams.get_highest_resolution()
                    ys.download()
                    messagebox.showinfo("Done",f"You have downloaded {title}, which has {view} views in Youtube")
                else:
                    messagebox.showerror("Error","Pleace copy link")
            except pytube.exceptions.RegexMatchError:
                    messagebox.showerror("Error","Your link is incorrect")
            finally:
                    messagebox.showinfo("INFO", "THANKS FOR USING MY YOUTUBE DOWNLOADER")

        window.geometry('1000x250')
        B1=Entry(window,width=30,font=('Arial',15))
        B1.grid(row=3,column=1,padx=20,pady=20,sticky="W")
        L1=Label(window,text="Please Entry Your Link: ",width=25,font=('Arial',15))
        L1.grid(row=3,column=0,sticky="W")
        B3=Button(window,text="Download",command=download,font=("arial",25),background='green')
        B3.grid(row=7,column=0,pady=20,padx=20)
    window= tkinter.Tk()
    window.geometry('520x160')
    window.title("Youtube Downloader")
    window.config(background='blue')
    menubar= Menu()
    L=Label(window,text="Welcome in my Youtube Downloader",font=('Arial',20),background='orange')
    L.grid(row=0,column=0,padx=20,pady=20)
    filemenu = Menu(menubar, tearoff=0, background='#ffcc99', foreground='black')
    filemenu.add_command(label="Download full Movie",command=Download_full)
    filemenu.add_separator()
    filemenu.add_command(label="Quit",command=window.destroy)
    menubar.add_cascade(label="Options",menu=filemenu)
    window.config(menu=menubar)
    window.mainloop()
Downloader()


import discord
import webbrowser
import os, random
from discord.ext import commands

version = 1.2

intents = discord.Intents.default()
intents.message_content = True

bot = commands.Bot(command_prefix='/', intents=intents)
#RR
items = {
    'бумага': ['2 года', 'пункт приема макулатуры у населения', 'https://rimtest.ru/wp-content/uploads/Ofisnaya-bumaga.jpg', 'https://ru.wikipedia.org/wiki/%D0%91%D1%83%D0%BC%D0%B0%D0%B3%D0%B0'],
    'пластик': ['от 6 месяцев до 700 лет ', ' городские пункты приема вторсырья', 'https://www.ixbt.com/img/n1/news/2018/3/4/d_large.jpg', 'https://ru.wikipedia.org/wiki/%D0%9F%D0%BB%D0%B0%D1%81%D1%82%D0%BC%D0%B0%D1%81%D1%81%D1%8B']

}

@bot.event
async def on_ready():
    print(f'Logged in as {bot.user.name}')

@bot.command()
async def help(ctx):
    await ctx.send('/mem -- мемы; /info материал -- информация')

@bot.command()
async def version(ctx):
    await ctx.send(f'Версия бота: {version}')

@bot.command()
async def mem(ctx):
    list_sam = os.listdir('mems')
    img_name = random.choice(list_sam)
    with open(f'mems/{img_name}', 'rb') as f:
        picture = discord.File(f)

    await ctx.send(file=picture)

@bot.command()
async def info(ctx, item):
    lowitem = item.lower()
    webbrowser.open_new(items[lowitem][3])
    if lowitem in items:
        await ctx.send(items[lowitem][2])
        await ctx.send(f'Кратко: {lowitem} разлагается {items[lowitem][0]}. Можно сдать в {items[lowitem][1]}')
    else:
        await ctx.send('Материал не найден')

bot.run('MTEzMjI3NzQxMDYzNzgyNDA1MQ.G2-y_J.PN1Z4e7ibAvFUzOItELQEvmPG4UQaJPILXZPoo')


import abc
import functools

import typing
from typing import Any, Dict, Iterator, List, Optional, Sequence, Tuple, Union

from pyglove.core import object_utils
from pyglove.core import typing as pg_typing
from pyglove.core.symbolic import base
from pyglove.core.symbolic import dict as pg_dict
from pyglove.core.symbolic import schema_utils

class ObjectMeta(abc.ABCMeta):
  """Meta class for pg.Object."""

  @property
  def schema(cls) -> pg_typing.Schema:
    """Class level property for schema."""
    return getattr(cls, '__schema__', None)

  @property
  def sym_fields(cls) -> pg_typing.Dict:
    """Gets symbolic field."""
    return getattr(cls, '__sym_fields')

  @property
  def type_name(cls) -> str:
    """Class level property for type name.

    NOTE(daiyip): This is used for serialization/deserialization.

    Returns:
      String of <module>.<class> as identifier.
    """
    return f'{cls.__module__}.{cls.__name__}'

  @property
  def serialization_key(cls) -> str:
    """Gets serialization type key."""
    return getattr(cls, '__serialization_key__')

  @property
  def init_arg_list(cls) -> List[str]:
    """Gets __init__ positional argument list."""
    return cls.schema.metadata['init_arg_list']

# Use ObjectMeta as meta class to inherit schema and type_name property.
class Object(base.Symbolic, metaclass=ObjectMeta):
  """Base class for symbolic user classes.

  PyGlove allow symbolic programming interfaces to be easily added to most
  Python classes in two ways:

  * Developing a dataclass-like symbolic class by subclassing ``pg.Object``.
  * Developing a class as usual and decorate it using :func:`pyglove.symbolize`.
    This also work with existing classes.

  By directly subclassing ``pg.Object``, programmers can create new symbolic
  classes with the least effort. For example::

    @pg.members([
        # Each tuple in the list defines a symbolic field for `__init__`.
        ('name', pg.typing.Str().noneable(), 'Name to greet'),
        ('time_of_day',
        pg.typing.Enum('morning', ['morning', 'afternnon', 'evening']),
        'Time of the day.')
    ])
    class Greeting(pg.Object):

      def __call__(self):
        # Values for symbolic fields can be accessed
        # as public data members of the symbolic object.
        print(f'Good {self.time_of_day}, {self.name}')

    # Create an object of Greeting and invoke it,
    # which shall print 'Good morning, Bob'.
    Greeting('Bob')()

  Symbolic fields can be inherited from the base symbolic class: the fields
  from the base class will be copied to the subclass in their declaration
  order, while the subclass can override the inherited fields with more
  restricted validation rules or different default values. For example::

    @pg.members([
        ('x', pg.typing.Int(max_value=10)),
        ('y', pg.typing.Float(min_value=0))
    ])
    class Foo(pg.Object)
      pass

    @pg.members([
        ('x', pg.typing.Int(min_value=1, default=1)),
        ('z', pg.typing.Str().noneable())
    ])
    class Bar(Foo)
      pass

    # Printing Bar's schema will show that there are 3 parameters defined:
    # x : pg.typing.Int(min_value=1, max_value=10, default=1))
    # y : pg.typing.Float(min_value=0)
    # z : pg.typing.Str().noneable()
    print(Bar.schema)
  """

  # Disable pytype attribute checking.
  _HAS_DYNAMIC_ATTRIBUTES = True

  # Class property that indicates whether to allow attribute access on symbolic
  # members.
  allow_symbolic_attribute = True

  # Class property that indicates whether to allow to set or rebind symbolic
  # members by value assginment.
  allow_symbolic_assignment = False

  # Allow symbolic mutation using `rebind`.
  allow_symbolic_mutation = True

  # Class property that indicates whether to use `sym_eq` for `__eq__`,
  # `sym_ne` for `__ne__`, and `sym_hash` for `__hash__`.
  use_symbolic_comparison = True

  @classmethod
  def __init_subclass__(cls):
    super().__init_subclass__()

    # Inherit schema from base classes that have schema
    # in the ordered of inheritance.
    # TODO(daiyip): size of base_schema_list can be reduced
    # by looking at their inheritance chains.
    base_schema_list = []
    for base_cls in cls.__bases__:
      base_schema = getattr(base_cls, 'schema', None)
      if isinstance(base_schema, pg_typing.Schema):
        base_schema_list.append(base_schema)

    cls_schema = schema_utils.formalize_schema(
        pg_typing.create_schema(
            maybe_field_list=[],
            name=cls.type_name,
            base_schema_list=base_schema_list,
            allow_nonconst_keys=True,
            metadata={}))
    setattr(cls, '__schema__', cls_schema)
    setattr(cls, '__sym_fields', pg_typing.Dict(cls_schema))
    setattr(cls, '__serialization_key__', cls.type_name)
    cls_schema.metadata['init_arg_list'] = schema_utils.auto_init_arg_list(cls)
    cls._update_init_signature_based_on_schema()
    cls._generate_sym_attributes_if_enabled()

  @classmethod
  def _update_init_signature_based_on_schema(cls):
    """Updates the signature of `__init__` if needed."""
    if (cls.__init__ is not Object.__init__
        and not hasattr(cls.__init__, '__sym_generated_init__')):
      # We only generate `__init__` from pg.Object subclass which does not
      # override the `__init__` method.
      # Functor and ClassWrapper override their `__init__` methods, therefore
      # they need to synchronize the __init__ signature by themselves.
      return
    signature = pg_typing.get_init_signature(
        cls.schema, cls.__module__, '__init__', f'{cls.__name__}.__init__')
    pseudo_init = signature.make_function(['pass'])

    # Create a new `__init__` that passes through all the arguments to
    # in `pg.Object.__init__`. This is needed for each class to use different
    # signature.
    @functools.wraps(pseudo_init)
    def _init(self, *args, **kwargs):
      # We pass through the arguments to `Object.__init__` instead of
      # `super()` since the parent class uses a generated `__init__` will
      # be delegated to `Object.__init__` eventually. Therefore, directly
      # calling `Object.__init__` is equivalent to calling `super().__init__`.
      Object.__init__(self, *args, **kwargs)
    setattr(_init, '__sym_generated_init__', True)
    setattr(cls, '__init__', _init)

  @classmethod
  def _generate_sym_attributes_if_enabled(cls):
    """Generates symbolic attributes based on schema if they are enabled."""
    def _create_sym_attribute(attr_name, field):
      return property(object_utils.make_function(
          attr_name,
          ['self'],
          [f'return self._sym_attributes[\'{attr_name}\']'],
          return_type=field.value.annotation))

    if cls.allow_symbolic_attribute:
      for key, field in cls.schema.fields.items():
        if isinstance(key, pg_typing.ConstStrKey):
          attr_name = str(key)
          if not hasattr(cls, attr_name):
            setattr(cls, attr_name, _create_sym_attribute(attr_name, field))

  @classmethod
  def partial(cls, *args, **kwargs) -> 'Object':
    """Class method that creates a partial object of current class."""
    return cls(*args, allow_partial=True, **kwargs)

  @classmethod
  def from_json(
      cls,
      json_value: Any,
      *,
      allow_partial: bool = False,
      root_path: Optional[object_utils.KeyPath] = None) -> 'Object':
    """Class method that load an symbolic Object from a JSON value.

    Example::

        @pg.members([
          ('f1', pg.typing.Int()),
          ('f2', pg.typing.Dict([
            ('f21', pg.typing.Bool())
          ]))
        ])
        class Foo(pg.Object):
          pass

        foo = Foo.from_json({
            'f1': 1,
            'f2': {
              'f21': True
            }
          })

        # or

        foo2 = symbolic.from_json({
            '_type': '__main__.Foo',
            'f1': 1,
            'f2': {
              'f21': True
            }
        })

        assert foo == foo2

    Args:
      json_value: Input JSON value, only JSON dict is acceptable.
      allow_partial: Whether to allow elements of the list to be partial.
      root_path: KeyPath of loaded object in its object tree.

    Returns:
      A symbolic Object instance.
    """
    return cls(allow_partial=allow_partial, root_path=root_path, **json_value)

  def __init__(
      self,
      *args,
      allow_partial: bool = False,
      sealed: Optional[bool] = None,
      root_path: Optional[object_utils.KeyPath] = None,
      explicit_init: bool = False,
      **kwargs):
    """Create an Object instance.

    Args:
      *args: positional arguments.
      allow_partial: If True, the object can be partial.
      sealed: If True, seal the object from future modification (unless under
        a `pg.seal(False)` context manager). If False, treat the object as
        unsealed. If None, it's determined by `cls.allow_symbolic_mutation`.
      root_path: The symbolic path for current object. By default it's None,
        which indicates that newly constructed object does not have a parent.
      explicit_init: Should set to `True` when `__init__` is called via
        `pg.Object.__init__` instead of `super().__init__`.
      **kwargs: key/value arguments that align with the schema. All required
        keys in the schema must be specified, and values should be acceptable
        according to their value spec.

    Raises:
      KeyError: When required key(s) are missing.
      ValueError: When value(s) are not acceptable by their value spec.
    """
    # Placeholder for Google-internal usage instrumentation.

    if sealed is None:
      sealed = not self.__class__.allow_symbolic_mutation

    if not isinstance(allow_partial, bool):
      raise TypeError(
          f'Expect bool type for argument \'allow_partial\' in '
          f'symbolic.Object.__init__ but encountered {allow_partial}.')

    # We delay the seal attempt until members are all set.
    super().__init__(
        allow_partial=allow_partial,
        accessor_writable=self.__class__.allow_symbolic_assignment,
        sealed=sealed,
        root_path=root_path,
        init_super=not explicit_init)

    # Fill field_args and init_args from **kwargs.
    _, unmatched_keys = self.__class__.schema.resolve(list(kwargs.keys()))
    if unmatched_keys:
      arg_phrase = object_utils.auto_plural(len(unmatched_keys), 'argument')
      keys_str = object_utils.comma_delimited_str(unmatched_keys)
      raise TypeError(
          f'{self.__class__.__name__}.__init__() got unexpected '
          f'keyword {arg_phrase}: {keys_str}')

    field_args = {}
    # Fill field_args and init_args from *args.
    init_arg_names = self.__class__.init_arg_list
    if args:
      if not self.__class__.schema.fields:
        raise TypeError(f'{self.__class__.__name__}() takes no arguments.')
      elif init_arg_names and init_arg_names[-1].startswith('*'):
        vararg_name = init_arg_names[-1][1:]
        vararg_field = self.__class__.schema.get_field(vararg_name)
        assert vararg_field is not None

        num_named_args = len(init_arg_names) - 1
        field_args[vararg_name] = list(args[num_named_args:])
        args = args[:num_named_args]
      elif len(args) > len(init_arg_names):
        arg_phrase = object_utils.auto_plural(len(init_arg_names), 'argument')
        was_phrase = object_utils.auto_plural(len(args), 'was', 'were')
        raise TypeError(
            f'{self.__class__.__name__}.__init__() takes '
            f'{len(init_arg_names)} positional {arg_phrase} but {len(args)} '
            f'{was_phrase} given.')

      for i, arg_value in enumerate(args):
        arg_name = init_arg_names[i]
        field_args[arg_name] = arg_value

    for k, v in kwargs.items():
      if k in field_args:
        values_str = object_utils.comma_delimited_str([field_args[k], v])
        raise TypeError(
            f'{self.__class__.__name__}.__init__() got multiple values for '
            f'argument \'{k}\': {values_str}.')
      field_args[k] = v

    # Check missing arguments when partial binding is disallowed.
    if not base.accepts_partial(self):
      missing_args = []
      for field in self.__class__.schema.fields.values():
        if (not field.value.has_default
            and isinstance(field.key, pg_typing.ConstStrKey)
            and field.key not in field_args):
          missing_args.append(str(field.key))
      if missing_args:
        arg_phrase = object_utils.auto_plural(len(missing_args), 'argument')
        keys_str = object_utils.comma_delimited_str(missing_args)
        raise TypeError(
            f'{self.__class__.__name__}.__init__() missing {len(missing_args)} '
            f'required {arg_phrase}: {keys_str}.')

    self._set_raw_attr('_sym_attributes', pg_dict.Dict(
        field_args,
        value_spec=self.__class__.sym_fields,
        allow_partial=allow_partial,
        sealed=sealed,
        accessor_writable=self.__class__.allow_symbolic_assignment,
        root_path=root_path,
        pass_through_parent=True))
    self._sym_attributes.sym_setparent(self)
    self._on_init()
    self.seal(sealed)

  #
  # Events that subclasses can override.
  #

  def _on_init(self):
    """Event that is triggered at then end of __init__."""
    self._on_bound()

  def _on_bound(self) -> None:
    """Event that is triggered when any value in the subtree are set/updated.

    NOTE(daiyip): This is the best place to set derived members from members
    registered by the schema. It's called when any value in the sub-tree is
    modified, thus making sure derived members are up-to-date.

    When derived members are expensive to create/update, you can implement
    _init, _on_rebound, _on_subtree_rebound to update derived members only when
    they are impacted.

    _on_bound is not called on per-field basis, it's called at most once
    during a rebind call (though many fields may be updated)
    and during __init__.
    """

  def _on_change(self,
                 field_updates: Dict[object_utils.KeyPath, base.FieldUpdate]):
    """Event that is triggered when field values in the subtree are updated.

    This event will be called
      * On per-field basis when object is modified via attribute.
      * In batch when multiple fields are modified via `rebind` method.

    When a field in an object tree is updated, all ancestors' `_on_change` event
    will be triggered in order, from the nearest one to furthest one.

    Args:
      field_updates: Updates made to the subtree. Key path is relative to
        current object.

    Returns:
      it will call `_on_bound` and return the return value of `_on_bound`.
    """
    del field_updates
    return self._on_bound()

  def _on_path_change(
      self, old_path: object_utils.KeyPath, new_path: object_utils.KeyPath):
    """Event that is triggered after the symbolic path changes."""
    del old_path, new_path

  def _on_parent_change(
      self,
      old_parent: Optional[base.Symbolic],
      new_parent: Optional[base.Symbolic]):
    """Event that is triggered after the symbolic parent changes."""
    del old_parent, new_parent

  @property
  def sym_init_args(self) -> pg_dict.Dict:
    """Returns symbolic attributes which are the arguments for `__init__`."""
    return self._sym_attributes

  def sym_hasattr(self, key: Union[str, int]) -> bool:
    """Tests if a symbolic attribute exists."""
    if key == '_sym_attributes':
      raise ValueError(
          f'{self.__class__.__name__}.__init__ should call `super().__init__`.')
    return (isinstance(key, str)
            and not key.startswith('_') and key in self._sym_attributes)

  def sym_attr_field(
      self, key: Union[str, int]
      ) -> Optional[pg_typing.Field]:
    """Returns the field definition for a symbolic attribute."""
    return self._sym_attributes.sym_attr_field(key)

  def sym_keys(self) -> Iterator[str]:
    """Iterates the keys of symbolic attributes."""
    return self._sym_attributes.sym_keys()

  def sym_values(self):
    """Iterates the values of symbolic attributes."""
    return self._sym_attributes.sym_values()

  def sym_items(self):
    """Iterates the (key, value) pairs of symbolic attributes."""
    return self._sym_attributes.sym_items()

  def sym_eq(self, other: Any) -> bool:
    """Tests symbolic equality."""
    return self is other or (
        type(self) is type(other) and base.eq(
            self._sym_attributes, other._sym_attributes))   # pylint: disable=protected-access

  def sym_lt(self, other: Any) -> bool:
    """Tests symbolic less-than."""
    if type(self) is not type(other):
      return base.lt(self, other)
    return base.lt(self._sym_attributes, other._sym_attributes)  # pylint: disable=protected-access

  def sym_hash(self) -> int:
    """Symbolically hashing."""
    return base.sym_hash((self.__class__, base.sym_hash(self._sym_attributes)))

  def sym_setparent(self, parent: base.Symbolic):
    """Sets the parent of current node in the symbolic tree."""
    old_parent = self.sym_parent
    super().sym_setparent(parent)
    if old_parent is not parent:
      self._on_parent_change(old_parent, parent)

  def _sym_getattr(  # pytype: disable=signature-mismatch  # overriding-parameter-type-checks
      self, key: str) -> Any:
    """Get symbolic field by key."""
    return self._sym_attributes[key]

  def _sym_rebind(
      self, path_value_pairs: Dict[object_utils.KeyPath, Any]
      ) -> List[base.FieldUpdate]:
    """Rebind current object using object-form members."""
    if base.treats_as_sealed(self):
      raise base.WritePermissionError(
          f'Cannot rebind a sealed {self.__class__.__name__}.')
    return self._sym_attributes._sym_rebind(path_value_pairs)  # pylint: disable=protected-access

  def _sym_clone(self, deep: bool, memo: Any = None) -> 'Object':
    """Copy flags."""
    kwargs = dict()
    for k, v in self._sym_attributes.items():
      if deep or isinstance(v, base.Symbolic):
        v = base.clone(v, deep, memo)
      kwargs[k] = v
    return self.__class__(allow_partial=self._allow_partial,
                          sealed=self._sealed,
                          **kwargs)  # pytype: disable=not-instantiable

  def _sym_missing(self) -> Dict[str, Any]:
    """Returns missing values."""
    # Invalidate the cache of child attributes' missing values before calling
    # `Dict.sym_missing`.
    setattr(self._sym_attributes, '_sym_missing_values', None)
    return self._sym_attributes.sym_missing(flatten=False)

  def _sym_nondefault(self) -> Dict[str, Any]:
    """Returns non-default values."""
    # Invalidate the cache of child attributes' non-default values before
    # calling `Dict.sym_nondefault`.
    setattr(self._sym_attributes, '_sym_nondefault_values', None)
    return self._sym_attributes.sym_nondefault(flatten=False)

  def set_accessor_writable(self, writable: bool = True) -> 'Object':
    """Sets accessor writable."""
    self._sym_attributes.set_accessor_writable(writable)
    super().set_accessor_writable(writable)
    return self

  def seal(self, sealed: bool = True) -> 'Object':
    """Seal or unseal current object from further modification."""
    self._sym_attributes.seal(sealed)
    super().seal(sealed)
    return self

  def _update_children_paths(
      self,
      old_path: object_utils.KeyPath,
      new_path: object_utils.KeyPath) -> None:
    """Update children paths according to root_path of current node."""
    self._sym_attributes.sym_setpath(new_path)
    self._on_path_change(old_path, new_path)

  def _set_item_without_permission_check(  # pytype: disable=signature-mismatch  # overriding-parameter-type-checks
      self, key: str, value: Any) -> Optional[base.FieldUpdate]:
    """Set item without permission check."""
    return self._sym_attributes._set_item_without_permission_check(key, value)  # pylint: disable=protected-access

  @property
  def _subscribes_field_updates(self) -> bool:
    """Returns True if current object subscribes field updates.

    For pg.Object, this return True only when _on_change is overridden
    from subclass.
    """
    return self._on_change.__code__ is not Object._on_change.__code__  # pytype: disable=attribute-error

  def __setattr__(self, name: str, value: Any) -> None:
    """Set field value by attribute."""
    # NOTE(daiyip): two types of members are treated as regular members:
    # 1) All private members which prefixed with '_'.
    # 2) Public members that are not declared as symbolic members.
    if (not self.allow_symbolic_attribute
        or not self.__class__.schema.get_field(name)
        or name.startswith('_')):
      super().__setattr__(name, value)
    else:
      if base.treats_as_sealed(self):
        raise base.WritePermissionError(
            self._error_message(
                f'Cannot set attribute {name!r}: object is sealed.'))
      if not base.writtable_via_accessors(self):
        raise base.WritePermissionError(
            self._error_message(
                f'Cannot set attribute of <class {self.__class__.__name__}> '
                f'while `{self.__class__.__name__}.allow_symbolic_assignment` '
                f'is set to False or under `pg.as_sealed` context.'))
      self._sym_attributes[name] = value

  def __getattribute__(self, name: str) -> Any:
    """Override to accomondate symbolic attributes with variable keys."""
    try:
      return super().__getattribute__(name)
    except AttributeError as error:
      if not self.allow_symbolic_attribute or not self.sym_hasattr(name):
        raise error
      return self._sym_getattr(name)

  def __eq__(self, other: Any) -> bool:
    """Operator==."""
    if self.use_symbolic_comparison:
      return self.sym_eq(other)
    return super().__eq__(other)

  def __ne__(self, other: Any) -> bool:
    """Operator!=."""
    r = self.__eq__(other)
    if r is NotImplemented:
      return r
    return not r

  def __hash__(self) -> int:
    """Hashing function."""
    if self.use_symbolic_comparison:
      return self.sym_hash()
    return super().__hash__()

  def sym_jsonify(self, **kwargs) -> object_utils.JSONValueType:
    """Converts current object to a dict of plain Python objects."""
    return object_utils.merge([{
        object_utils.JSONConvertible.TYPE_NAME_KEY:
            self.__class__.serialization_key
    }, self._sym_attributes.to_json(**kwargs)])

  def format(self,
             compact: bool = False,
             verbose: bool = False,
             root_indent: int = 0,
             **kwargs) -> str:
    """Formats this object."""
    return self._sym_attributes.format(
        compact,
        verbose,
        root_indent,
        cls_name=self.__class__.__name__,
        bracket_type=object_utils.BracketType.ROUND,
        **kwargs)

base.Symbolic.ObjectType = Object

def members(
    fields: List[Union[
        pg_typing.Field,
        Tuple[Union[str, pg_typing.KeySpec], pg_typing.ValueSpec, str],
        Tuple[Union[str, pg_typing.KeySpec], pg_typing.ValueSpec, str, Any]]],
    metadata: Optional[Dict[str, Any]] = None,
    init_arg_list: Optional[Sequence[str]] = None,
    **kwargs
) -> pg_typing.Decorator:
  """Function/Decorator for declaring symbolic fields for ``pg.Object``.

  Example::

    @pg.members([
      # Declare symbolic fields. Each field produces a symbolic attribute
      # for its object, which can be accessed by `self.<field_name>`.
      # Description is optional.
      ('x', pg.typing.Int(min_value=0, default=0), 'Description for `x`.'),
      ('y', pg.typing.Str(), 'Description for `y`.')
    ])
    class A(pg.Object):
      def sum(self):
        return self.x + self.y

    @pg.members([
      # Override field 'x' inherited from class A and make it more restrictive.
      ('x', pg.typing.Int(max_value=10, default=5)),
      # Add field 'z'.
      ('z', pg.typing.Bool().noneable())
    ])
    class B(A):
      pass

    @pg.members([
      # Declare dynamic fields: any keyword can be acceptable during `__init__`
      # and can be accessed using `self.<field_name>`.
      (pg.typing.StrKey(), pg.typing.Int())
    ])
    class D(B):
      pass

    @pg.members([
      # Declare dynamic fields: keywords started with 'foo' is acceptable.
      (pg.typing.StrKey('foo.*'), pg.typing.Int())
    ])
    class E(pg.Object):
      pass

  See :class:`pyglove.typing.ValueSpec` for supported value specifications.

  Args:
    fields: A list of pg.typing.Field or equivalent tuple representation as
      (<key>, <value-spec>, [description], [metadata-objects]). `key` should be
      a string. `value-spec` should be pg_typing.ValueSpec classes or
      equivalent, e.g. primitive values which will be converted to ValueSpec
      implementation according to its type and used as its default value.
      `description` is optional only when field overrides a field from its
      parent class. `metadata-objects` is an optional list of any type, which
      can be used to generate code according to the schema.
    metadata: Optional dict of user objects as class-level metadata which will
      be attached to class schema.
    init_arg_list: An optional sequence of strings as the positional argument
      list for `__init__`. This is helpful when symbolic attributes are
      inherited from base classes or the user want to change its order.
      If not provided, the `init_arg_list` will be automatically generated
      from symbolic attributes defined from ``pg.members`` in their declaration
      order, from the base classes to the subclass.
    **kwargs: Keyword arguments for infrequently used options.
      Acceptable keywords are:

      * `serialization_key`: An optional string to be used as the serialization
        key for the class during `sym_jsonify`. If None, `cls.type_name` will be
        used. This is introduced for scenarios when we want to relocate a class,
        before the downstream can recognize the new location, we need the class
        to serialize it using previous key.
      * `additional_keys`: An optional list of strings as additional keys to
        deserialize an object of the registered class. This can be useful
        when we need to relocate or rename the registered class while being able
        to load existing serialized JSON values.

  Returns:
    a decorator function that register the class or function with schema
      created from the fields.

  Raises:
    TypeError: Decorator cannot be applied on target class or keyword argument
      provided is not supported.
    KeyError: If type has already been registered in the registry.
    ValueError: schema cannot be created from fields.
  """
  serialization_key = kwargs.pop('serialization_key', None)
  additional_keys = kwargs.pop('additional_keys', None)
  if kwargs:
    raise TypeError(f'Unsupported keyword arguments: {list(kwargs.keys())!r}.')

  def _decorator(cls):
    """Decorator function that registers schema with an Object class."""
    schema_utils.update_schema(
        cls,
        fields,
        metadata=metadata,
        init_arg_list=init_arg_list,
        serialization_key=serialization_key,
        additional_keys=additional_keys)
    return cls
  return typing.cast(pg_typing.Decorator, _decorator)


#!/usr/bin/env python
# coding: utf-8

# # Import required libraries

# In[ ]:

import numpy as np
import pandas as pd
import tensorflow as tf
from tensorflow.keras import layers
from tensorflow import keras
from tensorflow.keras.layers import BatchNormalization
from keras.models import Sequential, Model
from keras.layers import Input, Embedding, Dense, Flatten, Concatenate, Reshape
from keras import backend as K
from keras import regularizers
from tensorflow.keras.optimizers import Adam
from keras.callbacks import EarlyStopping, ModelCheckpoint
from keras.regularizers import l2
from tensorflow.keras.losses import Loss

# # Load Dataset

# In[ ]:

stock_price_df = pd.read_csv("../input/jpx-tokyo-stock-exchange-prediction/train_files/stock_prices.csv")

# In[ ]:

supp_df = pd.read_csv('/kaggle/input/jpx-tokyo-stock-exchange-prediction/supplemental_files/stock_prices.csv')
supp_df.head()

# In[ ]:

stock_price_df = pd.concat([stock_price_df,supp_df],axis=0).reset_index(drop=True)
del supp_df

# # A glance at the data

# In[ ]:

print('(rows, columns) =', stock_price_df.shape)
stock_price_df.tail()

# In[ ]:

stock_price_df['ExpectedDividend'] = stock_price_df['ExpectedDividend'].fillna(0)
stock_price_df['SupervisionFlag'] = stock_price_df['SupervisionFlag'].map({True: 1, False: 0})
stock_price_df['Date'] = pd.to_datetime(stock_price_df['Date'])
stock_price_df.info()

# # Import stock list
#

# In[ ]:

stock_list = pd.read_csv("../input/jpx-tokyo-stock-exchange-prediction/stock_list.csv")

# In[ ]:

stock_list = stock_list[['SecuritiesCode','NewMarketSegment','33SectorCode','17SectorCode','Universe0','Section/Products','NewIndexSeriesSize']]
stock_list = stock_list.replace(np.nan,'-')
stock_list['Universe0'] = np.where(stock_list['Universe0'], 1, 0)
stock_list = stock_list.drop_duplicates()
stock_list

# # Some Feature Engineering

# In[ ]:

def FE(stock_price_df):
    stock_price_df['BOP'] = (stock_price_df['Open']-stock_price_df['Close'])/(stock_price_df['High']-stock_price_df['Low'])
    stock_price_df['wp'] = (stock_price_df['Open']+stock_price_df['High']+stock_price_df['Low'])/3
    stock_price_df['TR'] = stock_price_df['High'] - stock_price_df['Low']
    # stock_price_df['AD'] = ta.AD(High, Low, Close, Volume)
    # stock_price_df['OBV']  = ta.OBV(Close, Volume)
    stock_price_df['OC'] = stock_price_df['Open'] * stock_price_df['Close']
    stock_price_df['HL'] = stock_price_df['High'] * stock_price_df['Low']
    stock_price_df['logC'] = np.log(stock_price_df['Close']+1)
    stock_price_df['OHLCstd'] = stock_price_df[['Open','Close','High','Low']].std(axis=1)
    stock_price_df['OHLCskew'] = stock_price_df[['Open','Close','High','Low']].skew(axis=1)
    stock_price_df['OHLCkur'] = stock_price_df[['Open','Close','High','Low']].kurtosis(axis=1)
    stock_price_df['Cpos'] = (stock_price_df['Close']-stock_price_df['Low'])/(stock_price_df['High']-stock_price_df['Low']) -0.5
    stock_price_df['bsforce'] = stock_price_df['Cpos'] * stock_price_df['Volume']
    stock_price_df['Opos'] = (stock_price_df['Open']-stock_price_df['Low'])/(stock_price_df['High']-stock_price_df['Low']) -0.5
    stock_price_df['Date'] = pd.to_datetime(stock_price_df['Date'])
    stock_price_df['weekday'] = stock_price_df['Date'].dt.weekday+1
    stock_price_df['Monday'] = np.where(stock_price_df['weekday']==1,1,0)
    stock_price_df['Tuesday'] = np.where(stock_price_df['weekday']==2,1,0)
    stock_price_df['Wednesday'] = np.where(stock_price_df['weekday']==3,1,0)
    stock_price_df['Thursday'] = np.where(stock_price_df['weekday']==4,1,0)
    stock_price_df['Friday'] = np.where(stock_price_df['weekday']==5,1,0)
    return stock_price_df
stock_price_df = FE(stock_price_df)
stock_price_df = pd.merge(stock_price_df,stock_list, on='SecuritiesCode')

# In[ ]:

subf = ['Open', 'High', 'Low', 'Close','Volume','Monday','Friday']

# # standardize features according to daily stock data (at the same day only)

# In[ ]:

def daily_standardize(df,col):
    avg = df[[col,'Date']].groupby('Date').mean()
    avg.columns = ['avg']
    avg['Date'] = avg.index
    avg = avg.reset_index(drop=True)
    std = df[[col,'Date']].groupby('Date').std()
    std.columns = ['std']
    std['Date'] = std.index
    std = std.reset_index(drop=True)
    df = pd.merge(df, avg, on='Date')
    df = pd.merge(df,std,on='Date')
    df[col] = (df[col] - df['avg'])/df['std']
    df = df.drop(['avg','std'],axis=1)
    df[col] = df[col].fillna(0)
    return df

# In[ ]:

from sklearn.preprocessing import StandardScaler
stdsc = StandardScaler()

# In[ ]:

for i in subf:
    stock_price_df = daily_standardize(stock_price_df,i)

# In[ ]:

stock_price_df = stock_price_df.fillna(0)
stock_price_df.head()

# # standardize "Target" as well

# In[ ]:

stock_price_df = daily_standardize(stock_price_df,'Target')

# In[ ]:

stock_price_df['Target'].head()

# In[ ]:

# stock_price_df['class'] = stock_price_df[['Target','Date']].groupby('Date').rank(ascending=False)-1

# In[ ]:

pct_low = stock_price_df[['Target','Date']].groupby('Date').quantile(0.05)
pct_low.columns = ['low']
pct_low['Date'] = pct_low.index
pct_low = pct_low.reset_index(drop=True)
pct_high = stock_price_df[['Target','Date']].groupby('Date').quantile(0.95)
pct_high.columns = ['high']
pct_high['Date'] = pct_high.index
pct_high = pct_high.reset_index(drop=True)

# In[ ]:

stock_price_df = pd.merge(stock_price_df,pct_low, on='Date')
stock_price_df = pd.merge(stock_price_df,pct_high, on='Date')
stock_price_df.head()

# In[ ]:

stock_price_df['class'] = np.where(stock_price_df['Target']>=stock_price_df['high'],1,np.where(stock_price_df['Target']<=stock_price_df['low'],-1,0))

# In[ ]:

stock_price_df = stock_price_df.drop(['high','low'],axis=1)

# In[ ]:

stock_price_df.head()

# In[ ]:

pct_low = stock_price_df[['Target','Date']].groupby('Date').quantile(0.1)
pct_low.columns = ['low']
pct_low['Date'] = pct_low.index
pct_low = pct_low.reset_index(drop=True)
pct_high = stock_price_df[['Target','Date']].groupby('Date').quantile(0.9)
pct_high.columns = ['high']
pct_high['Date'] = pct_high.index
pct_high = pct_high.reset_index(drop=True)
stock_price_df = pd.merge(stock_price_df,pct_low, on='Date')
stock_price_df = pd.merge(stock_price_df,pct_high, on='Date')
stock_price_df['class_2'] = np.where(stock_price_df['Target']>=stock_price_df['high'],1,np.where(stock_price_df['Target']<=stock_price_df['low'],-1,0))

# In[ ]:

stock_price_df = stock_price_df.drop(['high','low'],axis=1)

# In[ ]:

stock_price_df.head()

# In[ ]:

pct_low = stock_price_df[['Target','Date']].groupby('Date').quantile(0.2)
pct_low.columns = ['low']
pct_low['Date'] = pct_low.index
pct_low = pct_low.reset_index(drop=True)
pct_high = stock_price_df[['Target','Date']].groupby('Date').quantile(0.8)
pct_high.columns = ['high']
pct_high['Date'] = pct_high.index
pct_high = pct_high.reset_index(drop=True)
stock_price_df = pd.merge(stock_price_df,pct_low, on='Date')
stock_price_df = pd.merge(stock_price_df,pct_high, on='Date')
stock_price_df['class_3'] = np.where(stock_price_df['Target']>=stock_price_df['high'],1,np.where(stock_price_df['Target']<=stock_price_df['low'],-1,0))
stock_price_df = stock_price_df.drop(['high','low'],axis=1)
stock_price_df.head()

# In[ ]:

from lightgbm import LGBMClassifier as lgbmc
params = {'boosting_type':'dart',
         'learning_rate': 0.05,
         'n_estimators':100,
#           'num_leaves': 60,
          'max_depth':20,
         'objective':'multiclass',
         'class weight':'balanced',
         'random_state':88,
         'n_jobs':-1,
         'device':'gpu'}
lgb_model = lgbmc(**params)

# In[ ]:

temp = stock_price_df[stock_price_df['Date']>'2019-06-01']

# In[ ]:

from keras.metrics import CategoricalAccuracy as ca

# In[ ]:

def get_model():
    #investment_id_inputs = tf.keras.Input((1, ), dtype=tf.uint16)
    features_inputs = tf.keras.Input((len(subf), ), dtype=tf.float16)

#     investment_id_x = investment_id_lookup_layer(investment_id_inputs)
#     investment_id_x = layers.Embedding(investment_id_size, 4, input_length=1)(investment_id_x)
#     investment_id_x = layers.Reshape((-1, ))(investment_id_x)
#     investment_id_x = layers.Dense(16, activation='swish')(investment_id_x)
#     investment_id_x = layers.Dense(16, activation='swish')(investment_id_x)

    feature_x = layers.Dense(16, activation='swish')(features_inputs)
    feature_x = layers.Dense(16, activation='swish')(feature_x)

   # x = layers.Concatenate(axis=1)([investment_id_x, feature_x])
    x = layers.Dropout(0.2)(feature_x)
    x = layers.Dense(16,activation='swish')(x)
    x = layers.Dense(16,activation='swish')(x)
    x = layers.Dropout(0.2)(x)
    x = layers.Dense(16, activation='swish', kernel_regularizer="l2")(x)
    x = layers.Dense(16, activation='swish', kernel_regularizer="l2")(x)
    output = layers.Dense(3,activation='softmax')(x)
    cat_acc = ca(name='categorical_accuracy')
   # rmse = keras.metrics.RootMeanSquaredError(name="rmse")
    model = tf.keras.Model(inputs=[features_inputs], outputs=[output])
    model.compile(optimizer=tf.optimizers.Adam(0.01), loss='binary_crossentropy', metrics=['categorical_crossentropy',cat_acc,'kullback_leibler_divergence'])
    return model

# In[ ]:

def preprocess(X, y):
    print(X)
    print(y)
    return X, y
def make_dataset(feature, y, batch_size=32, mode="train"):
    ds = tf.data.Dataset.from_tensor_slices(((feature), y))
    ds = ds.map(preprocess)
    if mode == "train":
        ds = ds.shuffle(256)
    ds = ds.batch(batch_size).cache().prefetch(tf.data.experimental.AUTOTUNE)
    return ds

# In[ ]:

from sklearn.model_selection import GroupKFold
kfold = GroupKFold(n_splits = 5)

# In[ ]:

from numpy.random import seed
seed(888)
from tensorflow import random
random.set_seed(888)
count=0
df_x = stock_price_df[subf]
df_y=stock_price_df[['class','class_2','class_3']]
time_id = stock_price_df['Date']
dnn_models = []
for train_index, val_index in kfold.split(df_x, df_y,time_id):
    # Split training dataset.
    train_x, train_y = df_x.iloc[train_index], df_y.iloc[train_index]
  #  train_inv =stock_price_df['SecuritiesCode'].iloc[train_index]
    # Split validation dataset.
    val_x, val_y = df_x.iloc[val_index], df_y.iloc[val_index]
  #  val_inv =  stock_price_df['SecuritiesCode'].iloc[val_index]
    # Make tensor dataset.
    tf_train = make_dataset(train_x, train_y, batch_size=4096, mode="train")
    tf_val = make_dataset(val_x, val_y, batch_size=4096, mode="train")
    # Load model
    model=get_model()
    model.fit(tf_train, epochs = 4,
             validation_data = (tf_val), shuffle=True)
    model.save_weights('my_dnn_'+str(count)+'.tf')
    dnn_models.append(model)
    count+=1

    del tf_train
    del tf_val
    del model, train_x, train_y, val_x, val_y

# In[ ]:

def preprocess_test(feature):
    return (feature), 0

def make_test_dataset(feature, batch_size=1024):
    ds = tf.data.Dataset.from_tensor_slices(((feature)))
    ds = ds.map(preprocess_test)
    ds = ds.batch(batch_size).cache().prefetch(tf.data.experimental.AUTOTUNE)
    return ds

# In[ ]:

# model.predict(temp[subf].iloc[-1000:,:])

# In[ ]:

def classification_predict(models, ds):
    #some = model.predict_proba(ds)
    some=0
    for model in models:
        some += model.predict(ds)
   # return np.matmul(some,np.array([-1,0,1]))
    return np.matmul(some,np.array([0.5,0.25,0.125]))

# In[ ]:

classification_predict(dnn_models, make_test_dataset(temp[subf].iloc[-1000:,:]))

# # Tranform the "SecuritiesCode" of stock as well

# In[ ]:

# investment_ids = list(stock_price_df['SecuritiesCode'].unique())
# investment_id_size = len(investment_ids) + 1
# investment_id_lookup_layer = layers.IntegerLookup(max_tokens=investment_id_size)
# with tf.device("cpu"):
#     investment_id_lookup_layer.adapt(stock_price_df['SecuritiesCode'])

# ## Define the DNN model that separately trains "SecuritiesCode" & features, and then concatenate them together for the final training

# ## You can adjust number of layers, neurons, and etc.

# In[ ]:

# def get_model():
#     investment_id_inputs = tf.keras.Input((1, ), dtype=tf.uint16)
#     features_inputs = tf.keras.Input((len(subf), ), dtype=tf.float16)

#     investment_id_x = investment_id_lookup_layer(investment_id_inputs)
#     investment_id_x = layers.Embedding(investment_id_size, 4, input_length=1)(investment_id_x)
#     investment_id_x = layers.Reshape((-1, ))(investment_id_x)
#     investment_id_x = layers.Dense(16, activation='swish')(investment_id_x)
#     investment_id_x = layers.Dense(16, activation='swish')(investment_id_x)

#     feature_x = layers.Dense(16, activation='swish')(features_inputs)
#     feature_x = layers.Dense(16, activation='swish')(feature_x)

#     x = layers.Concatenate(axis=1)([investment_id_x, feature_x])
#     x = layers.Dense(16, activation='swish', kernel_regularizer="l2")(x)
#     x = layers.Dense(16, activation='swish', kernel_regularizer="l2")(x)
#     output = layers.Dense(1)(x)
#     rmse = keras.metrics.RootMeanSquaredError(name="rmse")
#     model = tf.keras.Model(inputs=[investment_id_inputs, features_inputs], outputs=[output])
#     model.compile(optimizer=tf.optimizers.Adam(0.05), loss='mse', metrics=['mse', "mae", "mape", rmse])
#     return model

# ## Transform the train data so that it can used for DNN model training.

# In[ ]:

# def preprocess(X, y):
#     print(X)
#     print(y)
#     return X, y
# def make_dataset(feature, investment_id, y, batch_size=32, mode="train"):
#     ds = tf.data.Dataset.from_tensor_slices(((investment_id, feature), y))
#     ds = ds.map(preprocess)
#     if mode == "train":
#         ds = ds.shuffle(256)
#     ds = ds.batch(batch_size).cache().prefetch(tf.data.experimental.AUTOTUNE)
#     return ds

# ## Use GroupKFold to train 5 DNN models (the same "Sector" stock should always be in the same group)

# In[ ]:

# from sklearn.model_selection import GroupKFold
# kfold = GroupKFold(n_splits = 10)

# In[ ]:

# count=0
# df_x = stock_price_df[subf]
# df_y=stock_price_df['Target']
# time_id = stock_price_df['33SectorCode']
# dnn_models = []
# for train_index, val_index in kfold.split(df_x, df_y,time_id):
#     # Split training dataset.
#     train_x, train_y = df_x.iloc[train_index], df_y.iloc[train_index]
#     train_inv =stock_price_df['SecuritiesCode'].iloc[train_index]
#     # Split validation dataset.
#     val_x, val_y = df_x.iloc[val_index], df_y.iloc[val_index]
#     val_inv =  stock_price_df['SecuritiesCode'].iloc[val_index]
#     # Make tensor dataset.
#     tf_train = make_dataset(train_x, train_inv, train_y, batch_size=12000, mode="train")
#     tf_val = make_dataset(val_x, val_inv, val_y, batch_size=12000, mode="train")
#     # Load model
#     model = get_model()

#     model.fit(tf_train, epochs = 10,
#              validation_data = (tf_val), shuffle=True)
#     model.save_weights('my_dnn_'+str(count)+'.tf')
#     dnn_models.append(model)
#     count+=1

#     del tf_train
#     del tf_val
#     del model, train_x, train_y, val_x, val_y

# ## average model predictions

# In[ ]:

# def infer(models, ds):
#     y_preds = []
#     for model in models:
#         y_pred = model.predict(ds)
#         y_preds.append(y_pred)
#     return np.mean(y_preds, axis=0)

# ## Transform test set so that it can be used for prediction

# In[ ]:

# def preprocess_test(investment_id, feature):
#     return (investment_id, feature), 0

# def make_test_dataset(feature, investment_id, batch_size=1024):
#     ds = tf.data.Dataset.from_tensor_slices(((investment_id, feature)))
#     ds = ds.map(preprocess_test)
#     ds = ds.batch(batch_size).cache().prefetch(tf.data.experimental.AUTOTUNE)
#     return ds

# ## Create features for the test set, standardize them, and use 5 DNN models averaging to make final prediction.

# In[ ]:

import jpx_tokyo_market_prediction
env = jpx_tokyo_market_prediction.make_env()   # initialize the environment
iter_test = env.iter_test()    # an iterator which loops over the test files
for (prices, options, financials, trades, secondary_prices, sample_prediction) in iter_test:

    prices['ExpectedDividend'] = prices['ExpectedDividend'].fillna(0)
    prices['SupervisionFlag'] = prices['SupervisionFlag'].map({True: 1, False: 0})
    prices = pd.merge(prices,stock_list, on='SecuritiesCode')

    prices = FE(prices)

    prices[subf] = StandardScaler().fit_transform(prices[subf])
    prices = prices.fillna(0)

   # prices['inference'] = -infer(dnn_models, make_test_dataset(prices[subf],prices['SecuritiesCode']))
  #  prices['inference'] = classification_predict(lgb_model, prices[subf])
    prices['inference'] = classification_predict(dnn_models, make_test_dataset(prices[subf]))
    prices['rank'] = prices['inference'].rank(method='first',ascending = False)-1
    prices['rank'] = prices['rank'].apply(lambda x: int(x))
    prices = prices.drop('Date',axis=1)

    sample_prediction = pd.merge(sample_prediction, prices, on=['SecuritiesCode'])[['Date','SecuritiesCode','rank']]
    sample_prediction['rank'] = sample_prediction['rank'].fillna(1000)
    sample_prediction.columns = ['Date','SecuritiesCode','Rank']
    print(sample_prediction)

    env.predict(sample_prediction)   # register your predictions

# In[ ]:

len(np.unique(sample_prediction['Rank']))

# In[ ]:

sample_prediction['Rank'].min(),sample_prediction['Rank'].max()

# In[ ]:

alt = prices.copy()
alt.head()


import joblib
import streamlit as st

model = joblib.load('modelk.sav')
names=['setosa','versicolor','verginica']

st.title("Predict iris type")

# Add sliders for input fields
sepal_length = st.slider("Sepal Length", float(8), float(5))
sepal_width = st.slider("Sepal Width", float(5), float(3))
petal_length = st.slider("Petal Length", float(7), float(2))
petal_width = st.slider("Petal Width", float(3), float(0.1))

button=st.button('Predict')

if(button):
    sepal_length_value=float(sepal_length)
    sepal_width_value=float(sepal_width)
    petal_length_value=float(petal_length)
    petal_width_value=float(petal_width)
    x=[[sepal_length_value,sepal_width_value,petal_length_value,petal_width_value]]
    predict=model.predict(x)
    st.text('{}'.format(names[predict[0]]))
    st.text('{}'.format(predict))


# Vertex class to represent graph nodes
class Vertex:
    def __init__(self, name):
        self.name = name
        self.neighbors = list()
        self.distance = 99999
        self.visited = False
        self.discovery = 0
        self.finish = 0

    def add_neighbor(self, vertex):
        if vertex not in self.neighbors:
            self.neighbors.append(vertex)
            # store neighbors in sorted list
            self.neighbors.sort()


from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello_world():
    x = 0
    for i in range(1,90000000):
        x = x+1
        x = x-1
    return 'Hello, World!'

if __name__ == "__main__":
    app.run('0.0.0.0',port=5000,debug=True,threaded=True)


import itertools as it
import sys
import os

start = sys.argv[1]
finish = sys.argv[2]

origin_1 = os.path.expanduser("~") + "/data_ref/normal_sample/ERR160124_1.fastq"
origin_2 = os.path.expanduser("~") + "/data_ref/normal_sample/ERR160124_2.fastq"
target_1 = "./Data/patient_1/Normal/subset_normal_{start}_{finish}_1.fastq".format(start=start,finish=finish)
target_2 = "./Data/patient_1/Normal/subset_normal_{start}_{finish}_2.fastq".format(start=start,finish=finish)

files = [(origin_1,target_1),(origin_2,target_2)]

for (origin, target) in files:
    with open(origin, 'r') as origin_file:
        with open(target, 'w') as target_file:
            begin = int(start)*4
            end = int(finish)*4
            partial_lines = it.islice(origin_file, begin, end)
            for line in partial_lines:
                stripped_line = line.strip()
                print(stripped_line, file=target_file)

# %%


"""
∗ CSCI3180 Principles of Programming Languages ∗
∗ --- Declaration --- ∗
∗ I declare that the assignment here submitted is original except for source
∗ material explicitly acknowledged. I also acknowledge that I am aware of
∗ University policy and regulations on honesty in academic work, and of the
∗ disciplinary guidelines and procedures applicable to breaches of such policy
∗ and regulations, as contained in the website
∗ http://www.cuhk.edu.hk/policy/academichonesty/ ∗
∗ Assignment 2
∗ Name : Feng Haolin
∗ Student ID : 1155110663
∗ Email Addr : hlfeng8@cse.cuhk.edu.hk ∗/
"""

from Pos import Pos

class Task4Merchant():
    def __init__(self):
        self.__elixir_price = 1
        self.__shield_price = 2
        self.__pos = Pos()

    def action_on_soldier(self,soldier):
        sc=input("Do you want to buy something? (1. Elixir, 2. Shield, 3. Leave.) Input: ")
        if(sc == '1'):
            if(soldier.get_coin() >= self.__elixir_price):
                soldier.add_elixir()
                soldier.lose_coin(self.__elixir_price)
                self.talk("You bought an Elixir.\n\n")
            else:
                self.talk("You don't have enough coins.\n\n")
        elif(sc == '2'):
            if(soldier.get_coin() >= self.__shield_price):
                soldier.add_shield()
                soldier.lose_coin(self.__shield_price)
                self.talk("You bought a shield.\n\n")
            else:
                self.talk("You don't have enough coins.\n\n")
        elif(sc == '3'):
            self.talk("Thank you for coming. :D\n\n")
        else:
            print("=> Illegal choice!\n\n")

    def talk(self,text):
        print("Merchant$",text,end='')

    def set_pos(self,row,col):
        self.__pos.set_pos(row,col)

    def get_pos(self):
        return self.__pos

    def display_symbol(self):
        print("$",end='')