import bpy
from os import path
from mv import fd_types, unit, utils
from . import mv_closet_defaults as props_closet
from . import common_parts
from . import common_prompts
from . import common_lists

LOCK_DRAWER_TYPES=[('None','None','None'),
                   ('Top','Top','Top'),
                   ('Left','Left','Left'),
                   ('Right','Right','Right')]
FILE_RAIL_TYPES=[('Letter', 'Letter', 'Letter'),
                 ('Legal', 'Legal', 'Legal')]
FILE_DIRECTION_TYPES=[('Front to Back','Front to Back','Front to Back'),
                      ('Lateral', 'Lateral', 'Lateral')]

class Drawer_Stack(fd_types.Assembly):
    """ This drawer insert allows users to specify the quanity of drawers
        and the height of each indiviual drawer front height then the top
        shelf is automatically placed based on the heights. The remaining
        space is filled with an opening. The drawer max is 6.
    """
    property_id = props_closet.LIBRARY_NAME_SPACE + ".drawer_prompts"
    placement_type = "SPLITTER"
    type_assembly = "INSERT"
    mirror_y = False

    is_pull_out_tray = False

    number_of_drawers = 3 #1-9

    upper_interior = None
    upper_exterior = None

    def add_drawers(self):
        dim_x = self.get_var("dim_x")
        dim_y = self.get_var("dim_y")
        Left_Overlay = self.get_var("Left Overlay")
        Right_Overlay = self.get_var("Right Overlay")
        Bottom_Overlay = self.get_var("Bottom Overlay")
        Horizontal_Gap = self.get_var("Horizontal Gap")

        Front_Thickness = self.get_var("Front Thickness")
        Door_to_Cabinet_Gap = self.get_var("Door to Cabinet Gap")
        Open = self.get_var("Open")
        Drawer_Quantity = self.get_var("Drawer Quantity")
        Drawer_Stack_Height = self.get_var("Drawer Stack Height")
        Center_Pulls_on_Drawers = self.get_var("Center Pulls on Drawers")
        Drawer_Pull_From_Top = self.get_var("Drawer Pull From Top")
        Use_Double_Pulls = self.get_var("Use Double Pulls")
        Drawer_Box_Slide_Gap = self.get_var("Drawer Box Slide Gap")
        Drawer_Box_Bottom_Gap = self.get_var("Drawer Box Bottom Gap")
        Drawer_Box_Rear_Gap = self.get_var("Drawer Box Rear Gap")
        Drawer_Box_Top_Gap = self.get_var("Drawer Box Top Gap")
        Division_Thickness = self.get_var("Division Thickness")
        Lift_Drawers_From_Bottom = self.get_var("Lift Drawers From Bottom")
        Bottom_Drawer_Space = self.get_var("Bottom Drawer Space")
        No_Pulls = self.get_var("No Pulls")

        Shelf_Thickness = self.get_var("Shelf Thickness")
        Remove_Top_Shelf = self.get_var("Remove Top Shelf")
        Top_Overlay = self.get_var("Top Overlay")

        Full_Overlay = self.get_var("Full Overlay")
        Default_Middle_KD_Depth = self.get_var("Default Middle KD Depth")
        Max_Height_For_Centered_Pulls = self.get_var("Max Height For Centered Pulls")
        Large_Drawer_Pull_Height = self.get_var("Large Drawer Pull Height")
        Standard_Drawer_Rear_Gap = self.get_var("Standard Drawer Rear Gap")
        Deep_Drawer_Rear_Gap = self.get_var("Deep Drawer Rear Gap")
        EDDB = self.get_var("Extra Deep Drawer Box","EDDB")
        SDF = self.get_var("Small Drawer Face", "SDF")
        LDF = self.get_var("Large Drawer Face", "LDF")
        FHBD = self.get_var("Four Hole Box Difference", "FHBD")
        THBD = self.get_var("Three Hole Box Difference", "THBD")
        SDFOD = self.get_var("Single Door Full Overlay Difference", "SDFOD")
        AHOBD = self.get_var("Above Hamper Or Base Doors",'AHOBD')
        DBH = self.get_var("Double Box Height", "DBH")
        LDBH = self.get_var("Locked Double Box Height", "LDBH")
        Six_Hole = self.get_var("Six Hole")
        Seven_Hole = self.get_var("Seven Hole")

        prev_drawer_empty = None

        for i in range(1,self.number_of_drawers):
            DF_Height = self.get_var("Drawer " + str(i) + " Height","DF_Height")
            Lock_Drawer = self.get_var("Lock " + str(i) + " Drawer","Lock_Drawer")
            FR_Type = self.get_var("File Rail Type " + str(i), "FR_Type")
            FR_Direction = self.get_var("File Rail Direction " + str(i), "FR_Direction")
            Use_FR = self.get_var("Use File Rail " + str(i), "Use_FR")
            UDD = self.get_var("Use Double Drawer " + str(i), 'UDD')

            front_empty = self.add_empty()
            if prev_drawer_empty:
                prev_drawer_z_loc = prev_drawer_empty.get_var('loc_z','prev_drawer_z_loc')
                front_empty.z_loc('prev_drawer_z_loc-DF_Height-Horizontal_Gap',[prev_drawer_z_loc,DF_Height,Horizontal_Gap])
            else:
                front_empty.z_loc('Drawer_Stack_Height-DF_Height+IF(Lift_Drawers_From_Bottom,Bottom_Drawer_Space,0)',
                                  [Drawer_Stack_Height,DF_Height,Lift_Drawers_From_Bottom,Bottom_Drawer_Space])

            df_z_loc = front_empty.get_var('loc_z','df_z_loc')

            front = common_parts.add_drawer_front(self)
            front.x_loc('IF(Full_Overlay,dim_x+(Right_Overlay*2),dim_x+Right_Overlay)',[dim_x,Right_Overlay,Full_Overlay])
            front.y_loc('-Door_to_Cabinet_Gap-(dim_y*Open)',[Door_to_Cabinet_Gap,dim_y,Open,Front_Thickness])
            front.z_loc('df_z_loc',[df_z_loc])
            front.x_rot(value = 90)
            front.y_rot(value = -90)
            front.z_rot(value = 0)
            front.x_dim('DF_Height',[DF_Height])
            front.y_dim('IF(Full_Overlay,(dim_x+(Shelf_Thickness*2)-SDFOD),dim_x+Left_Overlay+Right_Overlay)',[dim_x,Left_Overlay,Right_Overlay,Full_Overlay,Shelf_Thickness,SDFOD])
            front.z_dim('Front_Thickness',[Front_Thickness])
            front.prompt('No Pulls','No_Pulls',[No_Pulls])
            front.prompt('Use Double Pulls','Use_Double_Pulls',[Use_Double_Pulls])
            front.prompt('Center Pulls on Drawers','Center_Pulls_on_Drawers',[Center_Pulls_on_Drawers])
            front.prompt('Drawer Pull From Top','Drawer_Pull_From_Top',[Drawer_Pull_From_Top])
            front.add_prompt(name="Left Overlay",prompt_type='DISTANCE',value=0,tab_index=0)
            front.add_prompt(name="Right Overlay",prompt_type='DISTANCE',value=0,tab_index=0)
            front.prompt('Left Overlay','Left_Overlay',[Left_Overlay])
            front.prompt('Right Overlay','Right_Overlay',[Right_Overlay])

            # front = common_parts.add_drawer_front(self)
            # front.x_loc('-Left_Overlay',[Left_Overlay])
            # front.y_loc('-Door_to_Cabinet_Gap-(dim_y*Open)',[Door_to_Cabinet_Gap,dim_y,Open,Front_Thickness])
            # front.z_loc('df_z_loc',[df_z_loc])
            # front.x_rot(value = 90)
            # front.y_rot(value = 0)
            # front.z_rot(value = 0)
            # front.x_dim('dim_x+Left_Overlay+Right_Overlay',[dim_x,Left_Overlay,Right_Overlay])
            # front.y_dim('DF_Height',[DF_Height])
            # front.z_dim('Front_Thickness',[Front_Thickness])
            # front.prompt('Hide','IF(Drawer_Quantity>' + str(i-1) + ',False,True)',[Drawer_Quantity])
            # front.prompt('No Pulls','No_Pulls',[No_Pulls])
            # front.prompt('Use Double Pulls','Use_Double_Pulls',[Use_Double_Pulls])
            # front.prompt('Center Pulls on Drawers','Center_Pulls_on_Drawers',[Center_Pulls_on_Drawers])
            # front.prompt('Drawer Pull From Top','Drawer_Pull_From_Top',[Drawer_Pull_From_Top])
            # front.add_prompt(name="Left Overlay",prompt_type='DISTANCE',value=0,tab_index=0)
            # front.add_prompt(name="Right Overlay",prompt_type='DISTANCE',value=0,tab_index=0)
            # front.prompt('Left Overlay','Left_Overlay',[Left_Overlay])
            # front.prompt('Right Overlay','Right_Overlay',[Right_Overlay])

            l_pull = common_parts.add_drawer_pull(self)
            l_pull.set_name("Drawer Pull")
            l_pull.x_loc('-Left_Overlay',[Left_Overlay])
            l_pull.y_loc('-Door_to_Cabinet_Gap-(dim_y*Open)',[Door_to_Cabinet_Gap,dim_y,Open,Front_Thickness])
            l_pull.z_loc('df_z_loc',[df_z_loc])
            l_pull.x_rot(value = 90)
            l_pull.y_rot(value = 0)
            l_pull.z_rot(value = 0)
            l_pull.x_dim('dim_x+Left_Overlay+Right_Overlay',[dim_x,Left_Overlay,Right_Overlay])
            l_pull.y_dim('DF_Height',[DF_Height])
            l_pull.z_dim('Front_Thickness',[Front_Thickness])
            l_pull.prompt("Pull X Location",'IF(DF_Height<Max_Height_For_Centered_Pulls,DF_Height/2,Large_Drawer_Pull_Height)',[Max_Height_For_Centered_Pulls,DF_Height,Large_Drawer_Pull_Height])
            l_pull.prompt("Pull Z Location",'IF(Use_Double_Pulls,(dim_x/4),(dim_x/2))+Right_Overlay',[Use_Double_Pulls,dim_x,Right_Overlay])
            l_pull.prompt('Hide','IF(No_Pulls,True,False)',[No_Pulls])

            r_pull = common_parts.add_drawer_pull(self)
            r_pull.set_name("Drawer Pull")
            r_pull.x_loc('-Left_Overlay',[Left_Overlay])
            r_pull.y_loc('-Door_to_Cabinet_Gap-(dim_y*Open)',[Door_to_Cabinet_Gap,dim_y,Open,Front_Thickness])
            r_pull.z_loc('df_z_loc',[df_z_loc])
            r_pull.x_rot(value = 90)
            r_pull.y_rot(value = 0)
            r_pull.z_rot(value = 0)
            r_pull.x_dim('dim_x+Left_Overlay+Right_Overlay',[dim_x,Left_Overlay,Right_Overlay])
            r_pull.y_dim('DF_Height',[DF_Height])
            r_pull.z_dim('Front_Thickness',[Front_Thickness])
            r_pull.prompt("Pull X Location",'IF(DF_Height<Max_Height_For_Centered_Pulls,DF_Height/2,Large_Drawer_Pull_Height)',[Large_Drawer_Pull_Height,Max_Height_For_Centered_Pulls,Center_Pulls_on_Drawers,DF_Height,Drawer_Pull_From_Top])
            r_pull.prompt("Pull Z Location",'dim_x-(dim_x/4)+Right_Overlay',[dim_x,Right_Overlay])
            r_pull.prompt('Hide','IF(No_Pulls,True,IF(Use_Double_Pulls,False,True))',[No_Pulls,Use_Double_Pulls])

            drawer = common_parts.add_drawer(self)
            drawer.set_name("Drawer Box")
            drawer.x_loc('Drawer_Box_Slide_Gap',[Drawer_Box_Slide_Gap])
            drawer.y_loc('-Door_to_Cabinet_Gap-(dim_y*Open)',[Door_to_Cabinet_Gap,dim_y,Open,Front_Thickness])
            #drawer.z_loc('df_z_loc+Drawer_Box_Bottom_Gap+IF(' + Drawer_Quantity== str(i) + ',Bottom_Overlay,0)',[df_z_loc,Drawer_Box_Bottom_Gap,Bottom_Overlay])
            drawer.z_loc('df_z_loc+Drawer_Box_Bottom_Gap',[df_z_loc,Drawer_Box_Bottom_Gap])
            drawer.x_rot(value = 0)
            drawer.y_rot(value = 0)
            drawer.z_rot(value = 0)
            drawer.x_dim('dim_x-(Drawer_Box_Slide_Gap*2)',[dim_x,Drawer_Box_Slide_Gap])
            drawer.y_dim('IF(Use_FR,IF(FR_Direction == 1,IF(FR_Type == 0,INCH(14),INCH(17)),IF(dim_y <= EDDB, dim_y-Standard_Drawer_Rear_Gap, dim_y-Deep_Drawer_Rear_Gap)),IF(dim_y <= EDDB, dim_y-Standard_Drawer_Rear_Gap, dim_y-Deep_Drawer_Rear_Gap))',
                         [dim_y, EDDB, Standard_Drawer_Rear_Gap, Deep_Drawer_Rear_Gap, Use_FR, FR_Direction, FR_Type])

            drawer.z_dim("IF(DF_Height<SDF,DF_Height-THBD,IF(OR(Lock_Drawer==2,Lock_Drawer==3),IF(UDD,LDBH,DF_Height-Drawer_Box_Top_Gap-Drawer_Box_Bottom_Gap),IF(DF_Height==SDF,DF_Height-FHBD,IF(UDD,DBH,DF_Height-Drawer_Box_Top_Gap-Drawer_Box_Bottom_Gap))))", [DF_Height,SDF,Drawer_Box_Top_Gap,Drawer_Box_Bottom_Gap,FHBD,THBD,Lock_Drawer,LDBH,DBH,UDD])

            drawer.prompt('Use File Rail','Use_FR',[Use_FR])
            drawer.prompt('File Rail Type','FR_Type',[FR_Type])
            drawer.prompt('File Rail Direction','FR_Direction',[FR_Direction])

            double_drawer = common_parts.add_drawer(self)
            double_drawer.set_name("Drawer Box")
            double_drawer.x_loc('Drawer_Box_Slide_Gap',[Drawer_Box_Slide_Gap])
            double_drawer.y_loc('-Door_to_Cabinet_Gap-(dim_y*(Open/2))',[Door_to_Cabinet_Gap,dim_y,Open,Front_Thickness])
            double_drawer.z_loc('df_z_loc+Drawer_Box_Bottom_Gap+Shelf_Thickness+IF(OR(Lock_Drawer==2,Lock_Drawer==3),LDBH,DBH)',[df_z_loc,Drawer_Box_Bottom_Gap,Lock_Drawer,DBH,LDBH,Shelf_Thickness])
            double_drawer.x_rot(value = 0)
            double_drawer.y_rot(value = 0)
            double_drawer.z_rot(value = 0)
            double_drawer.x_dim('dim_x-(Drawer_Box_Slide_Gap*2)',[dim_x,Drawer_Box_Slide_Gap])
            double_drawer.y_dim('IF(dim_y <= EDDB, dim_y-Standard_Drawer_Rear_Gap, dim_y-Deep_Drawer_Rear_Gap)',[dim_y, EDDB, Standard_Drawer_Rear_Gap, Deep_Drawer_Rear_Gap])

            double_drawer.z_dim("DBH",[DBH])

            double_drawer.prompt('Hide', "IF(AND(DF_Height >= Six_Hole,DF_Height <= Seven_Hole,dim_y >= "+ str(unit.inch(15.99)) +"),IF(UDD,False,True),True)",[UDD,DF_Height,Six_Hole,Seven_Hole,dim_y])

            double_drawer.prompt('Use File Rail','Use_FR',[Use_FR])
            double_drawer.prompt('File Rail Type','FR_Type',[FR_Type])
            double_drawer.prompt('File Rail Direction','FR_Direction',[FR_Direction])

            prev_drawer_empty = front_empty

            drawer_z_loc = drawer.get_var('loc_z','drawer_z_loc')
            drawer_z_dim = drawer.get_var('dim_z','drawer_z_dim')

            drawer_lock = common_parts.add_lock(self)
            drawer_lock.x_loc('IF(Lock_Drawer==2,-Division_Thickness,IF(Lock_Drawer==3,dim_x+Division_Thickness,dim_x/2))',[Lock_Drawer,dim_x,Division_Thickness])
            drawer_lock.y_loc('IF(Lock_Drawer==1,-Front_Thickness-Door_to_Cabinet_Gap-(dim_y*Open),+INCH(.75))',[Lock_Drawer,Front_Thickness,Door_to_Cabinet_Gap,Open,dim_y])
            drawer_lock.z_loc('drawer_z_loc+IF(UDD,DF_Height-Drawer_Box_Top_Gap-Drawer_Box_Bottom_Gap,drawer_z_dim)-INCH(.5)',[drawer_z_loc,drawer_z_dim,UDD,DF_Height,Drawer_Box_Top_Gap,Drawer_Box_Bottom_Gap])
            drawer_lock.y_rot(value = 0)
            drawer_lock.z_rot('IF(Lock_Drawer==2,radians(-90),IF(Lock_Drawer==3,radians(90),0))',[Lock_Drawer])
            drawer_lock.prompt('Hide', 'IF(Lock_Drawer>0,False,True)',[Lock_Drawer])

            KD_Shelf = common_parts.add_shelf(self)
            KD_Shelf.x_loc(value = 0)
            KD_Shelf.y_loc('Default_Middle_KD_Depth', [Default_Middle_KD_Depth])
            KD_Shelf.z_loc('df_z_loc+DF_Height-Top_Overlay',[df_z_loc,DF_Height,Top_Overlay])
            KD_Shelf.x_rot(value = 180)
            KD_Shelf.y_rot(value = 0)
            KD_Shelf.z_rot(value = 0)
            KD_Shelf.x_dim('dim_x',[dim_x])
            KD_Shelf.y_dim('Default_Middle_KD_Depth', [Default_Middle_KD_Depth])
            KD_Shelf.z_dim('-Shelf_Thickness',[Shelf_Thickness])

            KD_Shelf.prompt('Is Locked Shelf',value=True)
            KD_Shelf.prompt('Hide', value = True)

            KD_Shelf.y_dim('IF(Lock_Drawer>0, dim_y, Default_Middle_KD_Depth)', [Lock_Drawer, dim_y, Default_Middle_KD_Depth])
            KD_Shelf.y_loc('IF(Lock_Drawer>0, dim_y, Default_Middle_KD_Depth)', [Lock_Drawer, dim_y, Default_Middle_KD_Depth])

            if(i==1):
                KD_Shelf.y_dim('dim_y', [dim_y])
                KD_Shelf.y_loc('dim_y', [dim_y])
                KD_Shelf.prompt('Hide', 'IF(Remove_Top_Shelf,True,IF(Lock_Drawer>0,False,True))',[Remove_Top_Shelf,Lock_Drawer])
            if(i==2):
                KD_Shelf.prompt('Hide', 'IF(AHOBD,True,IF( Drawer_Quantity-1 == 2,False,IF( Drawer_Quantity-1 == 3,False,IF(Lock_Drawer>0,False,True))))', [Drawer_Quantity, Lock_Drawer,AHOBD])

            if(i==3):
                KD_Shelf.prompt('Hide', 'IF(Drawer_Quantity-1 == 4,False,IF(Drawer_Quantity-1 == 5,False,IF(Drawer_Quantity-1 == 7,False,IF(Lock_Drawer>0,False,True))))', [Drawer_Quantity, Lock_Drawer])

            if(i==4):
                KD_Shelf.prompt('Hide', 'IF(Drawer_Quantity-1 == 6,False,IF(Drawer_Quantity-1 == 8,False,IF(Lock_Drawer>0,False,True)))', [Drawer_Quantity, Lock_Drawer])

            if(i==5):
                KD_Shelf.prompt('Hide', 'IF(Drawer_Quantity-1 == 7,False,IF(Lock_Drawer>0,False,True))',[Lock_Drawer,Drawer_Quantity])

            if(i==6):
                KD_Shelf.prompt('Hide', 'IF(Drawer_Quantity-1 == 8,False,IF(Lock_Drawer>0,False,True))',[Lock_Drawer,Drawer_Quantity])

            if(i==7):
                KD_Shelf.prompt('Hide', 'IF(Lock_Drawer>0,False,True)',[Lock_Drawer])

            if(i==8):
                KD_Shelf.prompt('Hide', 'IF(Lock_Drawer>0,False,True)',[Lock_Drawer])

    def draw(self):
        self.create_assembly()
        self.obj_bp.mv.export_as_subassembly = True
        self.obj_bp.lm_closets.export_nested_subassemblies = True

        props = props_closet.get_object_props(self.obj_bp)
        props.is_drawer_stack_bp = True

        common_prompts.add_thickness_prompts(self)
        common_prompts.add_front_overlay_prompts(self)
        common_prompts.add_pull_prompts(self)
        common_prompts.add_drawer_pull_prompts(self)
        common_prompts.add_drawer_box_prompts(self)

        self.add_tab(name='Drawer Options',tab_type='VISIBLE')
        self.add_tab(name='Formulas',tab_type='HIDDEN')

        self.add_prompt(name="Open",prompt_type='PERCENTAGE',value=0,tab_index=0)
        self.add_prompt(name="Lift Drawers From Bottom",prompt_type='CHECKBOX',value=False,tab_index=0)
        self.add_prompt(name="Bottom Drawer Space",prompt_type='DISTANCE',value=0,tab_index=0)
        self.add_prompt(name="Remove Bottom Shelf",prompt_type='CHECKBOX',value=True,tab_index=0)
        self.add_prompt(name="Remove Top Shelf",prompt_type='CHECKBOX',value=True,tab_index=0)
        self.add_prompt(name="Shelf Thickness",prompt_type='DISTANCE',value=unit.inch(0.75),tab_index=1)
        self.add_prompt(name="Drawer Quantity",prompt_type='QUANTITY',value=self.number_of_drawers,tab_index=0)
        self.add_prompt(name="Drawer Stack Height",prompt_type='DISTANCE',value=0,tab_index=0)
        self.add_prompt(name="Drawer Stack Backing Gap",prompt_type='DISTANCE',value=0,tab_index=0)
        self.add_prompt(name="Use Mirror",prompt_type='CHECKBOX',value=False,tab_index=0)
        self.add_prompt(name="Cleat Location", prompt_type='COMBOBOX', items=["Above", "Below", "None"], value=0, tab_index=0, columns=3)
        self.add_prompt(name="Cleat Height",prompt_type='DISTANCE',value=unit.inch(3.64),tab_index=0)

        self.add_prompt(name="Default Middle KD Depth",prompt_type='DISTANCE',value=unit.inch(6),tab_index=1)
        self.add_prompt(name="Full Overlay",prompt_type='CHECKBOX',value=False,tab_index=0)
        self.add_prompt(name="Max Height For Centered Pulls",prompt_type='DISTANCE',value=unit.millimeter(315.95),tab_index=1)
        self.add_prompt(name="Large Drawer Pull Height",prompt_type='DISTANCE',value=unit.millimeter(93.98),tab_index=1)
        self.add_prompt(name="Standard Drawer Rear Gap",prompt_type='DISTANCE',value=unit.inch(1.25),tab_index=0)
        self.add_prompt(name="Deep Drawer Rear Gap",prompt_type='DISTANCE',value=unit.inch(2),tab_index=0)
        self.add_prompt(name="Extra Deep Drawer Box",prompt_type='DISTANCE',value=unit.inch(16),tab_index=1)
        self.add_prompt(name="Small Drawer Face",prompt_type='DISTANCE',value=unit.millimeter(123.95),tab_index=1)
        self.add_prompt(name="Large Drawer Face",prompt_type='DISTANCE',value=unit.millimeter(315.95),tab_index=1)
        self.add_prompt(name="Four Hole Box Difference",prompt_type='DISTANCE',value=unit.inch(2.88),tab_index=1)
        self.add_prompt(name="Three Hole Box Difference",prompt_type='DISTANCE',value=unit.inch(1.62),tab_index=1)
        self.add_prompt(name="Pard Has Bottom KD",prompt_type='CHECKBOX',value=False,tab_index=1)

        self.add_prompt(name="Above Hamper Or Base Doors",prompt_type='CHECKBOX',value=False,tab_index=0)

        self.add_prompt(name="Six Hole",prompt_type='DISTANCE',value=unit.inch(7.4),tab_index=1)
        self.add_prompt(name="Seven Hole",prompt_type='DISTANCE',value=unit.inch(8.66),tab_index=1)
        self.add_prompt(name="Double Box Height",prompt_type='DISTANCE',value=unit.inch(2),tab_index=1)
        self.add_prompt(name="Locked Double Box Height",prompt_type='DISTANCE',value=unit.inch(2.68),tab_index=1)

        self.add_prompt(name="Above Hamper Or Base Doors",prompt_type='CHECKBOX',value=False,tab_index=0)

        for i in range(1,self.number_of_drawers):
            self.add_prompt(name="Lock " + str(i) + " Drawer",prompt_type='COMBOBOX',items=["None","Top","Left","Right"],value=0,tab_index=0,columns=4)
            self.add_prompt(name="Drawer " + str(i) + " Height",prompt_type='DISTANCE',value=unit.millimeter(91.95),tab_index=0)
            self.add_prompt(name="File Rail Type " + str(i),prompt_type='COMBOBOX',value=0,items=['Letter', 'Legal'],tab_index=1)
            self.add_prompt(name="File Rail Direction " + str(i),prompt_type='COMBOBOX',value=0,items=['Front to Back','Lateral'],tab_index=1)
            self.add_prompt(name="Use File Rail " + str(i),prompt_type='CHECKBOX',value=False,tab_index=1)
            self.add_prompt(name="Use Double Drawer " + str(i),prompt_type='CHECKBOX',value=False,tab_index=1)

        dim_x = self.get_var("dim_x")
        dim_y = self.get_var("dim_y")
        dim_z = self.get_var("dim_z")
        Bottom_Overlay = self.get_var("Bottom Overlay")
        Top_Overlay = self.get_var("Top Overlay")
        Drawer_Stack_Height = self.get_var("Drawer Stack Height")
        Shelf_Thickness = self.get_var("Shelf Thickness")
        dq = self.get_var("Drawer Quantity",'dq')
        df1 = self.get_var("Drawer 1 Height",'df1')
        df2 = self.get_var("Drawer 2 Height",'df2')
        df3 = self.get_var("Drawer 3 Height",'df3')
        df4 = self.get_var("Drawer 4 Height",'df4')
        df5 = self.get_var("Drawer 5 Height",'df5')
        df6 = self.get_var("Drawer 6 Height",'df6')
        df7 = self.get_var("Drawer 7 Height",'df7')
        df8 = self.get_var("Drawer 8 Height",'df8')
        hg = self.get_var("Horizontal Gap",'hg')
        Lift_Drawers_From_Bottom = self.get_var("Lift Drawers From Bottom")
        Bottom_Drawer_Space = self.get_var("Bottom Drawer Space")
        Remove_Top_Shelf = self.get_var("Remove Top Shelf")
        Remove_Bottom_Shelf = self.get_var("Remove Bottom Shelf")
        Cleat_Location = self.get_var("Cleat Location")
        Cleat_Height = self.get_var("Cleat Height")

        self.prompt(
            'Drawer Stack Backing Gap',
            'Drawer_Stack_Height+Shelf_Thickness*2-Top_Overlay+IF(Lift_Drawers_From_Bottom,Bottom_Drawer_Space,0)',
            [Drawer_Stack_Height,Shelf_Thickness,Top_Overlay,Lift_Drawers_From_Bottom,Bottom_Drawer_Space,Cleat_Location]
        )

        self.prompt('Drawer Stack Height',
                    'df1+IF(dq>1,df2+hg,0)+IF(dq>2,df3+hg,0)+IF(dq>3,df4+hg,0)+IF(dq>4,df5+hg,0)+IF(dq>5,df6+hg,0)+IF(dq>6,df7+hg,0)+IF(dq>7,df8+hg,0)-(Bottom_Overlay*2)+(MILLIMETER(.85688)*2)', # ? Change height to allow correct door heights
                    [df1,df2,df3,df4,df5,df6,df7,df8,dq,hg,Bottom_Overlay])

        self.add_drawers()

        cleat = common_parts.add_cleat(self)
        cleat.set_name("Bottom Cleat")
        cleat.x_loc(value = 0)
        cleat.y_loc('dim_y',[dim_y])
        cleat.z_loc('Drawer_Stack_Height+IF(Cleat_Location==0,Shelf_Thickness,0)-Top_Overlay+IF(Lift_Drawers_From_Bottom,Bottom_Drawer_Space,0)',
                        [Drawer_Stack_Height,Shelf_Thickness,Top_Overlay,Lift_Drawers_From_Bottom,Bottom_Drawer_Space,Cleat_Location])
        cleat.x_rot(value=-90)
        cleat.y_rot(value = 0)
        cleat.z_rot(value = 0)
        cleat.x_dim('dim_x',[dim_x])
        cleat.y_dim('IF(Cleat_Location==0,-Cleat_Height,Cleat_Height)', [Cleat_Height, Cleat_Location])
        cleat.z_dim('-Shelf_Thickness',[Shelf_Thickness])
        cleat.prompt("Hide", "IF(Cleat_Location==2,True,False)", [Cleat_Location])
        cleat.prompt('Use Cleat Cover', 'IF(Cleat_Location==0,True,False)', [Cleat_Location])

        top_shelf = common_parts.add_shelf(self)
        top_shelf.x_loc(value = 0)
        top_shelf.y_loc('dim_y', [dim_y])
        top_shelf.z_loc('Drawer_Stack_Height-Top_Overlay+IF(Lift_Drawers_From_Bottom,Bottom_Drawer_Space,0)',
                        [Drawer_Stack_Height,Top_Overlay,Lift_Drawers_From_Bottom,Bottom_Drawer_Space])
        top_shelf.x_rot(value = 180)
        top_shelf.y_rot(value = 0)
        top_shelf.z_rot(value = 0)
        top_shelf.x_dim('dim_x',[dim_x])
        top_shelf.y_dim('dim_y',[dim_y])
        top_shelf.z_dim('-Shelf_Thickness',[Shelf_Thickness])
        top_shelf.prompt('Hide','IF(Remove_Top_Shelf,False,True)',[Remove_Top_Shelf])
        top_shelf.prompt('Is Locked Shelf',value=True)

        '''
        second_shelf = common_parts.add_shelf(self)
        second_shelf.x_loc(value = 0)
        second_shelf.y_loc(value = 0)
        second_shelf.z_loc('IF(dq==4,df4,IF(dq==5,df5,IF(dq==6,df6,0)))-Bottom_Overlay+Shelf_Thickness-Top_Overlay+IF(Lift_Drawers_From_Bottom,Bottom_Drawer_Space,0)',
                           [dq,df4,df5,df6,Bottom_Overlay,Shelf_Thickness,Top_Overlay,Lift_Drawers_From_Bottom,Bottom_Drawer_Space])
        second_shelf.x_rot(value = 0)
        second_shelf.y_rot(value = 0)
        second_shelf.z_rot(value = 0)
        second_shelf.x_dim('dim_x',[dim_x])
        second_shelf.y_dim('dim_y',[dim_y])
        second_shelf.z_dim('-Shelf_Thickness',[Shelf_Thickness])
        second_shelf.prompt('Hide','IF(dq>3,False,True)',[dq])
        second_shelf.prompt('Is Locked Shelf',value=True)
        '''

        top_shelf_z_loc = top_shelf.get_var('loc_z','top_shelf_z_loc')

        bottom_shelf = common_parts.add_shelf(self)
        bottom_shelf.x_loc(value = 0)
        bottom_shelf.y_loc('dim_y', [dim_y])
        bottom_shelf.z_loc('IF(Lift_Drawers_From_Bottom,Bottom_Drawer_Space,0)-Shelf_Thickness',
                        [Drawer_Stack_Height,Shelf_Thickness,Top_Overlay,Lift_Drawers_From_Bottom,Bottom_Drawer_Space])
        bottom_shelf.x_rot(value = 180)
        bottom_shelf.y_rot(value = 0)
        bottom_shelf.z_rot(value = 0)
        bottom_shelf.x_dim('dim_x',[dim_x])
        bottom_shelf.y_dim('dim_y',[dim_y])
        bottom_shelf.z_dim('-Shelf_Thickness',[Shelf_Thickness])
        bottom_shelf.prompt('Hide','IF(Remove_Bottom_Shelf,False,True)',[Remove_Bottom_Shelf])
        bottom_shelf.prompt('Is Locked Shelf',value=True)

        opening = common_parts.add_opening(self)
        opening.x_loc(value = 0)
        opening.y_loc(value = 0)
        opening.z_loc('top_shelf_z_loc+Shelf_Thickness',[top_shelf_z_loc,Shelf_Thickness])
        opening.x_rot(value = 0)
        opening.y_rot(value = 0)
        opening.z_rot(value = 0)
        opening.x_dim('dim_x',[dim_x])
        opening.y_dim('dim_y',[dim_y])
        opening.z_dim('dim_z-top_shelf_z_loc-Shelf_Thickness',[dim_z,top_shelf_z_loc,Shelf_Thickness])

        if self.upper_exterior:
            opening.obj_bp.mv.exterior_open = False

            self.upper_exterior.draw()
            self.upper_exterior.obj_bp.parent = self.obj_bp
            self.upper_exterior.x_loc(value = 0)
            self.upper_exterior.y_loc(value = 0)
            self.upper_exterior.z_loc('top_shelf_z_loc',[top_shelf_z_loc])
            self.upper_exterior.x_rot(value = 0)
            self.upper_exterior.y_rot(value = 0)
            self.upper_exterior.z_rot(value = 0)
            self.upper_exterior.x_dim('dim_x',[dim_x])
            self.upper_exterior.y_dim('dim_y',[dim_y])
            self.upper_exterior.z_dim('dim_z-top_shelf_z_loc',[dim_z,top_shelf_z_loc])

        if self.upper_interior:
            opening.obj_bp.mv.interior_open = False

            self.upper_interior.draw()
            self.upper_interior.obj_bp.parent = self.obj_bp
            self.upper_interior.x_loc(value = 0)
            self.upper_interior.y_loc(value = 0)
            self.upper_interior.z_loc('top_shelf_z_loc',[top_shelf_z_loc])
            self.upper_interior.x_rot(value = 0)
            self.upper_interior.y_rot(value = 0)
            self.upper_interior.z_rot(value = 0)
            self.upper_interior.x_dim('dim_x',[dim_x])
            self.upper_interior.y_dim('dim_y',[dim_y])
            self.upper_interior.z_dim('dim_z-top_shelf_z_loc',[dim_z,top_shelf_z_loc])

        #self.update()

