from django.db import models
from django.contrib.postgres import *
from datetime import datetime, timedelta
from django.utils import timezone

class manufacturer(models.Model):
    manufacturers = (
        ('asrock', 'asrock'),
        ('amd', 'amd'),
        ('intel', 'intel'),
        ('aorus', 'aorus'),
        ('asus', 'asus'),
        ('colorful', 'colorful'),
        ('coolermaster', 'coolermaster'),
        ('corsair', 'corsair'),
        ('crucial', 'crucial'),
        ('evga', 'evga'),
        ('gigabyte', 'gigabyte'),
        ('gskill', 'gskill'),
        ('lianli', 'lianli'),
        ('msi', 'msi'),
        ('noctua', 'noctua'),
        ('nvidia', 'nvidia'),
        ('nzxt', 'nzxt'),
        ('pny', 'pny'),
        ('powercolor', 'powercolor'),
        ('razer', 'razer'),
        ('sapphire', 'sapphire'),
        ('samsung', 'samsung'),
        ('siliconpower', 'siliconpower'),
        ('teamGroup', 'teamGroup'),
        ('thermaltake', 'thermaltake'),
        ('vcolor', 'vcolor'),
        ('xfx', 'xfx'),
        ('xpg', 'xpg'),
        ('zotac', 'zotac'),
        ('seagate', 'seagate'),
        ('westerndigital', 'westerndigital'),
        ('zotac', 'zotac'),
    )
    ID   = models.CharField(primary_key=True, null=False, blank=False, max_length=10)
    name = models.CharField(max_length=50, null=True, blank=True)
    manufactures_cpu           = models.BooleanField(verbose_name='Makes CPU', null=True, blank=True)
    manufactures_gpu           = models.BooleanField(verbose_name='Makes GPU', null=True, blank=True)
    manufactures_motherboard   = models.BooleanField(verbose_name='Makes Motherboards', null=True, blank=True)
    manufactures_ram           = models.BooleanField(verbose_name='Makes RAM', null=True, blank=True)
    manufactures_ssd           = models.BooleanField(verbose_name='Makes SSD', null=True, blank=True)
    manufactures_hdd           = models.BooleanField(verbose_name='Makes HDD', null=True, blank=True)
    manufactures_psu           = models.BooleanField(verbose_name='Makes PSU', null=True, blank=True)
    manufactures_case          = models.BooleanField(verbose_name='Makes Cases', null=True, blank=True)
    manufactures_cooler        = models.BooleanField(verbose_name='Makes Coolers', null=True, blank=True)

    def __str__(self):
        return f"{self.name}"

    class Meta:
        verbose_name ='Manufacturer'
        verbose_name_plural ='Manufacturers'
        app_label = 'Parts'

#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

class commoninfo(models.Model):
    ID                  = models.CharField(primary_key=True, max_length=15)
    manufacturer        = models.ForeignKey('manufacturer',  related_name="%(class)s_related", on_delete=models.CASCADE, default='')
    name                = models.CharField(max_length=150)
    data_added          = models.DateField(auto_now_add=True, null=True)
    amazon_url          = models.TextField(null=True)
    newegg_url          = models.TextField(null=True)
    #bestbuy_url        = models.TextField(null=True)
    rating              = models.FloatField(null=True)
    amazon_price        = models.FloatField(null=True)
    newegg_price        = models.FloatField(null=True)
    #bestbuy_price      = models.FloatField(null=True)
    previous_price      = models.FloatField(null=True, default=0.0)
    current_price       = models.FloatField(null=True, blank=True)
    lowest_Price_Link   = models.URLField(null=True, blank=True)
    last_modified       = models.DateField(auto_now=True)

    class Meta:
        abstract = True
        app_label = 'Parts'

#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

class cpu(commoninfo):
    Sockets = (
        ('AM4', 'AM4'),
        ('LGA 1700', 'LGA 1700'),
        ('LGA 1200', 'LGA 1200')
    )
    cores               = models.PositiveIntegerField()#WANTED
    threads             = models.PositiveIntegerField()#WANTED
    base_speed          = models.FloatField()#WANTED
    boost_speed         = models.FloatField()#WANTED
    overclockable       = models.BooleanField()#WANTED
    socket              = models.CharField(choices=Sockets, max_length=15)#WANTED
    cooler              = models.BooleanField(help_text='eg: amd ryzen 3600', verbose_name='Comes with cooler')#WANTED
    power_consumption   = models.PositiveIntegerField(null=True)#WANTED
    integrated_graphics = models.BooleanField(null=True)#WANTED
    use_case            = models.CharField(choices=(('Budget', 'Budget'), ('Mid-Range', 'Mid-Range'), ('High-end', 'High-end')), max_length=15)

    def __str__(self):
        return f"{self.Model_name} ({self.ID})"

    class Meta:
        verbose_name ='CPU'
        verbose_name_plural ='CPUs'

    def is_valid_cpu(self):
        condition = True
        manufacturer = self.manufacturer
        if manufacturer.manufactures_cpu == False:
            print('This manufacturer does not make cpus')
            condition = False
        if self.threads > self.cores:
            condition = False
        if (manufacturer.name.lower() == 'intel') and (self.cooler == True):
            condition = False
        return condition

#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

class aircooler(commoninfo):
    sockets = [
        ('AM4', 'AM4'),
        ('LGA 1700', 'LGA 1700'),
        ('LGA 1200', 'LGA 1200'),
        ('LGA 1151', 'LGA 1151'),
        ('All', 'AMD INTEL'),
    ]

    sizes = (
        ('ATX', 'ATX'),
        ('MicroAtx', 'MicroAtx'),
        ('MiniItx', 'MiniItx')
    )
    socket            = models.CharField(choices=sockets, max_length=15)#WANTED
    size              = models.CharField(choices=sizes, max_length=10)#WANTED
    height            = models.FloatField()#WANTED
    width             = models.FloatField()#WANTED
    num_fans          = models.PositiveIntegerField()#WANTED
    num_heatsinks     = models.PositiveIntegerField()#WANTED
    color_name        = models.CharField(default='Black', max_length=15) #Write the color name corresponding to the Hex value below #WANTED
    color_hex         = models.CharField(default='#RRGGBB', max_length=8) #Write the color value as a hex string #WANTED
    rgb               = models.BooleanField()#WANTED
    power_consumption = models.IntegerField(null=True)#WANTED
    theme             = models.CharField(choices=(('dark', 'dark'), ('light', 'light')), verbose_name='Color Theme', max_length=10)#WANTED
    use_case          = models.CharField(choices=(('Budget', 'Budget'), ('Mid-Range', 'Mid-Range'), ('High-end', 'High-end')), max_length=15)

    def __str__(self):
        return f"{self.name}"

    class Meta:
        verbose_name ='Aircooler'
        verbose_name_plural ='Aircoolers'

    def is_valid_aircooler(self):
        condition = True
        manufacturer = self.manufacturer
        if manufacturer.manufactures_cooler == False:
            print('This manufacturer does not make coolers')
            condition = False
        if (self.price < 50.0) and (self.use_case == 'High-end'):
            condition = False
        if (self.color_name.lower() == 'black') and (self.theme == 'light'):
            condition = False
        return condition

#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

class watercooler(commoninfo):
    sockets = (
        (1, 'AM4'),
        (2, 'LGA 1700'),
        (3, 'LGA 1200'),
        (4, 'LGA 1151'),
        (5, 'LGA 1700 and LGA 1151'),
        (6, 'AM4 and LGA 1700 and LGA 1151'),
    )

    sizes = (
        ('Large', 'Large'),
        ('Average', 'Average'),
        ('Small', 'Small')
    )
    socket            = models.IntegerField(choices=sockets)#WANTED
    size              = models.CharField(choices=sizes, max_length=10)#WANTED
    length            = models.FloatField()#WANTED
    width             = models.FloatField()#WANTED
    num_fans          = models.PositiveIntegerField()#WANTED
    color_name        = models.CharField(default='Black', max_length=15) #Write the color name corresponding to the Hex value below #WANTED
    color_hex         = models.CharField(default='#RRGGBB', max_length=8) #Write the color value as a hex string #WANTED
    rgb               = models.BooleanField()#WANTED
    power_consumption = models.PositiveIntegerField(null=True)#WANTED
    theme             = models.CharField(choices=(('dark', 'dark'), ('light', 'light')), verbose_name='Color Theme', max_length=15)#WANTED
    use_case          = models.CharField(choices=(('Budget', 'Budget'), ('Mid-Range', 'Mid-Range'), ('High-end', 'High-end')), max_length=15)

    def __str__(self):
        return f"{self.name}"

    class Meta:
        verbose_name ='Watercooler'
        verbose_name_plural ='Watercoolers'

    def is_valid_watercooler(self):
        condition = True
        manufacturer = self.manufacturer
        if manufacturer.manufactures_cpu == False:
            print('This manufacturer does not make cpus')
            condition = False
        if self.threads > self.cores:
            condition = False
        if (manufacturer.name.lower() == 'intel') and (self.cooler == True):
            condition = False
        return condition

#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

class gpu(commoninfo):
    type                 = models.CharField(choices=(('Nvidia GTX','Nvidia GTX'), ('Nvidia RTX','Nvidia RTX'), ('AMD Radeon', 'AMD Radeon')), max_length=15, verbose_name='Type')#WANTED
    atx                  = models.BooleanField(null=True, blank=True)#WANTED
    micro_atx            = models.BooleanField(null=True, blank=True)#WANTED
    mini_itx             = models.BooleanField(null=True, blank=True)#WANTED
    length               = models.FloatField(help_text='*in inches')#WANTED
    height               = models.FloatField(help_text='*in inches')#WANTED
    width                = models.FloatField(help_text='*in inches')#WANTED
    fan_count            = models.IntegerField(choices=((0, 0), (1, 1), (2, 2), (3, 3)))#WANTED
    vram                 = models.PositiveIntegerField(verbose_name='Memory (VRAM)')#WANTED
    gddr_type            = models.CharField(choices=(("GDDR6X", "GDDR6X"), ('GDDR6', 'GDDR6'), ('GDDR5X', 'GDDR5X'), ('GDDR5', 'GDDR5')), verbose_name='GDDR', max_length=10)#WANTED
    cude_cores           = models.IntegerField(null=True, blank=True)
    stream_processors    = models.IntegerField(null=True, blank=True)
    base_clock           = models.IntegerField() #in MHz #WANTED
    boost_clock          = models.IntegerField() #in MHz #WANTED
    multimonitor_support = models.BooleanField()
    monitor_count        = models.PositiveIntegerField()
    supported_resolution = models.CharField(verbose_name='Maximum supported resolutions', choices=(('1K', '1K'), ('2K', '2K'), ('4K', '4K'), ('5K', '5K'), ('8K', '8K')), max_length=5)#WANTED
    pcie_5_support       = models.BooleanField(verbose_name='Supports PCIe 5') #  gen of either pcie or ddr, then #WANTED
    pcie_4_support       = models.BooleanField(verbose_name='Supports PCIe 4') #  it automatically supports gen 4 #WANTED
    rgb                  = models.BooleanField(verbose_name='RGB Lighting', help_text="ONLY RGB LIGHT THAT'S PART OF THE MOBO")#WANTED
    pins_num             = models.PositiveIntegerField(verbose_name='Pins required', help_text='Number of pins to power the card')
    has_displayport      = models.BooleanField()
    displayport_count    = models.PositiveIntegerField()#WANTED
    has_hdmi             = models.BooleanField()
    hdmi_count           = models.PositiveIntegerField()#WANTED
    has_usbc             = models.BooleanField(verbose_name='Supports USB-C')
    usbc_count           = models.PositiveIntegerField(verbose_name='USB-C ports count')#WANTED
    theme                = models.CharField(choices=(('dark', 'dark'), ('light', 'light')), verbose_name='Color Theme', max_length=15)#WANTED
    power_consumption    = models.PositiveIntegerField(null=True) #In watts #WANTED
    use_case             = models.CharField(choices=(('Budget', 'Budget'), ('Mid-Range', 'Mid-Range'), ('High-end', 'High-end')), max_length=15)

    def __str__(self):
        return f"{self.name}"

    class Meta:
        verbose_name ='GPU'
        verbose_name_plural ='GPUs'

    def is_valid_gpu(self):
        condition = True
        if (self.has_hdmi == True and self.hdmi_count > 0) and (self.has_displayport == True and self.displayport_count > 0) and \
        (self.has_usbc == True and self.usbc_count > 0) and (self.base_clock < self.boost_clock) and (self.pcie_4_support == True and self.pcie_5_support == True):
            condition = True
        return condition