class PROMPTS_Drawer_Prompts(bpy.types.Operator):
    bl_idname = props_closet.LIBRARY_NAME_SPACE + ".drawer_prompts"
    bl_label = "Drawer Prompts"
    bl_description = "This shows all of the available drawer options"
    bl_options = {'UNDO'}

    object_name = bpy.props.StringProperty(name="Object Name")

    assembly = None
    part = None

    drawer_quantity = bpy.props.EnumProperty(name="Drawer Quantity",
                                   items=[('1',"1",'1'),
                                          ('2',"2",'2'),
                                          ('3',"3",'3'),
                                          ('4',"4",'4'),
                                          ('5',"5",'5'),
                                          ('6',"6",'6'),
                                          ('7',"7",'7'),
                                          ('8',"8",'8'),
                                          ('9',"9",'9')],
                                   default = '3')

    drawer_1_height = bpy.props.EnumProperty(name="Drawer 1 Height",
                                   items=common_lists.FRONT_HEIGHTS)

    drawer_2_height = bpy.props.EnumProperty(name="Drawer 2 Height",
                                   items=common_lists.FRONT_HEIGHTS)

    drawer_3_height = bpy.props.EnumProperty(name="Drawer 3 Height",
                                   items=common_lists.FRONT_HEIGHTS)

    drawer_4_height = bpy.props.EnumProperty(name="Drawer 4 Height",
                                   items=common_lists.FRONT_HEIGHTS)

    drawer_5_height = bpy.props.EnumProperty(name="Drawer 5 Height",
                                   items=common_lists.FRONT_HEIGHTS)

    drawer_6_height = bpy.props.EnumProperty(name="Drawer 6 Height",
                                   items=common_lists.FRONT_HEIGHTS)

    drawer_7_height = bpy.props.EnumProperty(name="Drawer 7 Height",
                                   items=common_lists.FRONT_HEIGHTS)

    drawer_8_height = bpy.props.EnumProperty(name="Drawer 8 Height",
                                   items=common_lists.FRONT_HEIGHTS)

    lock_1_drawer = bpy.props.EnumProperty(name="Lock 1 Drawer",
                                           items=LOCK_DRAWER_TYPES,
                                           default = 'None')

    lock_2_drawer = bpy.props.EnumProperty(name="Lock 2 Drawer",
                                           items=LOCK_DRAWER_TYPES,
                                           default = 'None')

    lock_3_drawer = bpy.props.EnumProperty(name="Lock 3 Drawer",
                                           items=LOCK_DRAWER_TYPES,
                                           default = 'None')

    lock_4_drawer = bpy.props.EnumProperty(name="Lock 4 Drawer",
                                           items=LOCK_DRAWER_TYPES,
                                           default = 'None')

    lock_5_drawer = bpy.props.EnumProperty(name="Lock 5 Drawer",
                                           items=LOCK_DRAWER_TYPES,
                                           default = 'None')

    lock_6_drawer = bpy.props.EnumProperty(name="Lock 6 Drawer",
                                           items=LOCK_DRAWER_TYPES,
                                           default = 'None')

    lock_7_drawer = bpy.props.EnumProperty(name="Lock 7 Drawer",
                                           items=LOCK_DRAWER_TYPES,
                                           default = 'None')

    lock_8_drawer = bpy.props.EnumProperty(name="Lock 8 Drawer",
                                           items=LOCK_DRAWER_TYPES,
                                           default = 'None')

    file_rail_type_1 = bpy.props.EnumProperty(name="File Rail Type 1",
                                              items=FILE_RAIL_TYPES,
                                              default = 'Letter')
    file_rail_direction_1 = bpy.props.EnumProperty(name="File Rail Direction 1",
                                                   items=FILE_DIRECTION_TYPES,
                                                   default = 'Front to Back')
    file_rail_type_2 = bpy.props.EnumProperty(name="File Rail Type 2",
                                              items=FILE_RAIL_TYPES,
                                              default = 'Letter')
    file_rail_direction_2 = bpy.props.EnumProperty(name="File Rail Direction 2",
                                                   items=FILE_DIRECTION_TYPES,
                                                   default = 'Front to Back')
    file_rail_type_3 = bpy.props.EnumProperty(name="File Rail Type 3",
                                              items=FILE_RAIL_TYPES,
                                              default = 'Letter')
    file_rail_direction_3 = bpy.props.EnumProperty(name="File Rail Direction 3",
                                                   items=FILE_DIRECTION_TYPES,
                                                   default = 'Front to Back')
    file_rail_type_4 = bpy.props.EnumProperty(name="File Rail Type 4",
                                              items=FILE_RAIL_TYPES,
                                              default = 'Letter')
    file_rail_direction_4 = bpy.props.EnumProperty(name="File Rail Direction 4",
                                                   items=FILE_DIRECTION_TYPES,
                                                   default = 'Front to Back')
    file_rail_type_5 = bpy.props.EnumProperty(name="File Rail Type 5",
                                              items=FILE_RAIL_TYPES,
                                              default = 'Letter')
    file_rail_direction_5 = bpy.props.EnumProperty(name="File Rail Direction 5",
                                                   items=FILE_DIRECTION_TYPES,
                                                   default = 'Front to Back')
    file_rail_type_6 = bpy.props.EnumProperty(name="File Rail Type 6",
                                              items=FILE_RAIL_TYPES,
                                              default = 'Letter')
    file_rail_direction_6 = bpy.props.EnumProperty(name="File Rail Direction 6",
                                                   items=FILE_DIRECTION_TYPES,
                                                   default = 'Front to Back')
    file_rail_type_7 = bpy.props.EnumProperty(name="File Rail Type 7",
                                              items=FILE_RAIL_TYPES,
                                              default = 'Letter')
    file_rail_direction_7 = bpy.props.EnumProperty(name="File Rail Direction 7",
                                                   items=FILE_DIRECTION_TYPES,
                                                   default = 'Front to Back')
    file_rail_type_8 = bpy.props.EnumProperty(name="File Rail Type 8",
                                              items=FILE_RAIL_TYPES,
                                              default = 'Letter')
    file_rail_direction_8 = bpy.props.EnumProperty(name="File Rail Direction 8",
                                                   items=FILE_DIRECTION_TYPES,
                                                   default = 'Front to Back')

    bottom_offset = bpy.props.EnumProperty(name="Bottom Offset",
                                   items=common_lists.DRAWER_BOTTOM_OFFSETS)

    front_heights = []

    drawer_qty_prompt = None

    @classmethod
    def poll(cls, context):
        return True

    def execute(self, context):
        # THIS NEEDS TO BE RUN TWICE TO AVOID RECAL ERRORS
        utils.run_calculators(utils.get_parent_assembly_bp(self.assembly.obj_bp))
        utils.run_calculators(utils.get_parent_assembly_bp(self.assembly.obj_bp))
        return {'FINISHED'}

    def check(self, context):
        if self.drawer_qty_prompt:
            props = props_closet.get_scene_props()

            self.drawer_qty_prompt.QuantityValue = int(self.drawer_quantity)
            small_drawer_face = self.assembly.get_prompt("Small Drawer Face")
            large_drawer_face = self.assembly.get_prompt("Large Drawer Face")
            six_hole = self.assembly.get_prompt("Six Hole")
            seven_hole = self.assembly.get_prompt("Seven Hole")

            for i in range(1,self.drawer_qty_prompt.value()):
                drawer_height = self.assembly.get_prompt("Drawer " + str(i) + " Height")
                lock_drawer = self.assembly.get_prompt("Lock " + str(i) + " Drawer")
                slide_type = self.assembly.get_prompt("Drawer " + str(i) + " Slide Type") #DONT REMOVE USED in exec
                file_rail_type = self.assembly.get_prompt("File Rail Type " + str(i))
                file_rail_direction = self.assembly.get_prompt("File Rail Direction " + str(i))
                use_double_drawer = self.assembly.get_prompt("Use Double Drawer " + str(i))
                bottom_offset = self.assembly.get_prompt("Bottom Drawer Space")
                if props.closet_defaults.use_32mm_system:
                    if drawer_height:
                        if not drawer_height.equal:
                            exec("drawer_height.set_value(unit.inch(float(self.drawer_" + str(i) + "_height) / 25.4))")
                    if bottom_offset:
                        bottom_offset.set_value(unit.inch(float(self.bottom_offset)/25.4))

                if lock_drawer:
                    exec("lock_drawer.set_value(self.lock_" + str(i) + "_drawer)")
                if slide_type:
                    exec("slide_type.set_value(self.drawer_" + str(i) + "_slide)")
                if file_rail_type:
                    exec("file_rail_type.set_value(self.file_rail_type_" + str(i) + ")")
                if file_rail_direction:
                    exec("file_rail_direction.set_value(self.file_rail_direction_" + str(i) + ")")
                if(drawer_height.value() < small_drawer_face.value()):
                    lock_drawer.set_value("None")
                if(drawer_height.value() < six_hole.value() or drawer_height.value() > seven_hole.value() or self.assembly.obj_y.location.y < unit.inch(15.99)):
                    use_double_drawer.set_value(False)

            pard_has_bottom_KD = self.assembly.get_prompt("Pard Has Bottom KD")
            remove_bottom_shelf = self.assembly.get_prompt("Remove Bottom Shelf")
            lift_drawers_from_bottom = self.assembly.get_prompt("Lift Drawers From Bottom")
            parent_assembly = fd_types.Assembly(self.assembly.obj_bp.parent)
            RBS = parent_assembly.get_prompt('Remove Bottom Hanging Shelf ' + self.assembly.obj_bp.mv.opening_name)
            if(lift_drawers_from_bottom.value()):
                pard_has_bottom_KD.set_value(False)
            elif(RBS):
                if(RBS.value()):
                    pard_has_bottom_KD.set_value(True)
            if(pard_has_bottom_KD.value()):
                remove_bottom_shelf.set_value(False)

        self.assign_mirror_material(self.assembly.obj_bp)
        utils.run_calculators(self.assembly.obj_bp)
        bpy.ops.cabinetlib.update_scene_from_pointers()
        self.assembly.obj_bp.location = self.assembly.obj_bp.location # Redraw Viewport

        # THIS NEEDS TO BE RUN TWICE TO AVOID RECAL ERRORS
        utils.run_calculators(utils.get_parent_assembly_bp(self.assembly.obj_bp))
        utils.run_calculators(utils.get_parent_assembly_bp(self.assembly.obj_bp))
        props_closet.update_render_materials(self, context)
        return True

    def get_front_heights(self):
        self.front_heights = []
        for front in common_lists.FRONT_HEIGHTS:
            self.front_heights.append(front[0])

    def set_properties_from_prompts(self):
        props = props_closet.get_scene_props()
        bottom_offset = self.assembly.get_prompt("Bottom Drawer Space").value()

        if bottom_offset:
            self.bottom_offset = str(round(unit.meter_to_millimeter(bottom_offset)))

        self.get_front_heights()

        self.drawer_qty_prompt = self.assembly.get_prompt("Drawer Quantity")
        if self.drawer_qty_prompt:
            self.drawer_quantity = str(self.drawer_qty_prompt.QuantityValue)

            for i in range(1,self.drawer_qty_prompt.value()):
                drawer_height = self.assembly.get_prompt("Drawer " + str(i) + " Height")
                lock_drawer = self.assembly.get_prompt("Lock " + str(i) + " Drawer") #DONT REMOVE USED in exec
                file_rail_type = self.assembly.get_prompt("File Rail Type " + str(i)) #DONT REMOVE USED in exec
                file_rail_direction = self.assembly.get_prompt("File Rail Direction " + str(i)) #DONT REMOVE USED in exec
                exec("self.lock_" + str(i) + "_drawer = lock_drawer.value()")
                exec("self.file_rail_type_" + str(i) + " = file_rail_type.value()")
                exec("self.file_rail_direction_" + str(i) + " = file_rail_direction.value()")
                if props.closet_defaults.use_32mm_system:
                    if drawer_height:
                        value = str(round(drawer_height.DistanceValue * 1000,3))
                        if value in self.front_heights:
                            exec("self.drawer_" + str(i) + "_height = value")

    def assign_mirror_material(self,obj):
        use_mirror = self.assembly.get_prompt("Use Mirror")
        if use_mirror.value():
            if obj.cabinetlib.type_mesh == 'BUYOUT':
                for mat_slot in obj.cabinetlib.material_slots:
                    if "Glass" in mat_slot.name:
                        mat_slot.pointer_name = 'Mirror'
        else:
            if obj.cabinetlib.type_mesh == 'BUYOUT':
                for mat_slot in obj.cabinetlib.material_slots:
                    if "Glass" in mat_slot.name:
                        mat_slot.pointer_name = 'Glass'

        for child in obj.children:
            self.assign_mirror_material(child)

    def invoke(self,context,event):
        obj = bpy.data.objects[self.object_name]
        obj_assembly_bp = utils.get_assembly_bp(obj)
        self.part = fd_types.Assembly(obj_assembly_bp)
        obj_insert_bp = utils.get_bp(obj,'INSERT')
        self.assembly = fd_types.Assembly(obj_insert_bp)
        self.set_properties_from_prompts()
        wm = context.window_manager
        return wm.invoke_props_dialog(self, width=450)

    def draw_drawer_heights(self,layout):
        col = layout.column(align=True)
        props = props_closet.get_scene_props()

        drawer_quantity = self.assembly.get_prompt("Drawer Quantity")
        small_drawer_face = self.assembly.get_prompt("Small Drawer Face")
        large_drawer_face = self.assembly.get_prompt("Large Drawer Face")
        six_hole = self.assembly.get_prompt("Six Hole")
        seven_hole = self.assembly.get_prompt("Seven Hole")

        if drawer_quantity:
            for i in range(1,drawer_quantity.value()):

                drawer_height = self.assembly.get_prompt("Drawer " + str(i) + " Height")
                lock_drawer = self.assembly.get_prompt("Lock " + str(i) + " Drawer")

                file_rail_type = self.assembly.get_prompt("File Rail Type " + str(i))
                file_rail_direction = self.assembly.get_prompt("File Rail Direction " + str(i))
                use_file_rail = self.assembly.get_prompt("Use File Rail " + str(i))
                use_double_drawer = self.assembly.get_prompt("Use Double Drawer " + str(i))
                extra_deep_drawer_box = self.assembly.get_prompt("Extra Deep Drawer Box")
                if(drawer_height and lock_drawer and file_rail_type and file_rail_direction and use_file_rail and extra_deep_drawer_box):
                    if(self.assembly.obj_y.location.y<=extra_deep_drawer_box.value()):
                        drawer_box_rear_gap = self.assembly.get_prompt("Standard Drawer Rear Gap")
                    else:
                        drawer_box_rear_gap = self.assembly.get_prompt("Deep Drawer Rear Gap")

                    width = self.assembly.obj_x.location.x - unit.inch(2)
                    depth = self.assembly.obj_y.location.y - drawer_box_rear_gap.value()
                    letter = unit.inch(12.5)
                    legal = unit.inch(15.5)

                    if drawer_height and drawer_quantity.value() >= i:
                        box = col.box()
                        row = box.row()

                        col_1 = row.column()
                        if props.closet_defaults.use_32mm_system:
                            col_1.label("Drawer " + str(i) + " Height:")
                            col_1.prop(self,'drawer_' + str(i) + '_height',text="")
                        else:
                            drawer_height.draw_prompt(col_1)

                        if(drawer_height.value() >= small_drawer_face.value()):
                            col_2 = row.column()
                            col_2.label("Lock:")
                            col_2.prop(self,'lock_' + str(i) + '_drawer',text="")
                        else:
                            lock_drawer.set_value('None')

                        if(drawer_height and six_hole and seven_hole):
                            if(drawer_height.value() >= six_hole.value() and drawer_height.value() <= seven_hole.value() and self.assembly.obj_y.location.y >= unit.inch(15.99)):
                                col_3 = row.column(align=True)
                                col_3.label("Double Jewelry Drawer")
                                col_3.prop(use_double_drawer,"CheckBoxValue",text="")

                        if(drawer_height.value()>=large_drawer_face.value() and (width >= letter or depth >= letter)):
                            col_3 = row.column(align=True)
                            #row.label("File Rail:")
                            col_3.prop(use_file_rail,"CheckBoxValue",text="File Rail")

                            if(use_file_rail.value()):
                                if(width<letter):
                                    if(depth<legal):

                                        col_3.label("Letter")
                                        exec("file_rail_type_" +str(i)+"= 'Letter'")
                                        file_rail_type.set_value('Letter')

                                        col_3.label("Lateral")
                                        exec("file_rail_direction_" +str(i)+"= 'Lateral'")
                                        file_rail_direction.set_value('Lateral')

                                    else:

                                        col_3.prop(self,'file_rail_type_' + str(i),text="")

                                        col_3.label("Lateral")
                                        exec("file_rail_direction_" +str(i)+"= 'Lateral'")
                                        file_rail_direction.set_value('Lateral')

                                elif(width<legal):
                                    if(depth<letter):

                                        col_3.label("Letter")
                                        exec("file_rail_type_" +str(i)+"= 'Letter'")
                                        file_rail_type.set_value('Letter')

                                        col_3.label("Front to Back")
                                        exec("file_rail_direction_" +str(i)+"= 'Front to Back'")
                                        file_rail_direction.set_value('Front to Back')

                                    elif(depth<legal):

                                        col_3.label("Letter")
                                        exec("file_rail_type_" +str(i)+"= 'Letter'")
                                        file_rail_type.set_value('Letter')

                                        col_3.prop(self,'file_rail_direction_' + str(i),text="")

                                    else:

                                        if(file_rail_direction.value() == 'Front to Back'):
                                            col_3.label("Letter")
                                            exec("file_rail_type_" +str(i)+"= 'Letter'")
                                            file_rail_type.set_value('Letter')

                                            col_3.prop(self,'file_rail_direction_' + str(i),text="")
                                        else:
                                            col_3.prop(self,'file_rail_type_' + str(i),text="")

                                            col_3.prop(self,'file_rail_direction_' + str(i),text="")

                                else:
                                    if(depth<letter):

                                        col_3.prop(self,'file_rail_type_' + str(i),text="")

                                        col_3.label("Front to Back")
                                        exec("file_rail_direction_" +str(i)+"= 'Front to Back'")
                                        file_rail_direction.set_value('Front to Back')
                                    elif(depth<legal):
                                        if(file_rail_direction.value() == 'Lateral'):
                                            col_3.label("Letter")
                                            exec("file_rail_type_" +str(i)+"= 'Letter'")
                                            file_rail_type.set_value('Letter')

                                            col_3.prop(self,'file_rail_direction_' + str(i),text="")
                                        else:
                                            col_3.prop(self,'file_rail_type_' + str(i),text="")

                                            col_3.prop(self,'file_rail_direction_' + str(i),text="")
                                    else:
                                        col_3.prop(self,'file_rail_type_' + str(i),text="")

                                        col_3.prop(self,'file_rail_direction_' + str(i),text="")

                        else:
                            use_file_rail.set_value(False)

    def is_glass_front(self):
        if "Glass" in self.part.obj_bp.mv.comment:
            return True
        else:
            return False

    def draw(self, context):
        layout = self.layout
        if self.assembly.obj_bp:
            if self.assembly.obj_bp.name in context.scene.objects:
                if self.drawer_qty_prompt:
                    open_drawer = self.assembly.get_prompt('Open')
                    box = layout.box()

                    full_overlay = self.assembly.get_prompt('Full Overlay')
                    standard_drawer_rear_gap = self.assembly.get_prompt("Standard Drawer Rear Gap")
                    deep_drawer_rear_gap = self.assembly.get_prompt("Deep Drawer Rear Gap")
                    drawer_depth = self.assembly.obj_y.location.y
                    extra_deep_drawer_box = self.assembly.get_prompt("Extra Deep Drawer Box")

                    #hot = self.assembly.get_prompt('Half Overlay Top')
                    #hob = self.assembly.get_prompt('Half Overlay Bottom')
                    #hol = self.assembly.get_prompt('Half Overlay Left')
                    #hor = self.assembly.get_prompt('Half Overlay Right')
                    use_double_pulls = self.assembly.get_prompt('Use Double Pulls')
                    remove_top_shelf = self.assembly.get_prompt('Remove Top Shelf')
                    remove_bottom_shelf = self.assembly.get_prompt('Remove Bottom Shelf')
                    lift_drawers_from_bottom = self.assembly.get_prompt('Lift Drawers From Bottom')
                    no_pulls = self.assembly.get_prompt('No Pulls')
                    use_mirror = self.assembly.get_prompt("Use Mirror")
                    cleat_loc = self.assembly.get_prompt("Cleat Location")

                    propbox = box.box()
                    propbox.label("Options:",icon='SCRIPT')

                    row = propbox.row()
                    row.label("Open Drawers")
                    row.prop(open_drawer,'PercentageValue',text="")

                    row = propbox.row()
                    row.label("Drawer Rear Gap")
                    if(drawer_depth<=extra_deep_drawer_box.value()):
                        row.prop(standard_drawer_rear_gap,"DistanceValue",text="")
                    else:
                        row.prop(deep_drawer_rear_gap,"DistanceValue",text="")

                    row = propbox.row()
                    if cleat_loc:
                        cleat_loc.draw_prompt(row, text="Cleat Location")

                    row = propbox.row()
                    if lift_drawers_from_bottom:
                        lift_drawers_from_bottom.draw_prompt(row,text="Suspended Drawers",split_text=False)

                    if lift_drawers_from_bottom.value():
                        row.prop(self,'bottom_offset',text="")

                    row = propbox.row()
                    if use_double_pulls:
                        use_double_pulls.draw_prompt(row,split_text=False)
                    if no_pulls:
                        no_pulls.draw_prompt(row,split_text=False)

                    row = propbox.row()
                    if remove_top_shelf:
                        row.prop(remove_top_shelf,"CheckBoxValue",text="Top KD")
                    if remove_bottom_shelf:
                        row.prop(remove_bottom_shelf,"CheckBoxValue",text="Bottom KD")

                    row = propbox.row()
                    row = propbox.row()
                    full_overlay.draw_prompt(row,split_text=False,text="Full Overlay")
                    #row.label("Half Overlays:")
                    #hot.draw_prompt(row,split_text=False,text="Top")
                    #hob.draw_prompt(row,split_text=False,text="Bottom")
                    #hol.draw_prompt(row,split_text=False,text="Left")
                    #hor.draw_prompt(row,split_text=False,text="Right")
                    #half_overlay.draw_prompt(row,split_text=False,text="Half")

                    if self.is_glass_front():
                        row = propbox.row()
                        use_mirror.draw_prompt(row,split_text=False)

                    self.draw_drawer_heights(box)

class OPS_Drawer_Drop(bpy.types.Operator):
    bl_idname = "closets.insert_drawer_drop"
    bl_label = "Custom drag and drop for drawers insert"

    object_name = bpy.props.StringProperty(name="Object Name")
    product_name = bpy.props.StringProperty(name="Product Name")
    category_name = bpy.props.StringProperty(name="Category Name")
    library_name = bpy.props.StringProperty(name="Library Name")

    insert = None
    default_z_loc = 0.0
    default_height = 0.0
    default_depth = 0.0

    openings = []
    objects = []

    header_text = "Place Insert   (Esc, Right Click) = Cancel Command  :  (Left Click) = Place Insert"

    def execute(self, context):
        return {'FINISHED'}

    def __del__(self):
        bpy.context.area.header_text_set()

    def set_wire_and_xray(self, obj, turn_on):
        if turn_on:
            obj.draw_type = 'WIRE'
        else:
            obj.draw_type = 'TEXTURED'
        obj.show_x_ray = turn_on
        for child in obj.children:
            self.set_wire_and_xray(child,turn_on)

    def get_insert(self,context):
        bpy.ops.object.select_all(action='DESELECT')

        if self.object_name in bpy.data.objects:
            bp = bpy.data.objects[self.object_name]
            self.insert = fd_types.Assembly(bp)

        if not self.insert:
            lib = context.window_manager.cabinetlib.lib_inserts[self.library_name]
            blend_path = os.path.join(lib.lib_path,self.category_name,self.product_name + ".blend")
            obj_bp = None

            if os.path.exists(blend_path):
                obj_bp = utils.get_group(blend_path)
                self.insert = fd_types.Assembly(obj_bp)
            else:
                self.insert = utils.get_insert_class(context,self.library_name,self.category_name,self.product_name)

            if obj_bp:
                pass
            #TODO: SET UP UPDATE OPERATOR
                    # self.insert.update(obj_bp)
            else:
                self.insert.draw()
                self.insert.update()

        self.show_openings()
        utils.init_objects(self.insert.obj_bp)
        self.default_z_loc = self.insert.obj_bp.location.z
        self.default_height = self.insert.obj_z.location.z
        self.default_depth = self.insert.obj_y.location.y

    def invoke(self,context,event):
        self.insert = None
        context.window.cursor_set('WAIT')
        self.get_insert(context)
        self.set_wire_and_xray(self.insert.obj_bp, True)
        if self.insert is None:
            bpy.ops.fd_general.error('INVOKE_DEFAULT',message="Could Not Find Insert Class: " + "\\" + self.library_name + "\\" + self.category_name + "\\" + self.product_name)
            return {'CANCELLED'}
        context.window.cursor_set('PAINT_BRUSH')
        context.scene.update() # THE SCENE MUST BE UPDATED FOR RAY CAST TO WORK
        context.window_manager.modal_handler_add(self)
        return {'RUNNING_MODAL'}

    def cancel_drop(self,context,event):
        if self.insert:
            utils.delete_object_and_children(self.insert.obj_bp)
        bpy.context.window.cursor_set('DEFAULT')
        return {'FINISHED'}

    def show_openings(self):
        #Clear  to avoid old/duplicate openings
        self.objects.clear()
        insert_type = self.insert.obj_bp.mv.placement_type
        for obj in  bpy.context.scene.objects:
            #Check to avoid opening that is part of the dropped insert
            if utils.get_parent_assembly_bp(obj) == self.insert.obj_bp:
                continue

            if obj.layers[0]: #Make sure wall is not hidden
                opening = None
                if obj.mv.type_group == 'OPENING':
                    if insert_type in {'INTERIOR','SPLITTER'}:
                        opening = fd_types.Assembly(obj) if obj.mv.interior_open else None
                    if insert_type == 'EXTERIOR':
                        opening = fd_types.Assembly(obj) if obj.mv.exterior_open else None
                    if opening:
                        cage = opening.get_cage()
                        opening.obj_x.hide = True
                        opening.obj_y.hide = True
                        opening.obj_z.hide = True
                        cage.hide_select = False
                        cage.hide = False
                        self.objects.append(cage)

    def selected_opening(self,selected_obj):
        if selected_obj:
            opening = fd_types.Assembly(selected_obj.parent)
            if opening.obj_bp.parent:
                if self.insert.obj_bp.parent is not opening.obj_bp.parent:
                    self.insert.obj_bp.parent = opening.obj_bp.parent
                    self.insert.obj_bp.location = opening.obj_bp.location
                    self.insert.obj_bp.rotation_euler = opening.obj_bp.rotation_euler
                    self.insert.obj_x.location.x = opening.obj_x.location.x
                    self.insert.obj_y.location.y = opening.obj_y.location.y
                    self.insert.obj_z.location.z = opening.obj_z.location.z
                    utils.run_calculators(self.insert.obj_bp)
                    return opening

    def set_opening_name(self,obj,name):
        obj.mv.opening_name = name
        for child in obj.children:
            self.set_opening_name(child, name)

    def place_insert(self,opening):
        if self.insert.obj_bp.mv.placement_type == 'INTERIOR':
            opening.obj_bp.mv.interior_open = False
        if self.insert.obj_bp.mv.placement_type == 'EXTERIOR':
            opening.obj_bp.mv.exterior_open = False
        if self.insert.obj_bp.mv.placement_type == 'SPLITTER':
            opening.obj_bp.mv.interior_open = False
            opening.obj_bp.mv.exterior_open = False

        utils.copy_assembly_drivers(opening,self.insert)
        self.set_opening_name(self.insert.obj_bp, opening.obj_bp.mv.opening_name)
        self.set_wire_and_xray(self.insert.obj_bp, False)

        for obj in self.objects:
            obj.hide = True
            obj.hide_render = True
            obj.hide_select = True

    def insert_drop(self,context,event):
        if len(self.objects) == 0:
            bpy.ops.fd_general.error('INVOKE_DEFAULT',message="There are no openings in this scene.")
            return self.cancel_drop(context,event)
        else:
            selected_point, selected_obj = utils.get_selection_point(context,event,objects=self.objects)
            bpy.ops.object.select_all(action='DESELECT')
            selected_opening = self.selected_opening(selected_obj)
            if selected_opening:
                selected_obj.select = True

                if event.type == 'LEFTMOUSE' and event.value == 'PRESS':
                    self.place_insert(selected_opening)
                    self.set_backing_bottom_gap(self.insert.obj_bp, selected_opening)
                    self.set_drawer_cleat_hide(self.insert.obj_bp, selected_opening)
                    self.set_bottom_KD(self.insert.obj_bp,selected_opening)
                    self.set_above_hamper_or_base_door(self.insert.obj_bp)
                    context.scene.objects.active = self.insert.obj_bp
                    # THIS NEEDS TO BE RUN TWICE TO AVOID RECAL ERRORS
                    utils.run_calculators(self.insert.obj_bp)
                    utils.run_calculators(self.insert.obj_bp)
                    # TOP LEVEL PRODUCT RECAL
                    utils.run_calculators(utils.get_parent_assembly_bp(self.insert.obj_bp))
                    utils.run_calculators(utils.get_parent_assembly_bp(self.insert.obj_bp))

                    bpy.context.window.cursor_set('DEFAULT')

                    return {'FINISHED'}

            return {'RUNNING_MODAL'}

    def set_drawer_cleat_hide(self, insert_bp, selected_opening):
        drawer_assembly = fd_types.Assembly(insert_bp)
        carcass_bp = utils.get_parent_assembly_bp(insert_bp)
        carcass_assembly = fd_types.Assembly(carcass_bp)
        opening_name = selected_opening.obj_bp.mv.opening_name
        Back_Thickness = carcass_assembly.get_var("Opening " + opening_name + " Backing Thickness", "Back_Thickness")
        Cleat_Location = drawer_assembly.get_var("Cleat Location")

        for child in insert_bp.children:
            if child.lm_closets.is_cleat_bp:
                cleat_assembly = fd_types.Assembly(child)
                cleat_assembly.prompt('Hide', 'IF(OR(Cleat_Location==2,Back_Thickness==1),True,False)', [Back_Thickness, Cleat_Location])

        carcass_props = props_closet.get_object_props(carcass_bp)
        cleat_location = drawer_assembly.get_prompt("Cleat Location")
        has_counter_top = False

        for child in carcass_bp.children:
            if child.lm_closets.is_countertop_bp or child.lm_closets.is_counter_top_insert_bp:
                has_counter_top = True
        if has_counter_top or carcass_props.is_island:
            cleat_location.set_value("Below")

    def set_backing_bottom_gap(self, insert_bp, selected_opening):
        opening_name = selected_opening.obj_bp.mv.opening_name
        carcass_bp = utils.get_parent_assembly_bp(insert_bp)
        drawer_assembly = fd_types.Assembly(insert_bp)
        Drawer_Stack_Backing_Gap = drawer_assembly.get_var('Drawer Stack Backing Gap')

        for child in carcass_bp.children:
            if child.lm_closets.is_back_bp:
                if child.mv.opening_name == opening_name:
                    back_assembly = fd_types.Assembly(child)
                    bottom_insert_gap = back_assembly.get_prompt('Bottom Insert Gap')

                    if bottom_insert_gap:
                        back_assembly.prompt('Bottom Insert Gap', 'Drawer_Stack_Backing_Gap', [Drawer_Stack_Backing_Gap])

    def set_above_hamper_or_base_door(self, insert_bp):
        drawer_assembly = fd_types.Assembly(insert_bp)
        above_hamper_or_base_door = drawer_assembly.get_prompt("Above Hamper Or Base Doors")
        parent_bp = utils.get_parent_assembly_bp(insert_bp)

        if(above_hamper_or_base_door):
            if(parent_bp.lm_closets.is_door_bp):
                door_assembly = fd_types.Assembly(parent_bp)
                door_type = door_assembly.get_prompt("Door Type")
                if(door_type):
                    if(door_type.value() == 'Base'):
                        above_hamper_or_base_door.set_value(True)
            elif(parent_bp.lm_closets.is_hamper_bp):
                above_hamper_or_base_door.set_value(True)
            else:
                for child in parent_bp.children:
                    if(child.lm_closets.is_door_insert_bp):
                        door_assembly = fd_types.Assembly(child)
                        door_type = door_assembly.get_prompt("Door Type")
                        if(door_type):
                            if(door_type.value() == 'Base'):
                                above_hamper_or_base_door.set_value(True)
                    elif(child.lm_closets.is_hamper_insert_bp):
                        above_hamper_or_base_door.set_value(True)

    def set_bottom_KD(self, insert_bp, selected_opening):
        opening_name = selected_opening.obj_bp.mv.opening_name
        carcass_bp = utils.get_parent_assembly_bp(insert_bp)
        drawer_assembly = fd_types.Assembly(insert_bp)
        carcass_assembly = fd_types.Assembly(carcass_bp)
        if(carcass_assembly.get_prompt("Opening " + str(opening_name) + " Floor Mounted") and carcass_assembly.get_prompt('Remove Bottom Hanging Shelf ' + str(opening_name))):
            if(carcass_assembly.get_prompt("Opening " + str(opening_name) + " Floor Mounted").value() or carcass_assembly.get_prompt('Remove Bottom Hanging Shelf ' + str(opening_name)).value()):
                drawer_assembly.get_prompt("Pard Has Bottom KD").set_value(True)

    def modal(self, context, event):
        context.area.tag_redraw()
        context.area.header_text_set(text=self.header_text)

        if event.type in {'MIDDLEMOUSE', 'WHEELUPMOUSE', 'WHEELDOWNMOUSE'}:
            return {'PASS_THROUGH'}

        if event.type in {'ESC','RIGHTMOUSE'}:
            self.cancel_drop(context,event)
            return {'FINISHED'}

        return self.insert_drop(context,event)