#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

class motherboard(commoninfo):
    Sockets = (
        ('AM5', 'AM5'),
        ('AM4', 'AM4'),
        ('LGA 1700', 'LGA 1700'),
        ('LGA 1200', 'LGA 1200'),
        ('LGA 1151', 'LGA 1151'),
    )

    sizes = (
        ('ATX', 'ATX'),
        ('Micro-ATX', 'Micro-ATX'),
        ('Mini-ITX', 'Mini-ITX'),
    )
    socket               = models.CharField(choices=Sockets, max_length=15, verbose_name='Socket support') #WANTED
    size                 = models.CharField(choices=sizes, max_length=15, verbose_name='Size (form factor)')#WANTED
    ram_slots            = models.IntegerField(choices=((4,4), (2,2)), verbose_name='How many ram slots',null=True, blank=True)#WANTED
    ddr_5_support        = models.BooleanField(verbose_name='Supports DDR5 RAM') #WANTED
    ddr_4_support        = models.BooleanField(verbose_name='Supports DDR4 RAM') #  - if a mobo supports a 5th #WANTED
    pcie_5_support       = models.BooleanField(verbose_name='Supports PCIe 5') #  gen of either pcie or ddr, then #WANTED
    pcie_4_support       = models.BooleanField(verbose_name='Supports PCIe 4') #  it automatically supports gen 4 #WANTED
    wifi                 = models.BooleanField(help_text='Does it allow WIFI connectivity (without a cable)', verbose_name='Supports Wireless Connectivity')#WANTED
    wifi_6_support       = models.BooleanField(verbose_name='Supports WIFI 6')
    lan_support          = models.BooleanField(verbose_name='Supports LAN Connectivity')
    fan_headers          = models.PositiveIntegerField(help_text='How many fan pins on the motherboards, basically how many fans can be directly connected \n Check motherboard description on official website for more help', verbose_name='Fan Headers count')
    rgb                  = models.BooleanField(verbose_name='RGB Lighting', help_text="ONLY RGB LIGHT THAT'S PART OF THE MOBO") #WANTED
    rgb_headers          = models.PositiveIntegerField(verbose_name='RGB Headers count', help_text='How many pins onboard can be used to power RGB in other components')
    argb_headers         = models.PositiveIntegerField()
    has_hdmi             = models.BooleanField()
    hdmi_count           = models.PositiveIntegerField()#WANTED
    has_displayport      = models.BooleanField()
    displayport_count    = models.PositiveIntegerField()#WANTED
    has_usbc             = models.BooleanField(verbose_name='Supports USB-C')
    usbc_count           = models.PositiveIntegerField(verbose_name='USB-C ports count')#WANTED
    usb3point2_support   = models.BooleanField(verbose_name='USB3.2 support')
    usb3point2_count     = models.IntegerField(verbose_name='USB3.2 count', null=True)
    usb_count            = models.IntegerField(verbose_name='USB count', null=True)#WANTED
    mdot2_SSD_slots      = models.PositiveIntegerField(verbose_name='Number of M.2 slots')#WANTED
    sata_slots           = models.PositiveIntegerField(verbose_name='Number of SATA slots', null=True)#WANTED
    integrated_io_sheild = models.BooleanField(help_text='Does it have a built in cover on the rear ports', verbose_name='Integrated IO sheild')#WANTED
    theme                = models.CharField(choices=(('dark', 'dark'), ('light', 'light')), verbose_name='Color Theme', max_length=15)#WANTED
    use_case             = models.CharField(choices=(('Budget', 'Budget'), ('Mid-Range', 'Mid-Range'), ('High-end', 'High-end')), max_length=15)

    def __str__(self):
        return f"{self.name}"

    class Meta:
        verbose_name ='Motherboard'
        verbose_name_plural ='Motherboards'

    def is_valid_motherboard(self):
        condition = True
        if (self.wifi == False and self.wifi_6_support == True) or (self.has_hdmi == False and self.hdmi_count > 0) or (self.has_displayport == False and self.displayport_count > 0) or (self.has_usbc == False and self.usbc_count > 0):
            condition = False
        return condition

#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

class ram(commoninfo):
    number_of_channels = (
        ('Single', 'Single'),
        ('Dual', 'Dual'),
        ('Four', 'Four')
    )

    ram_capacity = (
        (4, 4),
        (8, 8),
        (16, 16),
        (32, 32),
        (64, 64),
        (128, 128)
    )

    ddr_type = (
        ('DDR4', 'DDR4'),
        ('DDR5', 'DDR5')
    )
    capacity          = models.PositiveIntegerField(choices=ram_capacity)#WANTED
    divided_capacity  = models.CharField(choices=(('4x2', '4x2'),('4x4', '4x4'),('8x2', '8x2'),('8x4', '8x4'),('16x2', '16x2'),('16x4', '16x4'),('32x2', '32x2'),('32x4', '32x4'),), help_text='How many sticks to make up total RAM capacity', max_length=10) #WANTED
    channels          = models.CharField(choices=number_of_channels, max_length=20)#WANTED
    height            = models.FloatField(verbose_name="How tall", help_text='In mm (milimeter')#WANTED
    speed             = models.IntegerField() #WANTED
    type              = models.CharField(choices=ddr_type, max_length=5)#WANTED
    pins              = models.PositiveIntegerField()
    xmp               = models.BooleanField()
    color_name        = models.CharField(default='Black', max_length=15) #Write the color name corresponding to the Hex value below #WANTED
    color_hex         = models.CharField(default='#RRGGBB', max_length=8) #Write the color value as a hex string #WANTED
    power_consumption = models.PositiveIntegerField(null=True) #WANTED
    rgb               = models.BooleanField() #WANTED
    use_case          = models.CharField(choices=(('Budget', 'Budget'), ('Mid-Range', 'Mid-Range'), ('High-end', 'High-end')), max_length=15)

    def __str__(self):
        return f"{self.name}"

    class Meta:
        verbose_name ='RAM'
        verbose_name_plural ='RAMs'

    def is_valid_ram(self):
        condition = True
        manufacturer = self.manufacturer
        if manufacturer.manufactures_cpu == False:
            print('This manufacturer does not make cpus')
            condition = False
        if self.threads > self.cores:
            condition = False
        if (manufacturer.name.lower() == 'intel') and (self.cooler == True):
            condition = False
        return condition

#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

class hdd(commoninfo):
    rpm = (
        (3600, 3600),
        (4200, 4200),
        (5400, 5400),
        (7200, 7200),
        (1000, 1000)
    )

    sata = (
        (1.0, 1.0),
        (1.5, 1.5),
        (3.0, 3.0),
        (6.0, 6.0),
    )

    cache = (
        (64, 64),
        (128, 128),
        (256, 256),
        (512, 512),
    ) #in megabytes

    size = (
        (1, 1),
        (1.8, 1.8),
        (2.5, 2.5),
        (3.5, 3.5),
    ) #in inches
    capacity          = models.PositiveIntegerField() #in gb, tb values will be altered on the frontend #WANTED
    cache             = models.PositiveIntegerField() #in mb, tb values will be altered on the frontend #WANTED
    speed             = models.PositiveIntegerField(choices=rpm) #in GhZ #WANTED
    size              = models.FloatField(choices=size, null=True) #in GhZ #WANTED
    connectivity      = models.CharField(help_text='What is the connectivity type, (eg: number of pins, cable type)', max_length=20) #WANTED
    rgb               = models.BooleanField() #WANTED
    power_consumption = models.PositiveIntegerField(null=True) #WANTED
    use_case          = models.CharField(choices=(('Budget', 'Budget'), ('Mid-Range', 'Mid-Range'), ('High-end', 'High-end')), max_length=15)

    def __str__(self):
        return f"{self.name}"
    class Meta:
        verbose_name ='HDD'
        verbose_name_plural ='HDDs'

    def is_valid_hdd(self):
        condition = True
        manufacturer = self.manufacturer
        if manufacturer.manufactures_cpu == False:
            print('This manufacturer does not make cpus')
            condition = False
        if self.threads > self.cores:
            condition = False
        if (manufacturer.name.lower() == 'intel') and (self.cooler == True):
            condition = False
        return condition

#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

class ssd(commoninfo):
    connectivity = (
        ('SATA 3', 'SATA 3'),
        ('Micro-SATA', 'Micro-SATA'),
        ('Mini-SATA', 'Mini-SATA'),
        ('Mini-PCIe', 'Mini-PCIe'),
        ('PCIe-Express 3.0', 'PCIe-Express 3.0'),
        ('PCIe-Express 3.1', 'PCIe-Express 3.1'),
        ('PCIe-Express 4.0', 'PCIe-Express 4.0'),
        ('PCIe-Express 4.0', 'PCIe-Express 4.0'),
        ('Thunderbolt 3', 'Thunderbolt 3'),
    )

    size = (
        ('1.0', '1.0'),
        ('2.5', '2.5'),
        ('3.5', '3.5'),
        ('M.2', 'M.2'),
        ('mSATA', 'mSATA'),
        ('AIC', 'AIC'),
    ) #in inches
    capacity          = models.PositiveIntegerField() #in gb, tb values will be altered on the frontend #WANTED
    read_speed        = models.PositiveIntegerField() #in MbPs #WANTED
    write_speed       = models.PositiveIntegerField() #in MbPs #WANTED
    form_factor       = models.CharField(choices=size, max_length=20) #WANTED
    height            = models.FloatField() #WANTED
    interface         = models.CharField(choices=connectivity, help_text='What is the connectivity type, (eg: number of pins, cable type)', max_length=20) #WANTED
    power_consumption = models.PositiveIntegerField(null=True) #WANTED
    rgb               = models.BooleanField() #WANTED
    use_case          = models.CharField(choices=(('Budget', 'Budget'), ('Mid-Range', 'Mid-Range'), ('High-end', 'High-end')), max_length=15)
    def __str__(self):
        return f"{self.name}"

    class Meta:
        verbose_name ='SSD'
        verbose_name_plural ='SSDs'

    def is_valid_ssd(self):
        condition = True
        manufacturer = self.manufacturer
        if manufacturer.manufactures_cpu == False:
            print('This manufacturer does not make cpus')
            condition = False
        if self.threads > self.cores:
            condition = False
        if (manufacturer.name.lower() == 'intel') and (self.cooler == True):
            condition = False
        return condition

#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

class psu(commoninfo):
    ratings = (
        ('Bronze', 'Bronze'),
        ('Silver', 'Silver'),
        ('Gold', 'Gold'),
        ('Platinum', 'Platinum')
    )

    connectivity = (
        ('Full Modular', 'Full Modular'),
        ('Semi Modular', 'Semi Modular'),
        ('None Modular', 'None Modular'),
    )

    mobo_size = (
        # (1, 'ATX only'),
        # (2, 'Micro-ATX'),
        # (3, 'ATX and Micro-ITX'),
        # (4, 'Micro-ATX and Mini-ITX'),
        # (4, 'Mini-ITX only'),
        ('ATX', 'ATX'),
        ('Micro-ATX', 'Micro-ATX'),
        ('Mini-ITX', 'Mini-ITX')
    )
    wattage           = models.PositiveIntegerField() #WANTED
    rating            = models.CharField(choices=ratings, max_length=10) #WANTED
    connection        = models.CharField(choices=connectivity, max_length=15) #WANTED
    size              = models.IntegerField(choices=mobo_size) #WANTED
    color_name        = models.CharField(default='Black', max_length=15) #Write the color name corresponding to the Hex value below #WANTED
    color_hex         = models.CharField(default='#RRGGBB', max_length=8) #Write the color value as a hex string #WANTED
    use_case          = models.CharField(choices=(('Budget', 'Budget'), ('Mid-Range', 'Mid-Range'), ('High-end', 'High-end')), max_length=15)
    def __str__(self):
        return f"{self.ID}: {self.name}"

    class Meta:
        verbose_name ='PSU'
        verbose_name_plural ='PSUs'

    def is_valid_psu(self):
        condition = True
        manufacturer = self.manufacturer
        if manufacturer.manufactures_cpu == False:
            print('This manufacturer does not make cpus')
            condition = False
        if self.threads > self.cores:
            condition = False
        if (manufacturer.name.lower() == 'intel') and (self.cooler == True):
            condition = False
        return condition