bpy.utils.register_class(PROMPTS_Drawer_Prompts)
bpy.utils.register_class(OPS_Drawer_Drop)


import pygame
import sys
import numpy as np

width, height = 800, 600

def next_generation(array):
    size_x = len(array) - 2
    size_y = len(array[0]) - 2
    array_copy = array.copy()
    for x in range(1, size_x + 1):
        for y in range(1, size_y + 1):
            living_cell = bool(array_copy[x][y])
            living_neighbours = 0
            for x1 in range(-1, 2):
                for y1 in range(-1, 2):
                    if (x1, y1) == (0, 0): continue
                    living_neighbours += array_copy[x + x1][y + y1]

            if living_cell:
                if living_neighbours not in range(2, 4):
                    array[x][y] = 0
            elif living_neighbours == 3:
                array[x][y] = 1
            else:
                array[x, y] = array_copy[x, y]

def create_array(cols, rows):
    temp_array = np.random.randint(2, size=(cols, rows))
    padded_array = np.pad(temp_array, pad_width=1, mode='constant', constant_values=0)
    return padded_array

def run(screen, array):
    cols = len(array) - 2
    rows = len(array[0]) - 2
    running = True
    while running:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            elif event.type == pygame.VIDEORESIZE:
                # Update the window size
                width1, height1 = event.size
                screen = pygame.display.set_mode((width1, height1), pygame.RESIZABLE)

        rect_width = width // cols
        rect_height = height // rows

        next_generation(array)

        # Draw the rectangles
        for row in range(rows):
            for col in range(cols):
                color = WHITE if array[col][row] == 0 else BLACK
                pygame.draw.rect(screen, color, (col * rect_width, row * rect_height, rect_width, rect_height))

        # Update the display
        pygame.display.flip()

        # Control the frame rate
        clock.tick(10)  # Adjust the number to make the animation faster or slower

    # Quit Pygame
    pygame.quit()
    sys.exit()

# Initialize Pygame
pygame.init()

# Set up the initial display

scr = pygame.display.set_mode((width, height), pygame.RESIZABLE)
pygame.display.set_caption("Resizable Animated Chessboard")

# Define colors
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
# Set up the clock
clock = pygame.time.Clock()
run(scr, create_array(80, 60))


def take(n:int,xs):
    for x in xs:
        if x < n:
            yield x

print(list(take(3,range(7))))

a = lambda x: x>0

def myfilter(f,xs):
    for x in xs:
        if f(x) == True:
            yield x

print(list(myfilter(a,range(-5,8))))


import yfinance as yf
import streamlit as st
import pandas as pd
import plotly.express as px

st.set_page_config(layout="wide")
st.title("Ativo Analytics")

ticker1 = st.text_input("Digite o ticker do primeiro ativo (por exemplo, BTC-USD):")
ticker2 = st.text_input("Digite o ticker do segundo ativo, caso queira comparar")
genre = st.radio("Selecione o Período:", ["1D", "5D", "1M", "3M", "6M", "1Y", "5Y", "10Y", "MAX"], index=None, horizontal=True)

preco_inicial = None
preco_final = None
retorno = None

def baixar(t, p):
    df_ticket = yf.download(t, period=p)
    return df_ticket

col1= st.columns(1)
col2, col3= st.columns(2)