#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

class fan(commoninfo):
    size                  = models.PositiveIntegerField(null=True)
    lowest_rpm            = models.PositiveIntegerField(null=True, verbose_name='Lowest Speed', help_text='The RPM value')
    highest_rpm           = models.PositiveIntegerField(null=True, verbose_name='Highest Speed', help_text='The RPM value')
    rgb                   = models.BooleanField()
    connection            = models.PositiveIntegerField(verbose_name='Num of pins', null=True)
    color_name            = models.CharField(default='Black', max_length=15) #Write the color name corresponding to the Hex value below
    color_hex             = models.CharField(default='#RRGGBB', max_length=8) #Write the color value as a hex string
    theme                 = models.CharField(choices=(('dark', 'dark'), ('light', 'light')), verbose_name='Color Theme', max_length=15)
    use_case              = models.CharField(choices=(('Budget', 'Budget'), ('Mid-Range', 'Mid-Range'), ('High-end', 'High-end')), max_length=15)
    def __str__(self):
        return f"{self.name} ({self.ID})"

    class Meta:
            verbose_name ='Fan'
            verbose_name_plural ='Fans'

    def is_valid_fan(self):
        pass

#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

class case(commoninfo):
    mobo_size = (
        ('ATX', 'ATX'),
        ('Micro-ATX', 'Micro-ATX'),
        ('Mini-ITX', 'Mini-ITX')
    )

    mobo_support          = models.IntegerField(choices=mobo_size, null=True) #WANTED
    height                = models.FloatField() #WANTED
    width                 = models.FloatField() #WANTED
    depth                 = models.FloatField() #WANTED
    max_gpu_length        = models.FloatField(null=True, blank=True) #WANTED
    max_cpu_cooler_heigth = models.FloatField(null=True, blank=True) #WANTED
    rgb                   = models.BooleanField() #WANTED
    has_fans              = models.BooleanField() #WANTED
    num_fans              = models.PositiveIntegerField() #WANTED
    max_num_number        = models.IntegerField(null=True) #WANTED
    max_fan_size          = models.PositiveIntegerField(null=True) #WANTED
    io                    = models.TextField(null=True) #WANTED
    color_name            = models.CharField(default='Black', max_length=15) #Write the color name corresponding to the Hex value below #WANTED
    color_hex             = models.CharField(default='#RRGGBB', max_length=8) #Write the color value as a hex string #WANTED
    theme                 = models.CharField(choices=(('dark', 'dark'), ('light', 'light')), verbose_name='Color Theme', max_length=15) #WANTED
    use_case              = models.CharField(choices=(('Budget', 'Budget'), ('Mid-Range', 'Mid-Range'), ('High-end', 'High-end')), max_length=15)
    def __str__(self):
        return f"{self.name} ({self.ID})"

    class Meta:
        verbose_name = 'Case'
        verbose_name_plural = 'Cases'

    def is_valid_case(self):
        condition = True
        if self.has_fans == False and self.num_fans > 0:
            condition = False
        return condition

#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

class computer(models.Model):
    ID            = models.CharField(primary_key=True, max_length=20)
    motherboard   = models.ForeignKey(motherboard, on_delete= models.CASCADE)
    aircooler     = models.ForeignKey(aircooler, null=True, blank=True, on_delete= models.CASCADE)
    watercooler   = models.ForeignKey(watercooler, null=True, blank=True, on_delete= models.CASCADE)
    cpu           = models.ForeignKey(cpu, on_delete= models.CASCADE)
    gpu           = models.ForeignKey(gpu, on_delete= models.CASCADE)
    ram           = models.ForeignKey(ram, on_delete= models.CASCADE)
    ssd           = models.ForeignKey(ssd, null=True, blank=True, on_delete= models.CASCADE, related_name='ssd1')
    hdd           = models.ForeignKey(hdd, null=True, blank=True, on_delete= models.CASCADE, related_name='hdd1')
    psu           = models.ForeignKey(psu, on_delete= models.CASCADE)
    case          = models.ForeignKey(case, on_delete= models.CASCADE)

    def __str__(self):
        return f"{self.ID}"

    class Meta:
        verbose_name = 'Computer'
        verbose_name_plural = 'Computers'

    def is_valid_computer(self):
        condition = True
        if gpu.length > case.length:
            condition = False

        if aircooler.height > case.depth:
            condition = False

        if cpu.socket != motherboard.socket:
            condition = False

        ram_capacity = ['4x4', '8x4', '16x4', '32x4']
        for i in ram_capacity:
            if (ram.ram_capacity == i) and (motherboard.ram_slots == 2):
                condition = False

        if (case.size == 'Mini-ITX') and (motherboard.size == 'ATX' or 'Micro-ATX'):
            condition= False

        return condition

#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#                                       ALGORITHM                                       #
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