# Verifique se um ticker foi fornecido
if ticker1:
    # Baixe os dados do ticker
    df_ticket = baixar(ticker1, genre)

    # Verifique se o DataFrame não está vazio
    if not df_ticket.empty:
        # Renomeie as colunas do DataFrame
        df_ticket = df_ticket.rename(columns={'Adj Close': 'y'}).reset_index()
        df_ticket = df_ticket.rename(columns={'Date': 'ds'})

        # Crie um DataFrame com os dados do ticker
        df = df_ticket[["ds", "y", "Volume", "Open", "Close"]]

        # Verifique se um segundo ticker foi fornecido
        if ticker2:
            # Baixe os dados do segundo ticker
            df_ticket2 = baixar(ticker2, genre)
            # Verifique se o DataFrame do segundo ticker não está vazio
            if not df_ticket2.empty:
                # Renomeie as colunas do DataFrame do segundo ticker
                df_ticket2 = df_ticket2.rename(columns={'Adj Close': 'y2'}).reset_index()
                df_ticket2 = df_ticket2.rename(columns={'Date': 'ds'})

                # Crie um DataFrame com os dados do segundo ticker
                df2 = df_ticket2[["ds", "y2"]]

                # Mescle os dados dos dois ativos
                df = pd.merge(df, df2, on='ds', how='outer')

        # Crie o gráfico com os dados dos dois ativos, se existirem
        if 'y2' in df.columns:
            fig_lin = px.line(df, x="ds", y=["y", "y2"], title=ticker1.upper()+ " | " +ticker2.upper())
        else:
            fig_lin = px.line(df, x="ds", y="y", title=ticker1.upper())
    else:
        # Exiba uma mensagem de aviso se o DataFrame estiver vazio
        st.warning(f"Nenhum dado disponível para o ticker {ticker1} no período selecionado.")

    # Exiba o gráfico
    col1[0].plotly_chart(fig_lin, use_container_width=True)

    fig_bar = px.bar(df, x="ds", y="Volume", title="Volume de Negociação " + ticker1.upper())
    col2.plotly_chart(fig_bar, use_container_width=True)

if ticker1:
    # Defina o período selecionado
    data_inicio = df_ticket['ds'].min()
    data_fim = df_ticket['ds'].max()

    # Obtenha os dados do ativo
    df_ticket = df_ticket.loc[df_ticket['ds'].between(data_inicio, data_fim)]

    # Calcule o preço inicial e o preço final
    preco_inicial = df_ticket['Open'].iloc[0]
    preco_final = df_ticket['Close'].iloc[-1]

    # Calcule o retorno do ativo
    retorno = preco_final - preco_inicial
    df = pd.DataFrame({'Metrica': ['Preço Inicial', 'Preço Final', 'Retorno'], 'Valor': [preco_inicial, preco_final, retorno]})

    # Apresente os resultados
    fig_bar1 = px.bar(df, x="Metrica", y="Valor", title="Retorno de acordo com o período ")
    fig_bar1.add_annotation(x='Preço Inicial', y=preco_inicial, text=f"$ {preco_inicial:.2f}")
    fig_bar1.add_annotation(x='Preço Final', y=preco_final, text=f"$ {preco_final:.2f}")
    fig_bar1.add_annotation(x='Retorno', y=retorno, text=f"$ {retorno:.2f}")

    col3.plotly_chart(fig_bar1, use_container_width=True)


N, M, V = map(int, input().split())

graph = [[False]*(N+1) for _ in range(N+1)]
visited = [False]*(N+1)

def dfs(idx):
    visited[idx] = True
    print(idx, end=' ')

    for i in range(1,N+1):
        if visited[i]==False and graph[idx][i]:
            dfs(i)

def bfs(V):
    q= [V]
    visited[V] = True

    while q:
        idx = q.pop(0)
        print(idx, end=' ')

        for i in range(1,N+1):
            if visited[i] == False and graph[idx][i]:
                q.append(i)
                visited[i] = True

for _ in range(M):
    x,y = map(int, input().split())
    graph[x][y] = graph[y][x] = True

dfs(V)
print()

visited = [False]*(N+1)
bfs(V)


#!/usr/bin/env python
import sys, json, requests
from datetime import datetime

#district 04012 = Bremerhaven
url = "https://api.corona-zahlen.org/districts/04012"
r = requests.get(url)
data = r.json()

date1=data1['meta']['lastUpdate']
cases1=data1['data']['04012']['cases']
deaths1=data1['data']['04012']['deaths']
casesPerWeek1=data1['data']['04012']['casesPerWeek']
deathsPerWeek1=data1['data']['04012']['deathsPerWeek']
recovered1=data1['data']['04012']['recovered']
weekIncidence1=data1['data']['04012']['weekIncidence']
casesPer100k1=data1['data']['04012']['casesPer100k']
deltacases1=data1['data']['04012']['delta']['cases']
deltadeaths1=data1['data']['04012']['delta']['deaths']
deltarecovered1=data1['data']['04012']['delta']['recovered']

def telegram_bot_sendtext(bot_message):
   bot_token = 'INSERT_YOUR_BOT_TOKEN_HERE'
   bot_chatID = 'INSERT_YOUR_CHAT_ID_HERE'
   send_text = 'https://api.telegram.org/bot' + bot_token + '/sendMessage?chat_id=' + bot_chatID + '&parse_mode=Markdown&text=' + bot_message
   response = requests.get(send_text)
   return response.json()

text = telegram_bot_sendtext("BREMERHAVEN" + str(datetime.now()) + "\n\nweek incidence: " + str(weekIncidence1) + "\n\ncases: " + str(cases1) + "\ndeaths: " + str(deaths1) + "\n\ncases per week: " + str(casesPerWeek1) + "\ndeaths per week: " + str(deathsPerWeek1) + "\nrecovered: " + str(recovered1) + "\ncases per 100k: " + str(casesPer100k1) + "\n\ndelta cases: " + str(deltacases1) + "\ndelta deaths: " + str(deltadeaths1) + "\ndelta recovered: " + str(deltarecovered1) + "\n\ndata from: " + date1 + "\n\n powered by: https://fachinformatiker.app")


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

# In[1]:

import pandas as pd

# In[2]:

p = pd.date_range(start ='2020-05-01', periods=7)
print(p)

# ###https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html#offset-aliases
# Frequency 옵션들

# In[4]:

p = pd.date_range(start='2020-01-01', periods = 4, freq='2D') # D == Day
print(p)

# In[6]:

p = pd.date_range(start='2021-04-01', periods=5, freq='W') # W == Week
print(p)

# In[7]:

p = pd.date_range(start='2021-02-01', periods=12, freq='2BM') #BM == Business Month, 주의 마지막 평일까지
print(p)

# In[9]:

p = pd.date_range(start='2021-01-03', periods=5, freq='QS') # QS == 분기의 시작일
print(p)

# In[10]:

p = pd.date_range(start='2021-01-01', periods=3, freq='AS') # AS == 매 년의 시작일
print(p)

# In[12]:

p = pd.date_range(start='2021-01-01 08:00', periods=10, freq='H') # H == hour, 시간단위로 period 만큼
print(p)

# In[13]:

p = pd.date_range(start='2021-01-01 08:00', periods=10, freq='BH') # BH == Business hour
print(p)

# In[17]:

print(pd.offsets.BusinessHour())

# In[19]:

import datetime

bh = pd.offsets.BusinessHour(start='09:00', end=datetime.time(18,0)) # 임의로 BH의 Range 를 정의해서 사용할 수 있다.
p2 = pd.date_range(start='2021-01-01 08:00', periods=10, freq='BH') +bh
print(p2)

# In[20]:

import warnings
warnings.simplefilter(action='ignore', category=pd.errors.PerformanceWarning) # 위의 performanceWarning 잡아주는것

# In[25]:

p = pd.date_range(start='2021-01-01 10:00', periods=4, freq='30min')
print(p)

# In[28]:

index_date = pd.date_range(start='2021-04-01', periods=5, freq='D')
p= pd.Series([51, 63, 59, 48, 60], index = index_date) # 날짜에 인덱스를 지정해줌
print(p)

# ## DataFrame

# df = pd.DataFrame(data, [,index=index_data, columns = columns_data])
# data : 리스트, 딕셔너리, Numpy배열, Series, DataFrame
# DataFrame의 세로축은 index, 가로축은 columns 라함
# index 와 columns 를 제외한 영역은 values 라함
# index와 columns의 기본값은 숫자 0 부터 입력

# In[30]:

df = pd.DataFrame([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(df)

# In[31]:

import numpy as np

# In[32]:

data_list = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) # 위의 DataFrame 을 Numpy 배열로 만든것
df = pd.DataFrame(data_list)
print(df)

# In[34]:

data = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]])
index_date = pd.date_range('2020-05-01', periods=4)
columns_list = ['A', 'B', 'C']
df = pd.DataFrame(data, index = index_date, columns = columns_list)
print(df)

# In[36]:

# DataFrame 을 딕셔너리로 생성하면 key 가 columns 가 된다.
data = {'연도': [2015, 2016, 2016, 2017, 2018], '지사': ['서울','서울','부산','서울','부산'],
       '고객 수 ': [200, 250, 150, 300, 200]} #
df = pd.DataFrame(data)
print(df)

# In[39]:

data = {'연도': [2015, 2016, 2016, 2017, 2018], '지사': ['서울','서울','부산','서울','부산'],
       '고객 수': [200, 250, 150, 300, 200]}
df = pd.DataFrame(data, columns=['지사', '연도', '고객 수']) # 데이터를 건드리는것은 좋지않으므로 컬럼의 이름을줘서 추출
print(df)

# In[42]:

s1 = pd.Series([1, 2, 3, 4, 5])
s2 = pd.Series([10, 20, 30, 40, 50])

print(s1+s2)
print(s1-s2)
print(s1/s2)
print(s1*s2)

# In[43]:

s3 = pd.Series([1,2,3,4])
s4 = pd.Series([10, 20 ,30, 40, 50])
print(s3+s4)

# In[44]:

data1 = {'A': [1, 2, 3, 4, 5],
         'B': [10, 20, 30, 40, 50],
         'C': [100, 200, 300, 400, 500]}
df1 = pd.DataFrame(data1)
print(df1)

data2 = {'A': [6, 7, 8],
         'B': [60, 70, 80],
         'C': [600, 700, 800]}
df2 = pd.DataFrame(data2)
print(df2)

# In[45]:

print(df1 + df2)

# In[51]:

table_data3 = {'봄': [256.5, 264.3, 215.9, 223.2, 312.8],
             '여름': [770.6, 567.5, 599.8, 387.1, 446.2],
             '가을': [363.5, 231.2, 293.1, 247.7, 381.6],
             '겨울': [139.3, 59.9, 76.9, 109.1, 108.1]}
columns_list = ['봄', '여름', '가을', '겨울']
index_list = ['2012', '2013', '2014', '2015', '2016']

# In[52]:

df3 = pd.DataFrame(table_data3, columns = columns_list, index=index_list)
print(df3)

# In[53]:

print(df3.mean()) # 계절별 평균 --> columns
print('=' * 30)
print(df3.std()) # 계절별 표준편차

# In[55]:

print(df3.mean(axis=1)) # 연도별 --> index
print('=' * 30)
print(df3.std(axis=1))

# In[56]:

print(df3.describe()) # 전체를 다 표현해줌

# ## data slicing
#

# In[57]:

KTX_data = {'경부선 KTX': [39060, 39896, 42005, 43621, 41702, 41266, 32427],
           '호남선 KTX': [7313, 6967, 6873, 6626, 8675, 10622, 9228],
           '경전선 KTX': [3627, 4168, 4088, 4424, 4606, 4984, 5570],
           '전라선 KTX': [309, 1771, 1954, 2244, 3146, 3945, 5766],
           '동해선 KTX': [np.nan,np.nan, np.nan, np.nan, 2395, 3786, 6667]}
columns_list = ['경부선 KTX', '호남선 KTX', '경전선 KTX', '전라선 KTX', '동해선 KTX']
index_list = ['2011', '2012', '2013', '2014', '2015', '2016', '2017']

# In[58]:

df_KTX = pd.DataFrame(KTX_data, columns = columns_list, index = index_list)
print(df_KTX)

# ## 전체 데이터 중 처음이나 끝 일부분 선택
#
#   - head([n])
#   - tail([n])
#   - n 을 지정하지 않으면 기본값 5

# In[62]:

print(df_KTX.head())
print('='*30)
print(df_KTX.head(3))

# In[63]:

#slicing
print(df_KTX[2:5])

# In[64]:

# 인덱스 지정(행 선택)
print(df_KTX.loc['2011'])

# In[66]:

print(df_KTX.loc['2013':'2016'])

# In[67]:

print(df_KTX['경부선 KTX'][1:4]) #.loc 안쓰고 컬럼 추출

# In[68]:

print(df_KTX.loc['2016']['호남선 KTX'])
print('='*30)
print(df_KTX.loc['2016', '호남선 KTX'])
print('='*30)
print(df_KTX['호남선 KTX']['2016'])
print('='*30)
print(df_KTX['호남선 KTX'][5])
print('='*30)
print(df_KTX['호남선 KTX'].loc['2016'])
print('='*30)

# In[69]:

print(df_KTX.T) # 데이터 프레임을 행렬로 인식해서 만들어줌 (행과, 열을 바꿔줌)

# In[71]:

print(df_KTX[['동해선 KTX', '전라선  KTX', '경전선 KTX', '호남선  KTX', '경부선  KTX']])

# In[72]:

## 데이터 프레임 통합

# In[73]:

df1 = pd.DataFrame({'Class1': [95, 92 ,98, 100],
                    'Class2': [91,93,97,99]})
print(df1)

# In[74]:

df2 = pd.DataFrame({'Class1': [87, 89],
                    'Class2': [85, 90]})

# In[75]:

print(df1.append(df2)) # 같은 key 끼리 묶는거 append

# In[76]:

print(df1.append(df2, ignore_index=True)) # append로 합쳤을떄의 인덱스를 순서로 조정

# In[77]:

df3 = pd.DataFrame({'Class1': [96, 83]})

# In[78]:

print(df2.append(df3, ignore_index=True))

# In[79]:

df4 = pd.DataFrame({'Class3': [93, 91, 96, 98]})

# In[80]:

print(df1.join(df4)) # 옆으로 붙이는거 조인 (같은 index기준)

# In[81]:

index_label = ['a', 'b','c','d']
df1a = pd.DataFrame({'Class1': [95, 92, 98, 100],
                    'Class2': [91,93,95,99]}, index=index_label)
df4a = pd.DataFrame({'Class3': [92, 93, 94, 95]}, index=index_label)

print(df1a.join(df4a))

# In[82]:

df5 = pd.DataFrame({'Class4': [82, 92]})
print(df1.join(df5))

# In[83]:

df_A_B = pd.DataFrame({'판매월': ['1월', '2월', '3월', '4월'],
                      '제품A': [100, 150, 200, 130],
                      '제품B': [90, 110, 140, 170]})

df_C_D = pd.DataFrame({'판매월': ['1월', '2월', '3월', '4월'],
                      '제품C': [112, 141, 203, 134],
                      '제품D': [90, 110, 140, 170]})

# In[84]:

# 판매 월 이라는 동일한 컬럼이 겹쳐서 에러가남
print(df_A_B.join(df_C_D))

# In[87]:

#동일한 컬럼으로 조인 시킴
print(df_A_B.merge(df_C_D))
#append와의 차이
print(df_A_B.append(df_C_D))

# In[88]:

df_left = pd.DataFrame({'key': ['A', 'B','C'], 'left':[1, 2, 3]})
df_right = pd.DataFrame({'key': ['A','B','D'], 'right':[4, 5, 6]})
print(df_left, df_right)

# In[89]:

print(df_left.merge(df_right, how='left', on='key')) #기준을 잡아서 머지하는 것

# In[90]:

print(df_left.merge(df_right, how='outer', on='key')) # 양쪽 다

# In[91]:

print(df_left.merge(df_right, how='inner', on='key')) # 겹치는 부분만

# In[99]:

df = pd.read_csv('/Users/user/java-web-project0208/python-basic/data/sea_rain1.csv')

# In[96]:

print(df)

# In[100]:

df_WH = pd.DataFrame({'Weight': [62, 67, 55, 74],
                      'Height':[165, 177,160,180]},
                    index=['ID_1', 'ID_2', 'ID_3', 'ID_4' ])
df_WH.index.name = 'User'
print(df_WH)

# In[101]:

bmi = df_WH['Weight']/(df_WH['Height']/100) **2
print(bmi)

# In[102]:

df_WH['BMI'] = bmi
print(df_WH)

# In[103]:

df_WH.to_csv('/Users/user/java-web-project0208/python-basic/data/save_DataFrame.csv')

# In[104]:

import matplotlib.pyplot as plt

# In[105]:

data1 = [10, 14, 19, 20, 25]
plt.plot(data1)
plt.show()

# In[108]:

# 별도의 창으로 띄워줌
# %matplotlib auto

#jupyter 에서 쓸때
get_ipython().run_line_magic('matplotlib', 'inline')

# In[109]:

data1 = [10, 14, 19, 20, 25]
plt.plot(data1)
plt.show()

# In[112]:

x = np.arange(-4.5, 5, 0.5) # 범위 -4.5~ 5 0.5씩증가
y= 2*x**2
plt.plot(x, y)
plt.show()

# In[113]:

x = np.arange(-4.5, 5, 0.5)
y1 = 2*x**2
y2 = 5*x +30
y3 = 4*x**2 +10

# In[115]:

plt.plot(x, y1)
plt.plot(x, y2)
plt.plot(x, y3)
plt.show()

# In[116]:

plt.plot(x, y1, x, y2, x, y3)
plt.show()

# In[118]:

x = np.arange(-5, 5, 0.1)
y1 = x **2 -2
y2 = 20*np.cos(x) **2

plt.figure(1) # 1번 그래프 창을 생성합
plt.plot(x, y1) # 지정된 그래프 창에 그래프를 그림

plt.figure(2) # 2번 그래프 창을 생성합
plt.plot(x, y2)# 지정된 그래프 창에 그래프를 그림

plt.figure(1) # 이미 생성된 1번 그래프 창을 지정함
plt.plot(x, y2) # 지정된 그래프 창에 그래프를 그림

plt.figure(2) # 이미 생성된 2번 그래프창을 지정합
plt.clf() # 2번 그래프 창에 그려진 모든 그래프를 지움
plt.plot(x, y1) # 지정된 그래프 창에 그래프를 그림

plt.show()

# # 그래프 영역 나누기
#   - plt.subplot(m,n,p)
#   - m X n 행렬의 그래프 영역 중 p 번쨰 위치
#   - p는 왼쪽 -> 오른쪽 ,위 -> 아래
#

# In[119]:

x = np.arange(0, 10, 0.1)
y1 = 0.3*(x-5) **2 +1
y2 = -1.5*x +3
y3 = np.sin(x)**2 # Numpy에서 sin()은 np.sin()
y4 = 10*np.exp(-x) +1 # exp() 는 np.exp() 지수함수

# In[120]:

# 2 x 2 행렬로 이루어진 하위 그래프에서 p 에따라 위치를 지정

plt.subplot(2,2,1)  # p는 1
plt.plot(x,y1)

plt.subplot(2,2,2)  # p는 2
plt.plot(x,y2)

plt.subplot(2,2,3)  # p는 3
plt.plot(x,y3)

plt.subplot(2,2,4)  # p는 4
plt.plot(x,y4)

plt.show()

# In[121]:

x = np.linspace(-4, 4, 100) # [-4, 4] 범위에서 100개의 값 생성
y1 = x**3
y2 = 10*x**2 - 2

plt.plot(x, y1, x, y2)
plt.show()

# In[123]:

# 겹치는 부분의 데이터를 잘 확인할 수 있게해줌

plt.plot(x, y1, x, y2)
#x, y에 limit을 줘서 그부분만 확대 할수 있음
plt.xlim(-1, 1)
plt.ylim(-3, 3)
plt.show()

# ## 포맷 문자열 '[color][line_style][marker]'

# In[129]:

x = np.arange(0, 5, 1)
y1 = x
y2 = x + 1
y3 = x + 2
y4 = x + 3

plt.plot(x, y1, x, y2, x, y3, x, y4)
plt.show()

# In[130]:

plt.plot(x, y1, '>--r', x, y2, 's-g', x, y3, 'd:b', x, y4,'-.Xc')
plt.show()

# In[127]:

plt.plot(x,y1)
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.title('Graph title')
plt.grid()
plt.show()

# In[128]:

x = np.arange(0, 5, 1)
y1 = x
y2 = x + 1
y3 = x + 2
y4 = x + 3

# In[132]:

# 그래프의 이름 표시
plt.plot(x, y1, '>--r', x, y2, 's-g', x, y3, 'd:b', x, y4,'-.Xc')
plt.legend(['data1', 'data2', 'data3', 'data4'], loc = 'lower right') #loc 로 위치 조정가능
plt.show()

# In[136]:

plt.plot(x, y1, '>--r', x, y2, 's-g', x, y3, 'd:b', x, y4,'-.Xc')
plt.legend(['data1', 'data2', 'data3', 'data4'], loc=4)
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.title('Graph title')
plt.grid(True)
plt.show()

# In[142]:

plt.plot(x, y1, '>--r', x, y2, 's-g', x, y3, 'd:b', x, y4,'-.Xc')
plt.legend(['데이터1', '데이터2', '데이터3', '데이터4'], loc=4)
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.title('Graph title')
plt.grid(True)
plt.show()

# In[140]:

from matplotlib import rc # 한글출력할 수 있게 하는 임포트

# In[141]:

rc('font', family='AppleGothic')

# In[143]:

import platform
from matplotlib import font_manager, rc # 운영체제에 따라 구분
path = "c:/Windows/Fonts/malgun.ttf"
if platform.system() == 'Darwin':
    rc('font', family='AppleGothic')
elif platform.system() == 'Windows':
    font_name = font_manager.FontProperties(fname=path).get_name()
    rc('font', family = font_name)
else:
    print("Unknown system ..")

# In[147]:

plt.plot(x, y1, '>--r', x, y2, 's-g', x, y3, 'd:b', x, y4,'-.Xc')

# x, y 좌표를 지정해 그 위치에 문자열 출력 가능

plt.text(0, 6, "문자열 출력 1")
plt.text(0, 5, "문자열 출력 2")
plt.text(3, 1, "문자열 출력 3")
plt.text(3, 0, "문자열 출력 4")

plt.show()

# In[148]:

height = [165, 177, 160, 178, 185, 155, 172]
weight = [62, 67, 55, 74, 90, 43, 64]

# In[149]:

#scatter 그래프 그리기 => 지정위치에 점을 표현
plt.scatter(height, weight)
plt.xlabel('Height(m)')
plt.ylabel('weight(kg)')
plt.title('Height & Weight')
plt.grid(True)
plt.show()

# In[151]:

# 마커의 큭기와 색깔 설정
plt.scatter(height, weight, s=50, c='r')
plt.xlabel('Height(m)')
plt.ylabel('weight(kg)')
plt.title('Height & Weight')
plt.grid(True)
plt.show()

# In[152]:

#사이즈와 색을 변수에 담아 각자 다르게 출력하기