# Developement to be done on Jupyter Notebooks
class algorithm:
    def __init__(self, JSON):
        self.budget = int(JSON['budget'])
        self.fps = int(JSON['fps'])
        self.resolution = int(JSON['resolution'])
        self.gametype = str(JSON['gametype'])
        self.formFactor = str(JSON['formFactor'])
        self.purpose = str(JSON['purpose'])
        self.theme = JSON['theme'][0]
        self.DAYS_ALLOWED = 4 #Number of days allowed to use a part before updating its data using scraper
        self.currentDate = datetime.today()
        self.dateOfUpdate = self.currentDate - timedelta(days=self.DAYS_ALLOWED) # Last day allowed for part use
        if JSON['theme'][1] == 'RGB':
            self.rgb = True
        else:
            self.rgb = False

    ''' Since the algorithm currently serves gamers only '''
    ''' The CPU and GPU should both have the largest share of the budget '''
    ''' Also because they are the most important component in a PC '''
    def getPercents(self, part):
        #Percents in the order: CPU - GPU - MOBO - RAM - STORAGE - COOLER - PSU - CASE
        #The part parameter is to be send as an argument from the calling function(eg:0 is CPU, 2 if RAM)
        partPercentages = {
        500: [16, 33, 21, 5, 4, 4, 7, 10],
        750: [21, 37, 22, 4, 4, 4, 3, 5],
        1000:[21, 37, 16, 5, 5, 8, 7, 7],
        1250:[17, 38, 15, 5, 5, 6, 8, 6],
        1500:[19, 35, 13, 6, 6, 9, 6, 6],
        1750:[16, 48, 12, 3, 4, 8, 5, 5],
        2000:[0, 0, 0, 0, 0, 0, 0, 0],
        2250:[0, 0, 0, 0, 0, 0, 0, 0],
        2500:[0, 0, 0, 0, 0, 0, 0, 0],
        2750:[0, 0, 0, 0, 0, 0, 0, 0],
        3000:[0, 0, 0, 0, 0, 0, 0, 0],
        3250:[0, 0, 0, 0, 0, 0, 0, 0],
        3500:[0, 0, 0, 0, 0, 0, 0, 0],
        3750:[0, 0, 0, 0, 0, 0, 0, 0],
        4000:[0, 0, 0, 0, 0, 0, 0, 0],
        }
        percents = partPercentages[self.budget]
        return percents[part]

    #@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#
    ''' Below are the functions that get the parts based on inputs from the main function '''
    ''' Basic documentation is provided as general guidance, however feel free to add additionals '''
    ''' filters or check as long as it makes the function give better suggestions for its part '''
    ''' For questions or bugs, please raise an issue here: https://github.com/Computerizer/FULL-STACK/issues '''
    #@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#

    # If several parts remain, sort by highest rating.
    # If there are parts with the same rating, suggest lowest price
    # If part's specific budget is 200$, create a range of 10% above and below (so range 180 - 220)

    # Yusuf
    def __getCpu(self, budgetPercentage):
        # All CPUs are firstly filtered by budget from the CPUs table
        # The formFactor and purpose paramters play a role in deciding which CPU to choose
        # This is because some CPUs emit too much heat, and consume so much power, hence
        # they can not be used in mini-ITX or console killer builds for example
        # So the rule will be to filter out CPUs based on a combination of budget
        # and the other paramters, and you can use the formFactor and purpose fields
        # in the CPU table to help, for example the i9 is both table top and work machine,
        # and its also for ATX builds.

        budget = (self.budget * budgetPercentage) // 100
        budgetLowerBound = budget - ((budget*15)//100)
        budgetUpperBound = budget + ((budget*15)//100)

        Cpu = cpu.object.filter(
            current_price__gte=budgetLowerBound).filter(
            current_price__lte=budgetUpperBound).exclude(
            rating__lte=4.0).exclude(
            last_modified__lt=self.dateOfUpdate)

        if self.formFactor == 'MiniITX' or self.purpose == 'Console Killer':
            Cpu.object.filter(power_consumption__lte = 100)

        highest_rating = Cpu.objects.order_by('-rating')
        lowest_price = Cpu.objects.order_by('current_price')
        lowPrice_and_highRating = highest_rating.intersection(lowest_price).first()
        return lowPrice_and_highRating

    # Omar
    def __getGpu(self, budgetPercentage):
        # The GPU is a bit more complicated than the CPU
        # As there are many parameters involved
        # 1) Performance as in resolution, FPS, gametype, and boostclock.
        # 2) Maximizing GPU performance utilization from motherboard,
        # for example if the mobo doesn't support PCIe5, there is no need to suggest a PCIe5 GPU
        # And for that you can use the (supported_resolution, boost_clock, etc) fields
        budget = (self.budget * budgetPercentage)// 100
        HighestPrice = budget + ((budget * 15) // 100)
        LowestPrice = budget - ((budget * 15) // 100)
        Gpu = gpu.objects.filter(
            current_price__gte = LowestPrice).filter(
            current_price__lte=HighestPrice).exclude(
            rating__lte=4.0).exclude(
            last_modified__lt=self.dateOfUpdate)
        pass

    # Omar
    def __getRam(self, budgetPercentage, MOBO, CPU):
        # Follow the same previous pattern, first filter by budget
        # Next filter any ram sets that exceed the maximum slot number on the mobo
        # Then check if the mobo and cpu support DDr5, if so then suggest a DDr5 ram set
        # If not then filter out anything that is DDr5 and keep the DDr4
        budget = (self.budget * budgetPercentage)// 100
        HighestPrice = budget + ((budget * 15) // 100)
        LowestPrice = budget - ((budget * 15) // 100)
        ram_sets = MOBO.ram_slots
        #TODO Filter ram sets that exceed the maximum slot number on the mobo
        rams = ram.objects.filter(
            current_price__gte = LowestPrice).filter(
            current_price__lte=HighestPrice).exclude(
            rating__lte=4.0).exclude(
            last_modified__lt=self.dateOfUpdate)
        if MOBO.ddr_5_support:
            rams = rams.filter(type='DDR5')
        else:
            rams = rams.filter(type='DDR4')

        highest_rating = rams.objects.order_by('-rating')[:5]
        lowest_price = rams.objects.order_by('current_price')[:5]
        lowPrice_and_highRating = highest_rating.intersection(lowest_price).first()
        return lowPrice_and_highRating
    # Emad
    def __getMobo(self, budgetPercentage, CPU):
        # Choosing a motherboard is pretty simple
        # Firstly filter by budget, then by theme.
        # Then we filter based on our CPU choice (CPU-socket field), AMD and Intel use different mobos
        # Finally we filter based on formFactor: ATX, Micro-ATX, or Mini-ITX
        budget = (self.budget * budgetPercentage) // 100 # Calculating budget from given percentage
        budgetLowerBound = budget - ((budget*15)//100)
        budgetUpperBound = budget + ((budget*15)//100)
        cpuSocket = CPU.socket # String val, either: AM4, LGA1700, LGA1200

        mobo = motherboard.objects.filter(
            socket=cpuSocket).filter(
            current_price__gte=budgetLowerBound).filter(
            current_price__lte=budgetUpperBound).filter(
            size=self.formFactor).filter(
            rgb=self.rgb).filter(
            theme=self.theme).exclude(
            rating__lte=4.0).exclude(
            last_modified__lt=self.dateOfUpdate)

        highest_rating = mobo.objects.order_by('-rating')[:5]
        lowest_price = mobo.objects.order_by('current_price')[:5]
        lowPrice_and_highRating = highest_rating.intersection(lowest_price).first()
        return lowPrice_and_highRating

    # Yusuf
    def __getCooler(self, budgetPercentage, CPU, MOBO):
        # Again filter anything outside the budget range
        # Based on formFactor(ATX-Micro-Mini), purpose, budget, and the cpu type
        # choose either a water or air cooler (criteria can include intend of the pc
        # and how much heat the CPU releases, wich can be estimated by its name and wattage)
        # Finally filter out any coolers that aren't compatible with the motherboard/CPU
        budget = (self.budget * budgetPercentage) // 100
        budgetLowerBound = budget - ((budget*15)//100)
        budgetUpperBound = budget + ((budget*15)//100)

        # currently only using aircoolers
        cooler = aircooler.objects.filter(
            current_price__gte=budgetLowerBound).filter(
            current_price__lte=budgetUpperBound).filter(
            size = self.formFactor).filter(
            socket = CPU.socket).exclude(
            rating__lte=4.0).exclude(
            last_modified__lt=self.dateOfUpdate)

        highest_rating = cooler.objects.order_by('-rating')
        lowest_price = cooler.objects.order_by('current_price')
        lowPrice_and_highRating = highest_rating.intersection(lowest_price).first()
        return lowPrice_and_highRating

    # Emad
    def __getStorage(self, budgetPercentage, CASE, MOBO):
            # Follow the same previous pattern, first filter by budget
        # An SSD must hold the main OS at least, and preferablly be as fast as possible
        # There for check for the fastest SSD sockets going down, and filter out as you go
        # You can do so by checking sockets on the motherboard, using relative fields
        # At the end filter what's left based on the fastest speed and highest storage
        budget = (self.budget * budgetPercentage) // 100 # Calculating budget from given percentage
        budgetLowerBound = budget - ((budget*15)//100)
        budgetUpperBound = budget + ((budget*15)//100)
        currentDate = datetime.today()
        dateOfUpdate = currentDate - timedelta(days=4) #Older than 4 days ago from today
        ssd_count = 0
        hdd_count = 0
        ssd_price = 0
        hdd_price = 0
        if (self.formFactor == 'MiniItx') or (self.purpose == 'ConsoleKiller'):
            ssd_count = 1
            ssd_price = budget
        else:
            ssd_count = 1
            hdd_count = 1
            ssd_price = budget * 0.7
            hdd_price = budget - ssd_price

        if ssd_count > 0 and hdd_count == 0:
            SSD = ssd.objects.filter(
                current_price__gte=float(ssd_price - ((ssd_price*15)//100))).filter(
                current_price__lte=float(ssd_price + ((ssd_price*15)//100))).filter(
                rgb=self.rgb).exclude(
                rating__lte=4.0).exclude(
                last_modified__lt=dateOfUpdate)

        elif ssd_count > 0  and hdd_count > 0:
            SSD = ssd.objects.filter(
                current_price__gte=float(ssd_price - ((ssd_price*15)//100))).filter(
                current_price__lte=float(ssd_price + ((ssd_price*15)//100))).filter(
                rgb=self.rgb).exclude(
                rating__lte=4.0).exclude(
                last_modified__lt=dateOfUpdate)

            HDD = hdd.objects.filter(
                current_price__gte=float(hdd_price - ((hdd_price*15)//100))).filter(
                current_price__lte=float(hdd_price + ((hdd_price*15)//100))).filter(
                rgb=self.rgb).exclude(
                rating__lte=4.0).exclude(
                last_modified__lt=dateOfUpdate)

        if HDD.count() == 0:
            highest_rating = SSD.objects.order_by('-rating')[:5]
            lowest_price = SSD.objects.order_by('current_price')[:5]
            lowPrice_and_highRating = highest_rating.intersection(lowest_price).first()
            return lowPrice_and_highRating
        else:
            highest_rating_ssd = SSD.objects.order_by('-rating')[:5]
            lowest_price_ssd = SSD.objects.order_by('current_price')[:5]
            lowPrice_and_highRating_ssd = highest_rating_ssd.intersection(lowest_price_ssd).first()
            highest_rating_hdd = HDD.objects.order_by('-rating')[:5]
            lowest_price_hdd = HDD.objects.order_by('current_price')[:5]
            lowPrice_and_highRating_hdd = highest_rating_hdd.intersection(lowest_price_hdd).first()
            return [lowPrice_and_highRating_ssd, lowPrice_and_highRating_hdd]

    # Yusuf
    def __getCase(self, budgetPercentage, MOBO, GPU, COOLER):
        # Obviously, we filter by price/budget firstly
        # Then we fitler based on the formfactor (ATX, micro, or mini)
        # Then we filter cases left to fit the maximum width of the gpu
        # We also make sure that the cooler fits in the case,
        # if its an aircooler then we check for height and clearance,
        # if its a watercooler, then check that the radiator fits
        budget = (self.budget * budgetPercentage) // 100
        budgetLowerBound = budget - ((budget*15)//100)
        budgetUpperBound = budget + ((budget*15)//100)

        Case = case.objects.filter(
            current_price__gte=budgetLowerBound).filter(
            current_price__lte=budgetUpperBound).filter(
            size = self.formFactor)

    # Omar
    def __getPsu(self, budgetPercentage, CASE, WATTS):
        # Filter out by budget
        # Then filter out based on formFactor (ATX, ITX, etc)
        # Then filter for the minimum required watts given in the parameter
        # Finally go from the highest rating (Platinum) to lowest (Bronze),
        # check if there is any psu from the higher ratings, keep it and remove all else
        budget = (self.budget * budgetPercentage)// 100
        HighestPrice = budget + ((budget * 15) // 100)
        LowestPrice = budget - ((budget * 15) // 100)
        Size = self.JSON['formFactor'][0]
        Psu = psu.objects.filter(
            current_price__gte = LowestPrice).filter(
            current_price__lte=HighestPrice).filter(
            size = Size).filter(
            wattage__gte = WATTS).exclude(
            rating__lte=4.0).exclude(
            last_modified__lt=self.dateOfUpdate)

        highest_rating = Psu.objects.order_by('-ratings').order_by('-rating')[:5]
        lowest_price = Psu.objects.order_by('current_price')[:5]
        lowPrice_and_highRating = highest_rating.intersection(lowest_price).first()
        return lowPrice_and_highRating

    def getComputer(self):
        try:
            cpu = self.__getCpu(self.getPercents(0))
        except Exception:
            print('CPU ERROR')
            print(Exception)
            #or get static part

        try:
            mobo = self.__getMobo(self.getPercents(2), cpu)
        except Exception:
            print('MOBO ERROR')
            print(Exception)
            #or get static part

        try:
            cooler = self.__getCooler(self.getPercents(5), cpu, mobo)
        except Exception:
            print('COOLER ERROR')
            print(Exception)
            #or get static part

        try:
            gpu = self.__getGpu(self.getPercents(1))
        except Exception:
            print('GPU ERROR')
            print(Exception)
            #or get static part

        try:
            case = self.__getCase(self.getPercents(7), mobo, gpu, cooler)
        except Exception:
            print('CASE ERROR')
            print(Exception)
            #or get static part

        try:
            ram = self.__getRam(self.getPercents(3), mobo, cpu)
        except Exception:
            print('RAM ERROR')
            print(Exception)
            #or get static part

        try:
            storage = self.__getStorage(self.getPercents(4), case, mobo)
        except Exception:
            print('STORAGE ERROR')
            print(Exception)
            #or get static part

        try:
            watts = cpu['power_consumption'] + gpu['power_consumption'] + cooler['power_consumption']
        except Exception:
            print('ERROR CALCULATING WATTS')
            print('Check other parts errors...')
            print(Exception)
            #or get static part

        try:
            psu = self.__getPsu(self.getPercents(6), case, watts)
        except Exception:
            print('PSU ERROR')
            print(Exception)
            #or get static part

        #Before returning the PC to the views, we should run some error checking and integration checking
        try:
            return[cpu, mobo, cooler, gpu, case, ram, storage, psu]
        except Exception as error:
            return error

# Below is an exmaple of a JSON request we will get from the tool's frontend
JSON = {
    'budget': 4000,
    'fps': 144,
    'resolution': '4k',
    'gameType': 'AAA',
    'formFactor': 'ATX',
    'purpose': 'Table Top',
    'theme': 'Dark',
    'RGB': True
    }


import unittest
import os
import pandas as pd
import ejercicio5

class TestEjercicio5(unittest.TestCase):
    def setUp(self):
        self.test_directory = os.path.join(os.path.dirname(__file__), 'dataset_cities/labels/')
        self.valid_files = ['berlin_000000_000019_leftImg8bit_20-10-2018.txt', 'berlin_000005_000019_leftImg8bit_14-02-2017.txt']
        self.invalid_files = ['invalid_file1.csv', 'invalid_file2.csv']

    def test_process_files2(self):
        df = ejercicio5.process_files2(self.test_directory, self.invalid_files)
        self.assertIsInstance(df, pd.DataFrame)
        self.assertEqual(len(df), 7510)

    def test_plot_cars_by_year_and_city(self):
        df = ejercicio5.process_files2(self.test_directory, self.invalid_files)
        ejercicio5.plot_cars_by_year_and_city(df)
        #  the function should not raise any exception


import urllib.request
from bs4 import BeautifulSoup
import re

# upload to mysql
import mysql.connector

# Mysql Connection
mysql = mysql.connector.connect(
    host='localhost', password='', user='root', database='dicoding_scrape')
mysqlCursor = mysql.cursor()

url = 'https://www.dicoding.com/about'

req = urllib.request.Request(url)
res = urllib.request.urlopen(req)
responData = res.read()

# print(responData)
name = re.findall(
    r'
(.*?)
', str(responData))
job = re.findall(
    r'
(.*?)
', str(responData))
quotes = re.findall(
    r'
(.*?)
', str(responData))

# custom resource
def normalization(text):
    text = text.replace("\\n", "")
    text = text.replace("\\'", "")
    text = text.strip()

    return text

#  Loop for all getted data
for i in range(len(name)):

    getName = normalization(job[i])
    getJob = normalization(job[i])
    getQuotes = normalization(quotes[i])

    query = "INSERT INTO scrape(name, job, quotes) VALUES('" + \
        getName+"', '"+getJob+"', '"+getQuotes+"')"

    print(query)

    mysqlCursor.execute(query)
    mysql.commit()


# -*- coding: utf-8 -*-
"""
Created on Wed Mar  6 15:20:12 2019

@author: 86181
"""

##using tf implement one-layer perceptron

import tensorflow as tf

##load data##
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)

##define##

x = tf.placeholder(tf.float32,[None,784])   ##input image

y_label = tf.placeholder(tf.float32,[None,10])

w = tf.Variable(tf.zeros([784,10]))

b = tf.Variable(tf.zeros([10]))

y_predict = tf.nn.softmax(tf.matmul(x,w) + b)

loss = - tf.reduce_sum(y_label * tf.log(y_predict))

train = tf.train.GradientDescentOptimizer(0.01).minimize(loss)

accuracy = tf.reduce_mean(tf.cast(tf.equal(tf.arg_max(y_label,1),tf.arg_max(y_predict,1)),tf.float32))
##run##
init = tf.global_variables_initializer()

with tf.Session() as sess:
    sess.run(init)
    for i in range(6000):
        xs, ys = mnist.train.next_batch(100)
        sess.run(train,feed_dict={x:xs,y_label:ys})
        acc = sess.run(accuracy,feed_dict={x:mnist.test.images,y_label:mnist.test.labels})
        print('step:'+ str(i)+ ' accuracy is:' + str(acc))

print('Done!')


# -*- coding: gbk -*-
##################################################################
#   代收代付平台.与主机通讯函数
#=================================================================
#   程序文件:   VouhHostFunc.py
#   修改时间:   2008-12-18
#
#
##################################################################
import TradeContext,AfaFunc,UtilTools,HostComm,HostContext,HostDataHandler,AfaLoggerFunc,os,AfaFlowControl
from types import *

#====================与主机数据交换=============================
def CommHost( result = '8844' ):

    AfaLoggerFunc.tradeInfo('>>>主机通讯函数[CommHost]')

    #根据正反交易标志TradeContext.revTranF判断具体选择哪个map文件和主机接口方式

    if (result == '8844'):
        AfaLoggerFunc.tradeInfo('>>>核心记帐')
        mapfile=os.environ['AFAP_HOME'] + '/conf/hostconf/AH8844.map'
        TradeContext.HostCode = '8844'

    else:
        TradeContext.errorCode = 'A9999'
        TradeContext.errorMsg  = '主机代码错误'
        return False

    AfaLoggerFunc.tradeInfo( '=======================7' )
    #此处交易代码要求10位,右补空格
    HostComm.callHostTrade( mapfile, UtilTools.Rfill(TradeContext.HostCode,10,' ') ,'0002' )
    AfaLoggerFunc.tradeInfo( '=======================8' )
    if HostContext.host_Error:
        AfaLoggerFunc.tradeFatal( 'host_Error:'+str( HostContext.host_ErrorType )+':'+HostContext.host_ErrorMsg )

        if HostContext.host_ErrorType != 5 :
            TradeContext.__status__='1'
            TradeContext.errorCode='A0101'
            TradeContext.errorMsg=HostContext.host_ErrorMsg
        else :
            TradeContext.__status__='2'
            TradeContext.errorCode='A0102'
            TradeContext.errorMsg=HostContext.host_ErrorMsg
        return False
    AfaLoggerFunc.tradeInfo( '=======================9' )
    #================分析主机返回包====================
    return HostParseRet(result )

#================分析主机返回包====================
def HostParseRet( hostType ):
    HostContext.O1TLSQ=''
    AfaLoggerFunc.tradeInfo( '=======================10' )
    if (HostContext.host_Error == True):    #主机通讯错误
        TradeContext.__status__='2'
        TradeContext.errorCode, TradeContext.errorMsg = 'A9998', '主机通讯错误'
        TradeContext.bankCode  = HostContext.host_ErrorType                       #通讯错误代码
        return False
    AfaLoggerFunc.tradeInfo( '=======================11'+HostContext.O1MGID )
    if( HostContext.O1MGID == 'AAAAAAA' ): #成功

        TradeContext.__status__='0'
        TradeContext.errorCode, TradeContext.errorMsg = '0000', '主机成功'
        TradeContext.PDTLSQ = HostContext.O1TLSQ                               #柜员流水号
        TradeContext.PDTRDT = HostContext.O1TRDT                                #主机时间
        TradeContext.PAMGID = HostContext.O1MGID                               #主机返回代码
        return True

    else:                                  #失败
        TradeContext.__status__='1'

        #安徽农信-主机自动返回错误信息，不需要转换
        #result = AfapFunc.RespCodeMsg(HostContext.O1MGID,'0000','100000')
        #if not result :
        TradeContext.errorCode, TradeContext.errorMsg = HostContext.O1MGID, HostContext.O1INFO
        return False


import os

libN = 3
threads = libN
print("threads =%s" % threads)
os.environ["OMP_NUM_THREADS"] = "%s" % threads
# pool = Pool(processes=cpu_count())
import numpy as np

import definition as harmonic
import matplotlib.pyplot as plt
from multiprocessing import get_context
import poolscripts

# NOTE: time is inputted and plotted in terms of cycles, but the actual propagation happens in 'normal' time

# input units: THz (field), eV (t, U), MV/cm (peak amplitude, F0), Angstroms (lattice cst, a)
# they're then converted to t-normalised atomic units. bc='pbc' for periodic and 'abc' for antiperiodic

if __name__ == '__main__':
    neighbour = []
    phi_original = []
    phi_reconstruct = [0., 0.]
    boundary_1 = []
    boundary_2 = []
    two_body = []
    two_body_old = []
    error = []
    J_field = []
    D_cutfreq = []
    Jalt = []
    systems = []

    number = 3
    nelec = (number, number)
    nx = 6
    ny = 0
    t = 0.52
    # t=1.91
    # t=1
    U = 1 * t
    cutoff = 40
    delta = 0.005
    cycles = libN + 1
    field = 32.9
    # field=32.9*2
    F0 = 10
    a = 4
    ascale = 1
    U_start = 0 * t
    U_end = 1 * t
    sections = (cycles - 1) / libN
    U_list = np.linspace(U_start, U_end, libN)
    print(U_list)

    pool = get_context("spawn").Pool(processes=threads)

    parameternames = '-%s-nsites-%s-cycles-%s-t-%s-n-%s-delta-%s-field-%s-amplitude-%s-libN-%s-U_start-%s-U_end.npy' % (
        nx, cycles, t, number, delta, field, F0, libN, U_start, U_end)
    phi_discrim = np.load('./data/original/discriminatorfield' + parameternames)

    # for j in range(1,len(phi_discrim)):
    #     if phi_discrim[j]-phi_discrim[j-1] > 1.8*np.pi:
    #         phi_discrim[j:] = phi_discrim[j:]-2*np.pi
    #     elif phi_discrim[j]-phi_discrim[j-1] < -1.8*np.pi:
    #         phi_discrim[j:] = phi_discrim[j:]+2*np.pi
    plt.plot(phi_discrim)
    plt.show()

    def setup(U_input):
        system = harmonic.hhg(cycles=cycles, delta=delta, libN=libN, field=field, nup=number, ndown=number, nx=nx, ny=0,
                              U=U_input, t=t, F0=F0, a=a, bc='pbc', phi=phi_discrim)
        return system

    systems = []
    for U in U_list:
        print("U value is %.2f" % U)
        systems.append(setup(U))

    systems = pool.map(poolscripts.evolve_discrimate, systems)

    for j in range(len(systems)):
        plt.plot(systems[j].last_J)
    plt.show()

    plt.plot(phi_discrim)
    plt.plot(systems[0].phi)
    plt.show()

    for system in systems:
        parameternames = '-%s-nsites-%s-cycles-%s-U-%s-t-%s-n-%s-delta-%s-field-%s-amplitude-%s-libN-%s-U_start-%s-U_end' % (
            nx, cycles, system.U, t, number, delta, field, F0, libN, U_start, U_end)
        np.save('./data/discriminate/Jfield_discrim' + parameternames, system.last_J)


import tensorflow as tf
import numpy as np

sess = tf.Session()

x_vals = np.random.normal(1, 0.1, 100)
y_vals = np.repeat(10., 100)

x_data = tf.placeholder(tf.float32, shape=[1])
y_target = tf.placeholder(tf.float32, shape=[1])

A = tf.Variable(tf.random_normal(shape=[1]))

my_output = tf.multiply(x_data, A)

# 损失函数
loss = tf.square(my_output - y_target)

# 初始化变量
init = tf.initialize_all_variables()
sess.run(init)

my_opt = tf.train.GradientDescentOptimizer(learning_rate=0.02)
train_step = my_opt.minimize(loss)

# 训练算法
for i in range(100):
    rand_index = np.random.choice(100)
    rand_x = [x_vals[rand_index]]
    rand_y = [y_vals[rand_index]]
    sess.run(train_step, feed_dict={x_data: rand_x, y_target: rand_y})

    if (i + 1) % 25 == 0:
        print("step = " + str(i + 1) + "A = " + str(sess.run(A)))
        print("loss = " + str(sess.run(loss, feed_dict={x_data: rand_x, y_target: rand_y})))

print(str(A.eval(session=sess)))


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

"""
@author: Li Tian
@contact: litian_cup@163.com
@software: pycharm
@file: tsTclntSS.py
@time: 2020/12/26 16:37
@desc: 创建客户端
"""

from socket import *

HOST = 'localhost'
PORT = 21567
BUFSIZ = 1024
ADDR = (HOST, PORT)

while True:
    tcpCliSock = socket(AF_INET, SOCK_STREAM)
    tcpCliSock.connect(ADDR)
    data = input('> ')
    if not data:
        break
    tcpCliSock.send(bytes('%s\r\n' % data, encoding='utf-8'))
    data = tcpCliSock.recv(BUFSIZ)
    if not data:
        break
    print(str(data, encoding='utf-8').strip())
    tcpCliSock.close()


import re
import os
from os import listdir

def get_file_list(folderPath):
    """
    Returns a filenames with associated creation times in a list

    PARAMS:
        folderPath: path folder where the files by person are stored
                  if folder contains Loop Reports, then just return that list

    RETURNS:
        returnList list of filename(relative to folderPath),
                   creation time for file
                   returnList is sorted by creation time
    """
    list_of_reports = []
    list_of_dates = []

    thisLevel = listdir(folderPath)

    if thisLevel[0][0:4] == 'Loop':
        for y in thisLevel:
            if y == '.DS_Store':
                continue
            personFile = y
            list_of_reports.append(personFile)
            list_of_dates.append(os.path.getmtime(folderPath +
                                                  '/' + personFile))

    else:
        for x in thisLevel:
            if x == '.DS_Store':
                continue
            # print(x)
            for y in listdir(folderPath + '/' + x):
                if y == '.DS_Store':
                    continue
                personFile = x + '/' + y
                list_of_reports.append(personFile)
                list_of_dates.append(os.path.getmtime(folderPath +
                                                      '/' + personFile))

    zippedTuple = zip(list_of_reports, list_of_dates)
    zippedList = list(zippedTuple)
    returnList = sorted(zippedList, key=lambda x: x[1])

    # return the list of files and dates sorted by date
    return returnList

def getFileDict(folderPath, personFile):
    fileDict = {'filename': folderPath + '/' + personFile,
                'path': folderPath,
                'personFile': personFile}
    # parse the person and date from in personFile
    #   (of form person/LoopReport_date.md)
    val = '^.*/'
    thisPerson = re.findall(val, personFile)
    if not thisPerson:
        thisPerson = 'Unknown'
    else:
        thisPerson = thisPerson[0][0:-1]

    fileDict['person'] = thisPerson

    val = '/.*$'
    thisFullName = re.findall(val, personFile)
    thisFullName = thisFullName[0]
    thisFullName = thisFullName[1:]
    thisFullName = thisFullName.replace(' ', '')  # remove spaces
    thisFullName = thisFullName.replace('-', '')  # remove hypens
    thisFullName = thisFullName.replace('_', '')  # remove underscores
    # trim off some characters
    thisDate = thisFullName[10:18] + '_' + thisFullName[18:22]
    fileDict['date'] = thisDate

    return fileDict


# Variables

# number1 = 2
# print(number1)
# number1 = 4
# print(number1)

# String, Number
# name = 'Deva'
# print(name)
# name = 123
# print(name)

# Naming conventions for Variable
'''
we can't start a variable name with a number
we can't give a space in between the variable name
we can only allowed to use letters, numbers and underscore(_) for Naming the variable
'''
num1 = 1
_greet = 'Hello'
first_name = 'vasudev'  # Snake case writing
print(num1, first_name, _greet)
print()


from rest_framework import serializers

from ..models import Services, ServiceCapacities, Capacitystatuses

import logging

logger = logging.getLogger(__name__)

"""
This serializer models the DoS Services database table and contains only the
fields that we are interested in for the purposes of the application.
"""

class ServicesSerializer(serializers.ModelSerializer):
    class Meta:
        model = Services
        fields = ("id", "uid", "name", "publicname")

"""
This serializer models the DoS Capacitystatuses database table and contains only the
fields that we are interested in for the purposes of the application.
"""

class CapacitystatusesSerializer(serializers.ModelSerializer):
    class Meta:
        model = Capacitystatuses
        fields = ("color",)

"""
This serializer models the DoS ServiceCapacities database table and embeds within
it the two serializers defined above. It provides a flattend representation of the
data model for capacity status update and retrieval.
It is responsible for:
    capacity status retrieval
    database level validation
    capacity status update
"""

class CapacityStatusModelSerializer(serializers.ModelSerializer):

    service = ServicesSerializer(read_only=True)
    status = CapacitystatusesSerializer(required=True)

    class Meta:
        model = ServiceCapacities
        fields = (
            "id",
            "notes",
            "modifiedbyid",
            "modifiedby",
            "modifieddate",
            "service",
            "resetdatetime",
            "status",
        )

    """
    We are overriding the default method provided by the ModelSerializer class because
    we need to set the capacity status of the instance to a CapacityStatus instance.
    """

    def update(self, instance, validated_data):

        logger.debug(
            "Data passed into CapacityStatusModelSerializer for update: %s",
            validated_data,
        )

        ragStatusColor = validated_data.get("status", instance.status)["color"]
        capStatus = Capacitystatuses.objects.db_manager("dos").get(color=ragStatusColor)

        # Adapted from the super class's update method
        for attr, value in validated_data.items():
            if attr == "status":
                setattr(instance, attr, capStatus)
            else:
                setattr(instance, attr, value)

        instance.save()

        return instance


import numpy as np
import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn import metrics
import nltk
import re
from nltk.stem import WordNetLemmatizer
from nltk.corpus import stopwords
from sklearn.metrics import accuracy_score, classification_report
from sklearn.metrics import f1_score
import csv

# reading the data
test_csv = pd.read_csv('test3.csv')
train_csv = pd.read_csv('train3.csv')

#stopword removal and lemmatization
stopwords = set(stopwords.words('english'))
lemmatizer = WordNetLemmatizer()

nltk.download('stopwords')

train_csv.head()

train_X = train_csv['Text']
X = []

for i in range(0, len(train_X)):
    review = re.sub('[^a-zA-Z]', ' ', train_X[i])
    review = review.lower()
    review = review.split()
    review = [lemmatizer.lemmatize(word) for word in review if not word in set(stopwords)]
    review = ' '.join(review)
    X.append(review)

y = train_csv['Class']

# Building a TF IDF matrix out of the corpus of reviews
from sklearn.feature_extraction.text import TfidfVectorizer
td = TfidfVectorizer(max_features = 5000)
X = td.fit_transform(X).toarray()

# Splitting into training & test subsets
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.3,
                                                    random_state = 0)

# Training the classifier & predicting on test data
from sklearn.naive_bayes import MultinomialNB
classifier = MultinomialNB()
classifier.fit(X_train, y_train)

y_pred = classifier.predict(X_test) # Predicted Result
# Classification metrics
from sklearn.metrics import accuracy_score, classification_report
classification_report = classification_report(y_test, y_pred)

print('\n Accuracy: ', accuracy_score(y_test, y_pred))
print('\nClassification Report')
print('======================================================')
print('\n', classification_report)

# testing with actual test csv

X = test_csv['Text']
test_X = []
for i in range(0, len(X)):
    review = re.sub('[^a-zA-Z]', ' ', X[i])
    review = review.lower()
    review = review.split()
    review = [lemmatizer.lemmatize(word) for word in review if not word in set(stopwords)]
    review = ' '.join(review)
    test_X.append(review)
X_ID = test_csv['ID']

test_X = td.fit_transform(test_X).toarray()

y_pred_test_data = classifier.predict(test_X)

f = open('prediction.csv', 'w')
writer = csv.writer(f)
header = ['REVIEW-ID', 'CLASS']
writer.writerow(header)
for i in range(0, len(y_pred_test_data)):
    row = [X_ID[i], y_pred_test_data[i]]
    writer.writerow(row)
f.close()


import requests
import random

base_url = 'https://api.namemc.com/profile/{}/friends'

file = open('player-list.txt', 'w+')

# we will assume that the first profile used will have a friend list
def runner(kicker, characters):
	known = []
	next = kicker
	while(True):
		names, uuids = parse_user(next)
		for index in range(len(uuids)):
			name = names[index]
			if len(name) > characters:
				continue

			uuid = uuids[index]
			if uuid in known:
				print('User is on list, skipping...')
				continue
			known.append(uuid)
			file.write('{},{}\n'.format(name, uuid))
			print('Added "{}" to the list'.format(name))

		print('List is now composed of', len(known), 'users!')
		key = input('Press (c) to continue and any other key to stop: ')
		if key != 'c':
			break

		next = get_next_user(uuids)
		if next is None:
			print('No user suitable found, stopping program...')
			break
	file.close()
	print('Stopped working, all results saved in "players.txt".')

def get_next_user(uuids):
	next = None
	while (True):
		possible = random.choice(uuids)
		if not check_user(possible):
			continue
		next = possible
		break
	return next

def parse_user(user):
	request = requests.get(base_url.format(user))
	names, uuids = [], []
	for item in request.json():
		names.append(item['name'])
		uuids.append(item['uuid'])
	return names, uuids

def check_user(uuid):
	request = requests.get(base_url.format(uuid))
	return len(request.json()) > 0

kicker = input('Please input a suitable user: ')
characters = int(input('Max amount of characters in the name: '))
runner(kicker, characters)


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

f=mm1.readfile("bragg.txt",0)
f=mm1.transpose(f)

# plt.plot(f[0],f[1],'+-',label='plane=100')
# plt.plot(f[2],f[3],'o-',label='plane=110')
# plt.xlabel('Angle (deg)')
# plt.ylabel('Amplitude(mV)')
# plt.grid()
# plt.legend()
# plt.show()
#for fixed crystal orientation
plt.plot(f[4],f[5],'o-')
plt.title('Fixed Crystal at 100-plane')
plt.xlabel('Angle (deg)')
plt.ylabel('Amplitude(mV)')
plt.grid()
plt.show()


from __future__ import absolute_import
import argparse
import logging
import shutil
import sys
import tempfile
import six

from telemetry import benchmark
from telemetry import story
from telemetry.internal.browser import browser_options
from telemetry.internal.results import results_options
from telemetry.internal import story_runner
from telemetry.internal.util import binary_manager
from telemetry.page import legacy_page_test
from telemetry.util import matching
from telemetry.util import wpr_modes

from py_utils import discover
import py_utils

DEFAULT_LOG_FORMAT = (
    '(%(levelname)s) %(asctime)s %(module)s.%(funcName)s:%(lineno)d  '
    '%(message)s')

class RecorderPageTest(legacy_page_test.LegacyPageTest):
  def __init__(self, page_test):
    super().__init__()
    self._page_test = page_test
    self._platform = None

  @property
  def platform(self):
    return self._platform

  def CustomizeBrowserOptions(self, options):
    if self._page_test:
      self._page_test.CustomizeBrowserOptions(options)

  def WillStartBrowser(self, platform):
    if self.platform is not None:
      assert platform.GetOSName() == self.platform
    self._platform = platform.GetOSName()  # Record platform name from browser.
    if self._page_test:
      self._page_test.WillStartBrowser(platform)

  def DidStartBrowser(self, browser):
    if self._page_test:
      self._page_test.DidStartBrowser(browser)

  def WillNavigateToPage(self, page, tab):
    """Override to ensure all resources are fetched from network."""
    tab.ClearCache(force=False)
    if self._page_test:
      self._page_test.WillNavigateToPage(page, tab)

  def DidNavigateToPage(self, page, tab):
    if self._page_test:
      self._page_test.DidNavigateToPage(page, tab)
    tab.WaitForDocumentReadyStateToBeComplete()
    py_utils.WaitFor(tab.HasReachedQuiescence, 30)

  def CleanUpAfterPage(self, page, tab):
    if self._page_test:
      self._page_test.CleanUpAfterPage(page, tab)

  def ValidateAndMeasurePage(self, page, tab, results):
    if self._page_test:
      self._page_test.ValidateAndMeasurePage(page, tab, results)

def _GetSubclasses(base_dir, cls):
  """Returns all subclasses of |cls| in |base_dir|.

  Args:
    cls: a class

  Returns:
    dict of {underscored_class_name: benchmark class}
  """
  return discover.DiscoverClasses(base_dir, base_dir, cls,
                                  index_by_class_name=True)

def _MaybeGetInstanceOfClass(target, base_dir, cls):
  if isinstance(target, cls):
    return target
  classes = _GetSubclasses(base_dir, cls)
  return classes[target]() if target in classes else None

def _PrintAllImpl(all_items, item_name, output_stream):
  output_stream.write('Available %s\' names with descriptions:\n' % item_name)
  keys = sorted(all_items.keys())
  key_description = [(k, all_items[k].Description()) for k in keys]
  _PrintPairs(key_description, output_stream)
  output_stream.write('\n')

def _PrintAllBenchmarks(base_dir, output_stream):
  # TODO: reuse the logic of finding supported benchmarks in benchmark_runner.py
  # so this only prints out benchmarks that are supported by the recording
  # platform.
  _PrintAllImpl(_GetSubclasses(base_dir, benchmark.Benchmark), 'benchmarks',
                output_stream)

def _PrintAllStories(base_dir, output_stream):
  # TODO: actually print all stories once record_wpr support general
  # stories recording.
  _PrintAllImpl(_GetSubclasses(base_dir, story.StorySet), 'story sets',
                output_stream)

def _PrintPairs(pairs, output_stream, prefix=''):
  """Prints a list of string pairs with alignment."""
  first_column_length = max(len(a) for a, _ in pairs)
  format_string = '%s%%-%ds  %%s\n' % (prefix, first_column_length)
  for a, b in pairs:
    output_stream.write(format_string % (a, b.strip()))

class WprRecorder():

  def __init__(self, environment, target, args=None, parse_flags=True):
    self._base_dir = environment.top_level_dir
    self._output_dir = tempfile.mkdtemp()
    try:
      self._options = self._CreateOptions()
      self._benchmark = _MaybeGetInstanceOfClass(target, self._base_dir,
                                                 benchmark.Benchmark)
      if parse_flags:
        self._parser = self._options.CreateParser(usage='See %prog --help')
        self._AddCommandLineArgs()
        self._ParseArgs(args)
        self._ProcessCommandLineArgs(environment)
        self._SetExtraBrowserOptions()
      page_test = None
      if self._benchmark is not None:
        test = self._benchmark.CreatePageTest(self.options)
        # Object only needed for legacy pages; newer benchmarks don't need this.
        if isinstance(test, legacy_page_test.LegacyPageTest):
          page_test = test

      self._record_page_test = RecorderPageTest(page_test)
      options = self._options
      self._page_set_base_dir = (
          self._options.page_set_base_dir if
          (hasattr('options', 'page_set_base_dir') and
           options.page_set_base_dir)
          else self._base_dir)
      self._story_set = self._GetStorySet(target)
    except:
      self._CleanUp()
      raise

  def __enter__(self):
    return self

  def __exit__(self, *args):
    self._CleanUp()

  @property
  def options(self):
    return self._options

  @property
  def story_set(self):
    return self._story_set

  def _CreateOptions(self):
    options = browser_options.BrowserFinderOptions()
    options.browser_options.wpr_mode = wpr_modes.WPR_RECORD
    options.intermediate_dir = self._output_dir
    return options

  def _CleanUp(self):
    shutil.rmtree(self._output_dir)

  def CreateResults(self):
    if self._benchmark is not None:
      benchmark_name = self._benchmark.Name()
      benchmark_description = self._benchmark.Description()
    else:
      benchmark_name = 'record_wpr'
      benchmark_description = None

    return results_options.CreateResults(
        self._options,
        benchmark_name=benchmark_name,
        benchmark_description=benchmark_description,
        report_progress=True)

  def _AddCommandLineArgs(self):
    self._parser.add_option('--page-set-base-dir', action='store',
                            type='string')
    story_runner.AddCommandLineArgs(self._parser)
    if self._benchmark is not None:
      self._benchmark.AddCommandLineArgs(self._parser)
      self._benchmark.SetArgumentDefaults(self._parser)
    self._parser.add_option('--upload', action='store_true')
    self._parser.add_option('--use-local-wpr', action='store_true',
                            help='Builds and runs WPR from Catapult. '
                            'Also enables WPR debug output to STDOUT.')
    self._SetArgumentDefaults()

  def _SetArgumentDefaults(self):
    self._parser.set_defaults(output_formats=['none'])

  def _ParseArgs(self, args=None):
    args_to_parse = sys.argv[1:] if args is None else args
    self._parser.parse_args(args_to_parse)

  def _ProcessCommandLineArgs(self, environment):
    story_runner.ProcessCommandLineArgs(self._parser, self._options,
                                        environment)

    if self._options.use_live_sites:
      self._parser.error("Can't --use-live-sites while recording")

    if self._benchmark is not None:
      self._benchmark.ProcessCommandLineArgs(self._parser, self._options)

  def _SetExtraBrowserOptions(self):
    if self._benchmark is not None:
      self._benchmark.SetExtraBrowserOptions(self._options)

  def _GetStorySet(self, target):
    if self._benchmark is not None:
      return self._benchmark.CreateStorySet(self._options)
    story_set = _MaybeGetInstanceOfClass(target, self._page_set_base_dir,
                                         story.StorySet)
    if story_set is None:
      sys.stderr.write('Target %s is neither benchmark nor story set.\n'
                       % target)
      if not self._HintMostLikelyBenchmarksStories(target):
        sys.stderr.write(
            'Found no similar benchmark or story. Please use '
            '--list-benchmarks or --list-stories to list candidates.\n')
        self._parser.print_usage()
      sys.exit(1)
    return story_set

  def _HintMostLikelyBenchmarksStories(self, target):
    def _Impl(all_items, category_name):
      candidates = matching.GetMostLikelyMatchedObject(
          six.iteritems(all_items), target, name_func=lambda kv: kv[1].Name())
      if candidates:
        sys.stderr.write('\nDo you mean any of those %s below?\n' %
                         category_name)
        _PrintPairs([(k, v.Description()) for k, v in candidates], sys.stderr)
        return True
      return False

    has_benchmark_hint = _Impl(
        _GetSubclasses(self._base_dir, benchmark.Benchmark), 'benchmarks')
    has_story_hint = _Impl(
        _GetSubclasses(self._base_dir, story.StorySet), 'stories')
    return has_benchmark_hint or has_story_hint

  def Record(self, results):
    assert self._story_set.wpr_archive_info, (
        'Pageset archive_data_file path must be specified.')

    # Always record the benchmark one time only.
    self._options.pageset_repeat = 1
    self._story_set.wpr_archive_info.AddNewTemporaryRecording()
    self._record_page_test.CustomizeBrowserOptions(self._options)
    story_runner.RunStorySet(
        self._record_page_test,
        self._story_set,
        self._options,
        results)

  def HandleResults(self, results, upload_to_cloud_storage):
    if results.had_failures or results.had_skips:
      logging.warning('Some pages failed and/or were skipped. The recording '
                      'has not been updated for these pages.')
    results.Finalize()
    self._story_set.wpr_archive_info.AddRecordedStories(
        [run.story for run in results.IterStoryRuns() if run.ok],
        upload_to_cloud_storage,
        target_platform=self._record_page_test.platform)

def Main(environment, **log_config_kwargs):
  # the log level is set in browser_options
  log_config_kwargs.pop('level', None)
  log_config_kwargs.setdefault('format', DEFAULT_LOG_FORMAT)
  logging.basicConfig(**log_config_kwargs)

  parser = argparse.ArgumentParser(
      usage='Record a benchmark or a story (page set).')
  parser.add_argument(
      'benchmark_or_story_set', # Note, positional.
      help=('benchmark or story set name. This argument might be optional. '
            'If both benchmark name '
            'and story name are specified, this takes precedence as the '
            'target of the recording.'),
      nargs='?')
  parser.add_argument('--story', help='story (page set) name')
  parser.add_argument('--list-stories', dest='list_stories',
                      action='store_true', help='list all story names.')
  parser.add_argument('--list-benchmarks', dest='list_benchmarks',
                      action='store_true', help='list all benchmark names.')
  parser.add_argument('--upload', action='store_true',
                      help='upload to cloud storage.')

  args, extra_args = parser.parse_known_args()

  if args.list_benchmarks or args.list_stories:
    if args.list_benchmarks:
      _PrintAllBenchmarks(environment.top_level_dir, sys.stderr)
    if args.list_stories:
      _PrintAllStories(environment.top_level_dir, sys.stderr)
    return 0

  target = args.benchmark_or_story_set or args.story

  if not target:
    sys.stderr.write('Please specify target (benchmark or story). Please refer '
                     'usage below\n\n')
    parser.print_help()
    return 0

  binary_manager.InitDependencyManager(environment.client_configs)

  # TODO(crbug.com/1111556): update WprRecorder so that it handles the
  # difference between recording a benchmark vs recording a story better based
  # on the distinction between args.benchmark & args.story
  with WprRecorder(environment, target, extra_args) as wpr_recorder:
    results = wpr_recorder.CreateResults()
    wpr_recorder.Record(results)
    wpr_recorder.HandleResults(results, args.upload)
    return min(255, results.num_failed)


# Write a function, zipper_lists, that takes in the head of two linked lists as arguments. The function should zipper the two lists together into single linked list by alternating nodes. If one of the linked lists is longer than the other, the resulting list should terminate with the remaining nodes. The function should return the head of the zippered linked list.

# Do this in-place, by mutating the original Nodes.

# You may assume that both input lists are non-empty.

# class Node:
#   def __init__(self, val):
#     self.val = val
#     self.next = None

def zipper_lists(head_1, head_2):
  tail = head_1
  current_1 = head_1.next
  current_2 = head_2
  count = 0

  while current_1 and current_2:
    if count % 2 == 0:
      tail.next = current_2
      current_2 = current_2.next
    else:
      tail.next = current_1
      current_1 = current_1.next
    tail = tail.next
    count += 1

  if current_1:
    tail.next = current_1

  if current_2: tail.next = current_2

  return head_1

# a = Node("a")
# b = Node("b")
# c = Node("c")
# a.next = b
# b.next = c
# # a -> b -> c

# x = Node("x")
# y = Node("y")
# z = Node("z")
# x.next = y
# y.next = z
# x -> y -> z

# zipper_lists(a, x)
# a -> x -> b -> y -> c -> z


import numpy as np
import matplotlib.pyplot as plt
from const_avg_acc import const_avg_acc
from runge_kutta4 import runge_kutta4

def transient_regime(m, k, c, P, t, u0, udot0):
    # Showing effect of the initial conditions
    # and damping on the transient regime
    for i in range(len(c)):
        u_caa = const_avg_acc(m, k, c[i], P, t, u0[i], udot0[i])
        u_rk4 = runge_kutta4(m, k, c[i], P, t, u0[i], udot0[i])

        plt.figure(i)
        plt.rc('text', usetex=True)
        plt.rc('font', family='serif')
        plt.plot(t, u_rk4, 'b-', label='RK')
        plt.plot(t, u_caa, '--', color='red', label='CAA')

        plt.legend()
        plt.title(r'$\dot{{u}}_0$ = {:.2f}, $u_0$ = {:.2f}, $c$ = {:.2f}'.format(
            udot0[i], u0[i], c[i]))
        plt.grid(True)
        plt.xlabel('time, s')
        plt.ylabel('u(t)')
    plt.show()


#!/usr/bin/env python
# -*- coding: UTF-8 -*-

import rospy

from std_msgs.msg import Header
from sensor_msgs.msg import Image
import cv2
import numpy as np
import time
IMAGE_WIDTH=1280
IMAGE_HEIGHT=720

rospy.init_node('Image_talker', anonymous=True)
pub = rospy.Publisher('emotion_img', Image, queue_size=1)
rate = rospy.Rate(1) # 1hz

def publish_image(imgdata):
    while not rospy.is_shutdown():
        image_temp=Image()
        header = Header(stamp=rospy.Time.now())
        header.frame_id = 'map'
        image_temp.height=IMAGE_HEIGHT
        image_temp.width=IMAGE_WIDTH
        image_temp.encoding='rgb8'
        image_temp.data=np.array(imgdata).tostring()
        #print(imgdata)
        #image_temp.is_bigendian=True
        image_temp.header=header
        image_temp.step=1241*3
        pub.publish(image_temp)
        rospy.loginfo("图片成功发布")
        rate.sleep()

if __name__ == '__main__':
    try:
        img=cv2.imread('/home/zzzane/robot_empathy/src/emotion_module/image/emotion_img')
        publish_image(img)
    except rospy.ROSInterruptException:
        pass


try:
    getfile = open('myfile', 'r')
    getfile.write('test')
except IOError:
    print('Unable to open or read the data in the file.')

else:
    print('The file was written successfully')
finally:
    getfile.close()
    print('File is now closed.')

# finally allows us to always execute something even if there is an exception or not. This is usually used to signify the end of the try except.


import random as r
import os

def read_data_from_file(name):
    result = []
    with open(name, 'r', encoding='utf-8') as datafile:
        for line in datafile:
            result.append(line.strip('\n').split(','))
        return result

def save_data_to_file(name, data1, data2):
    with open(name, 'a', encoding='utf-8') as datafile:
        datafile.write(f'{data1}, {data2}\n')

def print_bus():
    os.system('cls')
    for i in read_data_from_file('bus.txt'):
        print(i)
    input('Enter для продолжения')

def add_bus():
    number_bus = input('Введите порядковый номер автобуса: > ')
    car_number = input('Введите госномер: > ')
    save_data_to_file('bus.txt', 'bus'+number_bus, car_number)
    print_bus()

def print_driver():
    os.system('cls')
    for i in read_data_from_file('driver.txt'):
        print(i)
    input('Enter для продолжения')

def add_driver():
    number_driver = input('Введите условный номер водителя: > ')
    lastname_driver = input('Введите фамилию водителя: > ')
    save_data_to_file('driver.txt', 'driver'+number_driver, lastname_driver)
    print_driver()

def print_route():
    os.system('cls')
    for i in read_data_from_file('route.txt'):
        print(i)
    input('Enter для продолжения')

def add_route():
    count_route = len(read_data_from_file('route.txt'))
    list_route = read_data_from_file('route.txt')
    list_bus = print_bus()
    list_driver = print_driver()
    while True:
        number_route = r.randint(1, 50)
        for _ in list_route:
            if number_route != list_route[1]:
                break
            else:
                print('Доступных маршрутов нет!')
        break
    name = f'm{count_route+1}, {number_route}'
    rand_bus = list_bus[r.randint(0, len(list_bus)-1)][0]
    rand_driver = list_driver[r.randint(0, len(list_driver)-1)][0]
    save_data_to_file('route.txt', f'{name}, {rand_bus}', rand_driver)
    print_route()

# print(add_route())


import unittest

import six
from mock import Mock, patch

import github3

from component_builder import github

class TestValidatePRURL(unittest.TestCase):

    def test_true_for_valid_pr_urls(self):
        for valid in [
                'https://blah/1',
                'http://github.com/ployst/ployst/pulls/1']:
            self.assertTrue(github.validate_pr_url(valid),
                            '{0} is not valid'.format(valid))

    def test_false_for_invalid_pr_urls(self):
        for invalid in ['null', 'http://github.com/ployst/ployst', '']:
            self.assertRaises(
                github.ValidationError, github.validate_pr_url, invalid
            )

class Label(object):
    def __init__(self, name):
        self.name = name

    def name(self):
        return self.name

class TestAddPRComponentsLabels(unittest.TestCase):

    def setUp(self):
        self.component_titles = ['library', 'service']
        self.current_labels = [
            Label('component:tool'), Label('component:service'),
            Label('not-a-component')]

    def test_replace_labels(self):
        to_add, to_del = github.replace_labels(
            self.component_titles, self.current_labels)

        six.assertCountEqual(self, to_add, ['component:library'])
        six.assertCountEqual(self, to_del, ['component:tool'])

    @patch('component_builder.github.get_repo')
    def test_add_pr_components_labels(self, get_repo):
        issue = Mock()
        issue.labels.return_value = self.current_labels
        repo = Mock()
        repo.issue.return_value = issue
        get_repo.return_value = repo

        pr_url = 'http://github.com/ployst/ployst/pulls/1'
        github.add_pr_components_labels(pr_url, self.component_titles)

        repo.issue.assert_called_once_with('1')
        issue.labels.assert_called_once_with()
        issue.remove_label.assert_called_once_with('component:tool')
        issue.add_labels.assert_called_once_with('component:library')
        self.assertEqual(len(repo.method_calls), 1)
        self.assertEqual(len(issue.method_calls), 3)

class TestUpdateBranch(unittest.TestCase):

    @patch('component_builder.github.get_sha')
    @patch('component_builder.github.get_repo')
    def test_forces_update_on_existing_branch(self, get_repo, get_sha):
        ref_mock = Mock()
        repo = Mock()
        repo.ref.return_value = ref_mock
        get_repo.return_value = repo
        branch_name = 'some-branch'
        sha = 'some-sha'
        get_sha.return_value = sha

        github.update_branch(branch_name)

        repo.ref.assert_called_once_with('heads/{0}'.format(branch_name))
        ref_mock.update.assert_called_once_with(sha, force=True)

    @patch('component_builder.github.get_sha')
    @patch('component_builder.github.get_repo')
    def test_creates_missing_branch(self, get_repo, get_sha):
        repo = Mock()
        repo.ref.side_effect = github3.exceptions.NotFoundError(Mock())
        get_repo.return_value = repo
        branch_name = 'some-branch'
        sha = 'some-sha'
        get_sha.return_value = sha

        github.update_branch(branch_name)

        repo.ref.assert_called_once_with('heads/{0}'.format(branch_name))
        repo.create_ref.assert_called_once_with(
            'refs/heads/{0}'.format(branch_name), sha)


# This backend is used together with an embedded Linux device such as the Raspberry Pi 4.
# The device uses the use the USB gadget kernel module simulate keyboard input.

import os

class HID_Backend:
    def __init__(self, read_cb):
        self.read_cb = read_cb
        self.hid_fd = os.open('/dev/hidg0', os.O_RDONLY)

    def write(self, report):
        with open('/dev/hidg0', 'rb+') as fd:
            fd.write(report.encode())

    def read_thread(self):
        """Read data from HID device."""
        while True:
            # read data from HID device
            hid_data = os.read(self.hid_fd, 1024)
            # Print the data as hex with a space between each byte
            print('Got data: ', end='')
            print(' '.join(format(x, '02x') for x in hid_data))
            command = hid_data[0]
            self.read_cb(command)


from flask import jsonify, request, make_response
from flask.ext.restful import Resource, reqparse

from library.connections import Connections

class GetCriteriaUsed(Resource):
    def __init__(self):
        self.reqparse = reqparse.RequestParser()
        self.reqparse.add_argument('title', type=str, location='json')
        self.reqparse.add_argument('description', type=str, location='json')
        self.reqparse.add_argument('done', type=bool, location='json')
        super(GetCriteriaUsed, self).__init__()

    def post(self):
        data = request.get_json()
        if not data:
            data = {"response": "Bad Request"}
            return jsonify(data)

        ssid = data.get('ssid')
        result = Connections.get_criteria_used(ssid)
        if result:
            return result
        else:
            return make_response(jsonify(result), 500)


# Sample code for an app to send data to and host and a port previously scanned. You can alter the code to send random amount of data for example, to test your systems against a DDOS attack

import tkinter as tk
import socket

def send_data():
    HOST = host_entry.get()
    PORT = int(port_entry.get())
    data = data_entry.get()
    try:
        with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
            s.connect((HOST, PORT))
            s.sendall(data.encode('utf-8'))
            response = s.recv(1024).decode('utf-8')
            result_label['text'] = 'Response: ' + response
    except socket.error as msg:
        result_label['text'] = 'Error: ' + str(msg)

root = tk.Tk()
root.title("Send Large Data to Port")

host_label = tk.Label(root, text="Host:")
host_label.grid(row=0, column=0)

host_entry = tk.Entry(root)
host_entry.grid(row=0, column=1)

port_label = tk.Label(root, text="Port:")
port_label.grid(row=1, column=0)

port_entry = tk.Entry(root)
port_entry.grid(row=1, column=1)

data_label = tk.Label(root, text="Data:")
data_label.grid(row=2, column=0)

data_entry = tk.Text(root, height=10, width=30)
data_entry.grid(row=2, column=1)

send_button = tk.Button(root, text="Send", command=send_data)
send_button.grid(row=3, column=0, columnspan=2, pady=10)

result_label = tk.Label(root, text="")
result_label.grid(row=4, column=0, columnspan=2)

root.mainloop()


"""Erawan GnuPG2 Decryption Plugin"""

import logging
import os
import os.path
import subprocess
import sys

logger = logging.getLogger(__name__)
logger.addHandler(logging.NullHandler())

def decrypt(config, enc_file):
    """Decrypt the encrypted backup using gpg2."""
    output_file = os.path.join(config['working_path'], 'decrypted_backup')
    args = '{} --batch --decrypt --passphrase {} --output {} {}'.format(
        config['plugins']['decryption']['gpg2_path'],
        os.environ['ERAWAN_DECRYPTION_KEY'],
        output_file,
        enc_file
    )
    try:
        subprocess.run(args, shell=True, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        logger.info('%s successfully decrypted', enc_file)
    except subprocess.CalledProcessError:
        logger.critical('Unable to decrypt %s', enc_file)
        sys.exit(1)
    return output_file


from tkinter import *
import tkinter as tk

def madLibsRules():
    print("Have you ever played Mad Libs? If not, here's how to play!")
    print("I have a story that's missing some words. It's your job to give me the words to fill in the blanks, however,")
    print("I can't show you the story until we are done.")
    print("I will ask you for a person, place, or thing. Give me a word you think can fit in to the story.")
def madLibsBeg():
    reply = input("Are you ready? ")
    if reply in 'YESYesyes':
        print("Great! Let's get started!")
    elif reply in 'NONono':
        print("Let's go over the rules again, then!")
        madLibsRules()
        madLibsBeg()
    else:
        print("Sorry, say yes or no.")
        madLibsBeg()
def madLibsAsk():
    global wordOne, wordTwo, wordThree, wordFour, wordFive
    wordOne = input("Give me an animal: ")
    wordTwo = input("Awesome!, I love those! Now, give me a name: ")
    wordThree = input("Great name! Now, I need a color: ")
    wordFour = input("That's my favorite color! I need a past tense verb: ")
    wordFive = input("That sounds like fun! Finally, I need a boy's name: ")
def madLibsFinal():
    print("Awesome! I have all the words I need!")
    reply = input("Are you happy with your words and ready to read our story? ")
    if reply in "YESYesyes":
        print("Okay! Here it is:")
    else:
        print("I'm sorry! We can try again!")
        madLibsAsk()
def madLibsStory():
    print(f"""There was a kid named {wordFive}. He wanted nothing more than a {wordOne}.
One year, his parents decided to give him a {wordThree} {wordOne} for his birthday!
He named his pet {wordTwo}, and wanted to bring it to the local {wordOne} park.
He hoped it'd play nice, but it {wordFour} all the others away!""")
## actually calling the functions
def main():
    ask = input("Do you want to play Mad Libs? ")
    if ask in "YESyes":
        print("Awesome! Let's get started!")
        madLibsRules()
        madLibsBeg()
        madLibsAsk()
        madLibsFinal()
        madLibsStory()
    elif ask in "NOno":
        print("That's okay. See you later!")
    else:
        print("Sorry, say yes or no.")
        main()
if __name__ == "__main__":
    main()

## fuck you lol


import numpy as np
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras.optimizers import Adam
from efficientdet_training import Generator, SeqGen
from losses import focal,smooth_l1
from model import EfficientDet, get_efficientdet_info
from tensorflow.keras.callbacks import TensorBoard, ReduceLROnPlateau, EarlyStopping
from utils.utils import BBoxUtility, ModelCheckpoint
from utils.anchors import get_anchors
from functools import partial
from tqdm import tqdm
import time
import os

tf.compat.v1.disable_eager_execution()
os.environ["CUDA_VISIBLE_DEVICES"]="0"

def get_classes(classes_path):
    '''loads the classes'''
    with open(classes_path) as f:
        class_names = f.readlines()
    class_names = [c.strip() for c in class_names]
    return class_names

gpus = tf.config.experimental.list_physical_devices(device_type='GPU')
for gpu in gpus:
    tf.config.experimental.set_memory_growth(gpu, True)

freeze_layers = [226, 328, 328, 373, 463, 463, 655, 802]
image_sizes = [512, 640, 768, 896, 1024, 1280, 1408, 1536]

if __name__ == "__main__":
    phi = 1
    annotation_path = '2007_train.txt'

    classes_path = 'model_data/voc_classes.txt'
    class_names = get_classes(classes_path)
    NUM_CLASSES = len(class_names)

    model = EfficientDet(phi,num_classes=NUM_CLASSES)
    # priors = get_anchors(image_sizes[phi])
    priors = get_anchors(get_efficientdet_info(phi)['image_size'])
    bbox_util = BBoxUtility(NUM_CLASSES, priors)

    val_split = 0.1
    with open(annotation_path) as f:
        lines = f.readlines()
    np.random.seed(10101)
    np.random.shuffle(lines)
    np.random.seed(None)
    num_val = int(len(lines)*val_split)
    num_train = len(lines) - num_val

    logging = TensorBoard(log_dir="logs")
    reduce_lr = ReduceLROnPlateau(monitor='val_loss', factor=0.5, patience=2, verbose=1)
    checkpoint = ModelCheckpoint('logs/phi1-ep{epoch:03d}-loss{loss:.3f}-val_loss{val_loss:.3f}.h5',
        monitor='val_loss', save_weights_only=True, save_best_only=False, period=1)
    early_stopping = EarlyStopping(monitor='val_loss', min_delta=0, patience=6, verbose=1)

    # for i in range(freeze_layers[phi]):
    for i in range(get_efficientdet_info(phi)['freeze_layers']):
        model.layers[i].trainable = False

    if True:
        BATCH_SIZE = 16
        Lr = 1e-3
        Init_Epoch = 0
        Freeze_Epoch = 50
        # gen = Generator(bbox_util, BATCH_SIZE, lines[:num_train], lines[num_train:],
        #                 (image_sizes[phi], image_sizes[phi]),NUM_CLASSES)
        gen = Generator(bbox_util, BATCH_SIZE, lines[:num_train], lines[num_train:],
                        get_efficientdet_info(phi)['image_shape'],NUM_CLASSES)

        model.compile(loss={
                    'regressor'    : smooth_l1(),
                    'classifier'    : focal()
                },optimizer=keras.optimizers.Adam(Lr)
        )
        print('Train on {} samples, val on {} samples, with batch size {}.'.format(num_train, num_val, BATCH_SIZE))
        model.fit(
                gen.generate(True,eager=False),
                steps_per_epoch=max(1, num_train//BATCH_SIZE),
                validation_data=gen.generate(False,eager=False),
                validation_steps=max(1, num_val//BATCH_SIZE),
                epochs=Freeze_Epoch,
                verbose=1,
                initial_epoch=Init_Epoch ,
                callbacks=[logging, checkpoint, reduce_lr, early_stopping]
            )

    # for i in range(freeze_layers[phi]):
    for i in range(get_efficientdet_info(phi)['freeze_layers']):
        model.layers[i].trainable = True

    if True:
        BATCH_SIZE = 16
        Lr = 5e-5
        Freeze_Epoch = 50
        Epoch = 100
        # gen = Generator(bbox_util, BATCH_SIZE, lines[:num_train], lines[num_train:],
        #                 (image_sizes[phi], image_sizes[phi]),NUM_CLASSES)
        gen = Generator(bbox_util, BATCH_SIZE, lines[:num_train], lines[num_train:],
                        get_efficientdet_info(phi)['image_shape'],NUM_CLASSES)

        model.compile(loss={
                    'regressor'    : smooth_l1(),
                    'classifier': focal()
                },optimizer=keras.optimizers.Adam(Lr)
        )
        print('Train on {} samples, val on {} samples, with batch size {}.'.format(num_train, num_val, BATCH_SIZE))
        model.fit(
                gen.generate(True,eager=False),
                steps_per_epoch=max(1, num_train//BATCH_SIZE),
                validation_data=gen.generate(False,eager=False),
                validation_steps=max(1, num_val//BATCH_SIZE),
                epochs=Freeze_Epoch,
                verbose=1,
                initial_epoch=Init_Epoch ,
                callbacks=[logging, checkpoint, reduce_lr, early_stopping]
            )