size = 100 * np.arange(1,8)
colors = ['r', 'g', 'b', 'c', 'm', 'k', 'y']
plt.scatter(height, weight, s=size, c=colors)
plt.xlabel('Height(m)')
plt.ylabel('weight(kg)')
plt.title('Height & Weight')
plt.grid(True)
plt.show()

# In[153]:

city = ['서울', '인천', '대전', '대구', '울산', '부산', '광주']
# 위도(latitude)와 경도(longitude)
lat = [37.56, 37.45, 36.35, 35.87, 35.53, 35.18, 35.16]
lon = [126.97, 126.70, 127.38, 128.60, 129.31, 129.07, 126.85]

# 인구 밀도(명/km^2): 2017년 통계청 자료
pop_den = [16154, 2751, 2839, 2790, 1099, 4454, 2995]

# In[154]:

size = np.array(pop_den) * 0.2
colors = ['r', 'g', 'b', 'c', 'm', 'k', 'y']

# In[155]:

plt.scatter(lon, lat, s= size, c=colors, alpha =0.5)
plt.xlabel('경도(longitude)')
plt.ylabel('밀도(latitude)')
plt.title('지역별 인구 밀도 (2017)')

for x, y, name in zip(lon, lat, city):
    plt.text(x, y, name) # 위도와 경도에 맞는 도시이름 출력

plt.show()

# In[158]:

#휘트니스 클럽 회원 4명의 운동 시작 전, 시작 한 달 후 윗몸 일으키키 횟수

member_IDs = ['m_01', 'm_02', 'm_03', 'm_04'] # 회원 ID
before_ex = [27, 35, 40, 33] # 운동 시작 전
after_ex = [30, 38, 42, 37] # 운동 한 달 후

# In[159]:

# 막대 그래프로 표시

n_data = len(member_IDs)  # 회원이 네명이르모 데이터 수는 4
index = np.arange(n_data) # numpy를 이용해 배열 생성 [0,1,2,3]
plt.bar(index, before_ex) # bar(x, y)에서 x=index, height=before_ex로 지정
plt.show()

# In[160]:

n_data = len(member_IDs)
index = np.arange(n_data)
plt.bar(index, before_ex, tick_label= member_IDs) # x축의 해당 멤버이름울 설정
plt.show()

# In[161]:

n_data = len(member_IDs)
index = np.arange(n_data)
colors = ['r','g','b','y']
plt.bar(index, before_ex, tick_label = member_IDs, color = colors)
plt.show()

# In[162]:

n_data = len(member_IDs)
index = np.arange(n_data)
colors = ['r','g','b','y']
plt.bar(index, before_ex, tick_label = member_IDs, color = colors, width =0.6)
plt.show()

# In[163]:

n_data = len(member_IDs)
index = np.arange(n_data)
colors = ['r','g','b','y']
plt.barh(index, before_ex, tick_label = member_IDs, color = colors) #bar horizontal 가로로
plt.show()

# In[165]:

n_data = len(member_IDs)
index = np.arange(n_data)
colors = ['r','g','b','y']
barWidth = 0.4
plt.bar(index, before_ex, color='c', align='edge', width= barWidth, label='before')
plt.bar(index+barWidth, after_ex, color='m', align='edge', width= barWidth, label='after')

plt.xticks(index+barWidth, member_IDs)
plt.legend()
plt.xlabel('회원 아이디')
plt.ylabel('윗몸일으키기 횟수')
plt.title('운동시작 전과 후의 근지구력 변화 비교')

plt.show()

# ## 히스토그램
#
# - plt.hist(x[,bins=bins_n 또는 'auto])
# - x 는 변량
# - bins 는 계급의 개수, 입력하지 않으면 기본값 10 (x축)
# - 'auto' 가 입력되면 x 에맞게 자동으로 할당

# In[169]:

math = [76, 82, 84, 83, 90, 86, 85, 92, 72, 71, 100, 87, 81, 76, 94, 78, 81, 60, 79, 69, 74, 87, 82, 68, 79]
plt.hist(math)
plt.show()

# In[170]:

plt.hist(math, bins =8)
plt.show()

# In[171]:

plt.hist(math, bins=8)
plt.xlabel('시험점수')
plt.ylabel('도수(frequency)')
plt.title('수학시험의 히스토그램')
plt.grid()
plt.show()

# In[175]:

# 학생 20명의 선호과일
# 3시를 기준으로 반시계방향으로 진행
fruit = ['사과','바나나','딸기','오렌지','포도']
result = [7, 6, 3, 2, 2]
plt.pie(result)
plt.title('학생 20명의 선호과일')
plt.show()

# In[176]:

plt.pie(result, labels=fruit, autopct='%.1f%%')
plt.show()

# In[180]:

plt.pie(result, labels=fruit, autopct='%.1f%%', startangle=90, counterclock=False) #시작점을 12시에서 시계방향으로
plt.show()

# In[186]:

explode_value = (0.1, 0, 0, 0, 0) # 인덱스에맞는 수 만큼 분리
plt.pie(result, labels=fruit, autopct='%.1f%%', startangle=90, counterclock=False, explode=explode_value, shadow=True)
plt.show()

# In[187]:

print(matplotlib.rcParams['figure.figsize'])

# In[188]:

print(matplotlib.rcParams['figure.dpi'])

# In[189]:

explode_value = (0.1, 0, 0, 0, 0)
plt.pie(result, labels=fruit, autopct='%.1f%%', startangle=90, counterclock=False, explode=explode_value, shadow=True)
plt.title('Save figures')
plt.savefig('/Users/user/java-web-project0208/python-basic/data/saveFigTest', dpi = 100) # 저장하기
plt.show()

# In[190]:

#사이즈 조정
plt.figure(figsize=(6,5))
plt.pie(result, labels=fruit, autopct='%.1f%%', startangle=90, counterclock=False, explode=explode_value, shadow=True)
plt.title('Save figures')
plt.savefig('/Users/user/java-web-project0208/python-basic/data/saveFigTest', dpi = 200)
plt.show()

# In[191]:

# pandas 로 그래프 그리기 ==> matplotlib 를 지원한다.
s1 = pd.Series([1,2,3,4,5,6,7,8,9,10])
print(s1)

# In[192]:

s1.plot()
plt.show()

# In[199]:

s2 = pd.Series([1,2,3,4,5,6,7,8,9,10], index = pd.date_range('2021-01-01', periods=10))
s2.plot(grid=True)
plt.show()

# In[203]:

df_rain = pd.read_csv('/Users/user/java-web-project0208/python-basic/data/sea_rain1.csv', index_col="연도")
df_rain.plot()
plt.show()

# In[206]:

rain_plot = df_rain.plot(grid=True, style=['r--*', 'g-o', 'b:*', 'm-.p'])
rain_plot.set_xlabel('연도')
rain_plot.set_ylabel('강수량')
rain_plot.set_title('연간 강수량')
plt.show()

# In[207]:

#연도별 1인당 주거면적
year = [2006, 2008, 2010, 2012, 2014, 2016] # 연도
area = [26.2, 27.8, 28.5, 31.7, 33.5, 33.2] # 1인당 주거면적
table = {'연도':year, '주거면적':area}

# In[208]:

df_area = pd.DataFrame(table, columns=['연도', '주거면적'])
print(df_area)

# In[209]:

df_area.plot(x='연도', y='주거면적', grid=True, title='연도별 1인당 주거면적')
plt.show()

# In[ ]:


from slapos.recipe.librecipe import GenericBaseRecipe
import os

class Recipe(GenericBaseRecipe):
  """Deploy a fully operational cloud9 service."""

  def _options(self, options):
    self.ip = options['ip'].strip()
    self.port = options['port'].strip()
    self.git = options['git-binary'].strip()
    self.node_executable = options['node-binary'].strip()
    self.cloud9 = options['cloud9'].strip()
    self.workdir = options['working-directory'].strip()
    self.wrapper = options['wrapper'].strip()
    # Set cloud9 access URL
    options['access-url'] = 'http://[%s]:%s' % (self.ip, self.port)

  def install(self):
    environment = {
        'PATH': os.path.dirname(self.git) + ':' + os.environ['PATH'],
    }

    cloud9_args = [self.node_executable, self.cloud9, '-l', self.ip, '-p',
        self.port, '-w', self.workdir]

    return self.createWrapper(self.wrapper, cloud9_args, environment)


import random

def play_game():
    print("What's you choice? 'r' for Rock, 'p' for paper or 's' for scissors")
    feedback = input("Your choice: ")
    cpu_choice = random.randint(0, 2)

    choices = ['r', 'p', 's']
    cpu_choice = choices[cpu_choice]

    result(feedback, cpu_choice)

def result(feedback, cpu_choice):
    if feedback == cpu_choice:
        print("It's a draw!")
    elif feedback == 'r':
        if cpu_choice == 'p':
            you_won()
        else:
            you_lost()

    elif feedback == 'p':
        if cpu_choice == 'r':
            you_won()
        else:
            you_lost()

    elif feedback == 's':
        if cpu_choice == 'p':
            you_won()
        else:
            you_lost()

def you_won():
    print("You won!")

def you_lost():
    print("You lost!")

play_game()


import asyncio
import json
import logging
from typing import Iterable

from aiohttp import web
from sqlalchemy.orm.attributes import flag_modified

from aiohttp_translation import gettext_lazy as _
from block_ip.decorators import api_key
from bot.messages.base import BotMessage
from bot_viber import defines
from bot_viber.utils.viber_api import (
    get_or_create_user,
    get_viber_user,
    to_input_message,
    Update,
    ViberSender
)
from mogiminsk.services.user import UserService
from mogiminsk.settings import VIBER_API_KEY
from mogiminsk.utils import Session, set_db, get_db, lazy_string_aware_json_dumps
from messager.bot_server import BotServer

logger = logging.getLogger(__name__)

class ViberServer(BotServer):
    BOT_CONTEXT_VALUE = defines.VIBER_BOT

    @classmethod
    @api_key(VIBER_API_KEY)
    async def webhook(cls, request):
        return await super().webhook(request)

    @classmethod
    def get_bot_context(cls, user):
        return user.viber_context

    @classmethod
    def set_bot_context(cls, user, full_context: dict):
        user.viber_context = full_context

    @classmethod
    async def get_remote_update(cls, request):
        data = await request.read()
        logger.debug('Got viber update: %s', data)

        remote_update = json.loads(data)
        return Update.create(remote_update)

    @classmethod
    def get_input_message(cls, remote_update: Update):
        return to_input_message(remote_update)

    @classmethod
    def get_or_create_user(cls, remote_update):
        return get_or_create_user(get_viber_user(remote_update))

    @classmethod
    async def send_the_answer(cls,
                              request,
                              remote_update: Update,
                              bot_messages: Iterable[BotMessage]):
        if not bot_messages:
            return

        request['db'].commit()
        asyncio.ensure_future(
            cls._answer_callback(request.app['client'], remote_update.user, bot_messages)
        )

    @classmethod
    async def _answer_callback(cls, client, remote_user, bot_messages):
        sender = ViberSender(client)
        try:
            await sender.send_messages(remote_user, bot_messages)
        except:
            logger.exception('Got exception during sending message to Viber server. Messages:\n%s',
                             bot_messages)

            set_db(Session())
            try:
                user = UserService.get_by_viber_id(remote_user.id)
                messages = cls.handle_exception(user)
                get_db().commit()
                await sender.send_messages(remote_user, messages)
            except:
                logger.exception("Couldn't even reset the state.")

            finally:
                get_db().close()

    @classmethod
    def get_response(cls, update):
        return web.Response()

    @classmethod
    async def handle_system_message(cls, remote_update: Update):
        if remote_update.event == defines.EVENT_TYPE_CONVERSATION_STARTED:
            if not remote_update.subscribed:
                return web.json_response({
                    'text': _('This is a bot for booking Mogilev-Minsk minibusses.\n'
                              'Choose the date, time and book your trip!\n'
                              'Notice:\n\U0001f690 - bookable directly from bot.\n'
                              '\U0001f4de - you have to make a call to book your trip.\n'),
                    'type': 'text',
                    'min_api_version': 4,
                    "keyboard": {
                        "Type": "keyboard",
                        'InputFieldState': 'hidden',
                        "Buttons": [{
                                "ActionType": "open-url",
                                "ActionBody": "https://rate.pautuzin.by/static/viber_intro.gif?v=2",
                                "Text": _("Take a quick animated tour"),
                                'OpenURLMediaType': 'gif',
                             },
                        ],
                    },
                }, dumps=lazy_string_aware_json_dumps)

            logger.debug('User %s has started conversation again. Ignoring it.', remote_update.user.id)

        elif remote_update.event == defines.EVENT_TYPE_UNSUBSCRIBED:
            logger.info('User %s has unsubscribed.', remote_update.user.id)

        elif remote_update.event == defines.EVENT_TYPE_SUBSCRIBED:
            logger.info('User %s has subscribed.', remote_update.user.id)

        elif remote_update.event == defines.EVENT_TYPE_FAILED:
            logger.error('Failed to deliver message to the user %s. Error message is: %s.',
                         remote_update.user.id, remote_update.description)

        else:
            logger.error('Unexpected event: %s', remote_update.event)

        return web.Response()

    @classmethod
    def save_data(cls, state):
        super().save_data(state)
        state.user.viber_context = state.data
        flag_modified(state.user, 'viber_context')


class Node:
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None

def printAncestors(root, target):

    if root == None:
        return False
    if root.data == target:
        return True
    if (printAncestors(root.left, target) or
        printAncestors(root.right, target)):
        print (root.data)
        return True
    return False

root = Node(1)
root.left = Node(2)
root.right = Node(3)
root.left.left = Node(4)
root.left.right = Node(5)
root.left.left.left = Node(7)
printAncestors(root, 7)