问:
How to run multiprocessing with while loop?
Background:

I have 2 script , one for my robot (main_dobot.py ) , one for my GUI (tkinter_oop.py). MY robot script quite heavy which could freeze the GUI, so i try to use multiprocess. First few simple test work really ok. However, when I add while loop in serial_port_connecting() function the GUI is freeze.

What i want :

The reason I use while is to let the program run and checking for user input from GUI. For example, the program open with GUI and run at the background. The program keep check for connected command and if the user press connected , the program will find the port and connected to it . If connecting fail or not available , print message "not available".

Question:
Is there a way I could add the while loop to keep the program running without freeze it? I had try for loop , the freeze still appeared.

Extra question :

When I delete the while loop out  of  serial_port_connecting and test the result again , I notice the variable self.connected_complete in main_dobot.py could not pass to the button_connected_clicked function in tkinter_oop.py. Did this happen because the multiprocess not allow variable to directly pass from one class to another class ?

What I want ( for extra question):
I want the value of main_dobot.dobot_automation.connected_complete (tkinter_oop.py) or known as self.connected_complete (main_dobot.py)  variable could be use in the tkinter GUI , so the GUI could decide which text to shows on the interface.

Error display ( for extra question):
AttributeError: type object 'dobot_automation' has no attribute 'connected_complete'

tkinter_oop.py

```<code>import tkinter as tk
from tkinter import ttk
import multiprocessing
import main_dobot

class graphic(tk.Tk):
    def __init__(self):
        super().__init__()
        self.reset_clock = 0
        self.check_value = 0
        self.done = 0
        self.minute = 1
        self.second = 0

        #button value
        self.button_connecting_done  =  0
        self.button_home_cablirate_done = 0
        self.button_automation_cablirate_done = 0
        self.button_quit_done = 0
        self.emergency_stop_done = 0

        self.title('Automation Cleaning Process')
        self.geometry('1100x800+100+100')
        self.resizable(False, False)
        self.menubar = tk.Menu(self)
        filemenu = tk.Menu(self.menubar, tearoff=0)
        filemenu.add_command(label="New")
        filemenu.add_command(label="Open")
        filemenu.add_command(label="Save")
        filemenu.add_separator()
        filemenu.add_command(label="Exit", command=self.quit)
        self.menubar.add_cascade(label="File", menu=filemenu)

        helpmenu = tk.Menu(self.menubar, tearoff=0)
        helpmenu.add_command(label="Help Index")
        helpmenu.add_command(label="About...")
        self.menubar.add_cascade(label="Help",menu=helpmenu)

        #self.integer_variable_x_value = tk.IntVar()
        #self.integer_variable_y_value = tk.IntVar()
        #self.integer_variable_z_value = tk.IntVar()
        #self.integer_variable_r_value = tk.IntVar()
        #self.integer_variable_x_value.set(0)
        #self.integer_variable_y_value.set(0)
        #self.integer_variable_z_value.set(0)
        #self.integer_variable_r_value.set(0)

        self.tabControl = ttk.Notebook(self)
        self.tab_1 = ttk.Frame(self.tabControl)
        self.tab_2 = ttk.Frame(self.tabControl)
        self.tabControl.add(self.tab_2,text = 'HOME')
        self.tabControl.add(self.tab_1,text = 'Option')
        self.tabControl.pack(expand = 1, fill ="both")

        self.set_button()
        self.set_photo_gui()
        self.set_text_gui()

        self.set_timer_counter_process(self.minute,self.second)
        #self.update_output(200,300,400,500)
        self.config(menu=self.menubar)
        self.dobot_run ()

    def dobot_run (self):
       Dobot_run = multiprocessing.Process(target=main_dobot.dobot_automation, args=(self.button_connecting_done,self.button_home_cablirate_done,self.button_automation_cablirate_done,self.emergency_stop_done, self.button_quit_done))
       Dobot_run.start()
       Dobot_run.join()

    def set_button(self):
        self.button_home_cablirate = tk.Button (self.tab_1,text = "Home Cabliration", command = self.button_home_cablirate_clicked, width = 50 , height = 5 )
        self.button_home_cablirate.place(x=380,y=150)
        self.button_Automation_Process = tk.Button(self.tab_1, text='Automation Process',command=self.button_automation_clicked_clock_counting_down, width = 50 , height = 5)
        self.button_Automation_Process.place(x=380,y=300)
        self.button_Stop = tk.Button(self.tab_1, text='Stop',command=self.button_quit_clicked, width = 50 , height = 5 )
        self.button_Stop.place(x=380,y=450)
        self.button_connected = tk.Button (self.tab_2,text = "Connecting Dobot" , command=self.button_connected_clicked, width=50 , height =5 )
        self.button_connected.place(x=400,y=400)
        self.emergency_button = tk.Button(self, text='Emergency Stop ',command=self.button_emergency_stop, width = 25 , height = 8 )
        self.emergency_button.place(x= 900,y = 50)
        self.slot_1 =  tk.Button(self.tab_2, text='2',command=self.two_slot_selected, width = 20 , height = 4)
        self.slot_1.place(x= 100 ,y = 250 )
        self.slot_2 =  tk.Button(self.tab_2, text='4',command=self.four_slot_selected, width = 20 , height = 4)
        self.slot_2.place(x= 500,y = 250)
        self.slot_3 =  tk.Button(self.tab_2, text='6',command=self.sixth_slot_selected, width = 20 , height = 4)
        self.slot_3.place(x= 850 ,y = 250)

    def update_button_value(self):
       self.button_connecting_done = main_dobot.dobot_automation.connected_command
       self.after(100)

    def button_connected_clicked(self):
        self.button_connecting_done  = 1
        self.connecting = tk.Label(self.tab_2,text = "N/A", font=("Inter", 25))
        self.connecting.place(x = 500  , y = 350)
        if  main_dobot.dobot_automation.connected_complete ==  1 :
            self.connecting.config("Connected")
        elif main_dobot.dobot_automation.connected_complete == 2 :
            self.connecting.config("Not Connected")

    def button_home_cablirate_clicked(self):
      print ("button home cablirate click ")
      self.button_home_cablirate_done  = 1

    def button_automation_clicked_clock_counting_down(self):
     self.done = 1
     self.button_automation_cablirate_done = 1
     print ("button automation click ")

    def button_quit_clicked(self):
     self.button_quit_done = 1
     print ("button quit click")

    def button_emergency_stop (self):
        self.emergency_stop_done  = 1
        print ("button emergency clicked")

    def two_slot_selected ():
        pass

    def four_slot_selected ():
        pass

    def sixth_slot_selected () :
        pass

    def set_text_gui(self):
        #declare label
        self.choose_clean_slot = tk.Label(self.tab_2,text = "Please choose how many slot avaliable ", font=("Inter", 20))

        self.time_title = tk.Label(self.tab_2, text = "Time Process:", font=("Inter",30))
        self.time_colon= tk.Label(self.tab_2, text = ":", font=("Inter",  30))
        self.min_label= tk.Label(self.tab_2, text = "min", font=("Inter", 30))
        self.second_label=tk.Label(self.tab_2, text = "sec", font=("Inter",30))
        self.label_minute = tk.Label(self.tab_2,font=("Inter",30))
        self.label_second = tk.Label (self.tab_2,font=("Inter",30))
        self.label_minute_zero_add = tk.Label(self.tab_2,font=("Inter",30))
        self.label_second_zero_add = tk.Label(self.tab_2,font=("Inter",30))
        # position label

        self.choose_clean_slot.place(x = 85  , y = 100)

        self.time_title.place(x=85,y=590)
        self.time_colon.place(x =230,y=650)
        self.min_label.place(x=150,y=650)
        self.second_label.place(x=335,y=650)
        self.label_minute.place(x = 120 , y = 650)
        self.label_second.place(x=  278 , y = 650)
        self.label_minute_zero_add.place(x=  90 ,y=650)
        self.label_second_zero_add.place(x = 250 ,y= 650)

    #def update_output(self , input_dobot_x, input_dobot_y, input_dobot_z , input_dobot_r):
        # update x-axis
        #self.integer_variable_x_value.set(input_dobot_x)
        #self.x_axis_value.config(text=str(self.integer_variable_x_value.get()))
        # update y axis
        #self.integer_variable_y_value.set(input_dobot_y)
        #self.y_axis_value.config(text=str(self.integer_variable_y_value.get()))
        # update z axis
        #self.integer_variable_z_value.set(input_dobot_z)
        #self.z_axis_value.config(text=str(self.integer_variable_z_value.get()))

        # update r axis
        #self.integer_variable_r_value.set(input_dobot_r)
        #self.r_axis_value.config(text=str(self.integer_variable_r_value.get()))

        #update all the variable every 100secs to GUI
        #self.after(100,self.update)

    def set_timer_counter_process(self,minute,second):
        self.label_minute['text'] = minute
        self.label_second['text'] = second
        check_minute_length = len(str(minute))
        check_second_length = len(str(second))
        if check_minute_length == 1:
            self.label_minute_zero_add['text'] = 0
        else:
            self.label_minute_zero_add['text'] =''

        if check_second_length == 1:
            self.label_second_zero_add['text'] = 0
        else:
            self.label_second_zero_add['text'] =''

        if self.done == 1:
            if second  > 0 :
                second = second - 1
            elif second <= 0 :
                if minute > 0:
                    minute  = minute - 1
                    second  = 60
                else:
                    self.done = 0
        else:
            minute = 1
            second = 0
        self.after(1000, self.set_timer_counter_process, minute , second)

def run_GUI():

    User_graphic = graphic()
    User_graphic.mainloop()

if __name__ == '__main__':
    run_GUI()

</code>```

main_dobot.py :

```<code>from serial.tools import list_ports

import pydobot
from pydobot.enums import PTPMode
from pydobot.enums import jogMode

class dobot_automation :
    def __init__(self,connected_command,home_cablibrate_command,automation_command,emergency_stop_command, quit_command):
        self.connected_complete = 0
        self.check_loop_after_connected = 0
        self.usb_check_connection  = 2
        self.connected_command = connected_command
        try:
           self.serial_port_connecting ()
           while (self.check_loop_after_connected > 1):
                self.home_cabliration(home_cablibrate_command)
                self.cleaning_automation_process(automation_command)
                self.automation_emergency_stop(emergency_stop_command)
                self.quit_automation_program(quit_command)
        except:
            print ("There is error in the program , please stop the program immediately ")

    def serial_port_connecting(self):
        while self.usb_check_connection > 1:
            if self.connected_command == 1:
                self.available_ports = list_ports.comports()
                print(f'available ports: {[x.device for x in self.available_ports]}')
                self.port = self.available_ports[0].device
                if len(self.available_ports) == 0:
                    print('No port avaliable')
                    print ('Please Check Connection')
                    self.connected_complete = 2
                else:
                    self.device = pydobot.Dobot(port=self.port, verbose=True)
                    self.usb_check_connection = 0
                    self.check_loop_after_connected = 2
                    self.connected_command = 0
                    self.connected_complete = 1
                    break

    def home_cabliration(self,home_cablibration_command):
        if home_cablibration_command == 1:
            self.device._set_queued_cmd_clear()
            self.device.set_jog_command( 1, jogMode.BP_DOWN, wait=True)
            self.device.wait(100)
            self.device.set_jog_command( 1, jogMode.IDLE , wait=True)
            self.device.wait(1000)
            self.device.set_home_params(178.9299, 3.3897 , -33.8784 , -82.7707, False)
            self.device.set_home_command (1,False)
            self.device.wait(1000)
            home_cablibration_command = 0

    def cleaning_automation_process(self,automation_command):
        if automation_command == 1:
            self.device._set_queued_cmd_clear()

            #initial position
            self.intial_moving_pos()

            #set 1
            self.set_one_pos_up()
            self.open_grip()

            self.set_one__pos_down()
            #close grip
            self.close_grip()
            #move up
            self.set_one_pos_up()

            self.bath_one_pos_1_up()
            self.bath_one_pos_1_down()
            self.open_grip()
            self.bath_one_pos_1_up()
            self.close_grip()
            self.disable_grip()

            #back to intial pos
            self.intial_moving_pos()
            self.set_two_pos_up()
            self.open_grip()
            self.set_two_pos_down()
            #close grip
            self.close_grip()
            #move up
            self.set_two_pos_up()
            self.bath_one_pos_2_up()
            self.bath_one_pos_2_down()
            self.open_grip()
            self.bath_one_pos_2_up()
            self.close_grip()
            self.disable_grip()

            #back to intial pos
            self.intial_moving_pos()
            self.bath_one_pos_1_up()
            self.open_grip()
            self.bath_one_pos_1_down()
            self.close_grip()
            self.bath_one_pos_1_up()
            self.set_one_pos_up()
            self.set_one__pos_down()
            self.open_grip()
            self.set_one_pos_up()
            self.close_grip()

            self.intial_moving_pos()
            self.bath_one_pos_2_up()
            self.open_grip()
            self.bath_one_pos_2_down()
            self.close_grip()
            self.bath_one_pos_2_up()
            self.set_two_pos_up()
            self.set_two_pos_down()
            self.open_grip()
            self.set_one_pos_up()
            self.close_grip()
            (x, y, z, r, j1, j2, j3, j4) = self.device.pose()
            print(f'x:{x} y:{y} z:{z} r:{r} j1:{j1} j2:{j2} j3:{j3} j4:{j4}')
            automation_command = 0

    def quit_automation_program(self,quit_command) :
        if quit_command == 1 :
            self.usb_check_connection = 2
            self.device.close()
            self.connected_complete = 0
            quit_command = 0

    def automation_emergency_stop(self,emmergency_command_stop ):
        if emmergency_command_stop == 1:
            self.device._set_queued_cmd_stop_exec()
            emmergency_command_stop = 0

    def intial_moving_pos(self):
        self.device.move_to( 17.8941 , 6.0331 ,  0.5921 , -134.5598, PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)
    def set_one_pos_up(self):
        self.device.move_to( 62.9159 , 13.689 , -10.0889 , 124.8797 , PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)

    def set_one__pos_down(self):
        self.device.move_to( 62.8941 , 16.9492 , 28.2911 , 124.8797 , PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)
    def set_two_pos_up (self):
        self.device.move_to( 80.2371 , 6.9371 , -12.9820 , 99.4637 , PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)
    def set_two_pos_down(self):
        self.device.move_to( 80.2371 , 6.9371 , 26.238 , 99.4637 , PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)
    def set_three_pos(self):
        self.device.move_to( 50.82 , -3.56 , -9.18 , -134.5598, PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)
        #device.move_to( 52.29 , 31.8271 , 13.82 , -85.6, PTPMode.MOVJ_ANGLE, wait=True)
        #device.wait(1000)
    def open_grip(self):
        self.device.grip(False)
        self.device_setupdevice.wait(1000)
        self.device.suck(False)
        self.device.wait(1000)
    def close_grip(self):
        self.device.grip(True)
        self.device.wait(1000)
        self.device.suck(True)
        self.device.wait(1000)
    def disable_grip(self):
        self.device.suck(False)
        self.device.wait(1000)
    def bath_one_pos_1_up(self):
        self.device.move_to( 3.1442 , 36.3588 , -14.6246 ,-68.4760  , PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)
    def bath_one_pos_1_down(self):
        self.device.move_to( 3.1442 , 36.3588 , -14.6246 , 89.4437 , PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)
        self.device.move_to( 3.1442 , 36.3588 , 20.5754 , 89.4437 , PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)
    def bath_one_pos_2_up(self):
        self.device.move_to ( 22.6588 , 46.7398 , -8.1826 , 99.4637 , PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)
    def bath_one_pos_2_down(self):
        self.device.move_to ( 22.6588 , 46.7398 , -8.1826 , -102.1199 , PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)
        self.device.move_to ( 22.6588 , 46.7398 , 16.3267 , -102.1199 , PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)

</code>```

main_dobot.py ( for extra question):

```<code>
from serial.tools import list_ports

import pydobot
from pydobot.enums import PTPMode
from pydobot.enums import jogMode

class dobot_automation :
    def __init__(self,connected_command,home_cablibrate_command,automation_command,emergency_stop_command, quit_command):
        self.connected_complete = 0
        self.check_loop_after_connected = 0
        self.usb_check_connection  = 2
        self.connected_command = connected_command
        try:
           self.serial_port_connecting ()
           while (self.check_loop_after_connected > 1):
                self.home_cabliration(home_cablibrate_command)
                self.cleaning_automation_process(automation_command)
                self.automation_emergency_stop(emergency_stop_command)
                self.quit_automation_program(quit_command)
        except:
            print ("There is error in the program , please stop the program immediately ")

    def serial_port_connecting(self):

        if self.connected_command == 1:
            self.available_ports = list_ports.comports()
            print(f'available ports: {[x.device for x in self.available_ports]}')
            self.port = self.available_ports[0].device
            if len(self.available_ports) == 0:
                print('No port avaliable')
                print ('Please Check Connection')
                self.connected_complete = 2
            else:
                self.device = pydobot.Dobot(port=self.port, verbose=True)
                self.usb_check_connection = 0
                self.check_loop_after_connected = 2
                self.connected_command = 0
                self.connected_complete = 1

    def home_cabliration(self,home_cablibration_command):
        if home_cablibration_command == 1:
            self.device._set_queued_cmd_clear()
            self.device.set_jog_command( 1, jogMode.BP_DOWN, wait=True)
            self.device.wait(100)
            self.device.set_jog_command( 1, jogMode.IDLE , wait=True)
            self.device.wait(1000)
            self.device.set_home_params(178.9299, 3.3897 , -33.8784 , -82.7707, False)
            self.device.set_home_command (1,False)
            self.device.wait(1000)
            home_cablibration_command = 0

    def cleaning_automation_process(self,automation_command):
        if automation_command == 1:
            self.device._set_queued_cmd_clear()

            #initial position
            self.intial_moving_pos()

            #set 1
            self.set_one_pos_up()
            self.open_grip()

            self.set_one__pos_down()
            #close grip
            self.close_grip()
            #move up
            self.set_one_pos_up()

            self.bath_one_pos_1_up()
            self.bath_one_pos_1_down()
            self.open_grip()
            self.bath_one_pos_1_up()
            self.close_grip()
            self.disable_grip()

            #back to intial pos
            self.intial_moving_pos()
            self.set_two_pos_up()
            self.open_grip()
            self.set_two_pos_down()
            #close grip
            self.close_grip()
            #move up
            self.set_two_pos_up()
            self.bath_one_pos_2_up()
            self.bath_one_pos_2_down()
            self.open_grip()
            self.bath_one_pos_2_up()
            self.close_grip()
            self.disable_grip()

            #back to intial pos
            self.intial_moving_pos()
            self.bath_one_pos_1_up()
            self.open_grip()
            self.bath_one_pos_1_down()
            self.close_grip()
            self.bath_one_pos_1_up()
            self.set_one_pos_up()
            self.set_one__pos_down()
            self.open_grip()
            self.set_one_pos_up()
            self.close_grip()

            self.intial_moving_pos()
            self.bath_one_pos_2_up()
            self.open_grip()
            self.bath_one_pos_2_down()
            self.close_grip()
            self.bath_one_pos_2_up()
            self.set_two_pos_up()
            self.set_two_pos_down()
            self.open_grip()
            self.set_one_pos_up()
            self.close_grip()
            (x, y, z, r, j1, j2, j3, j4) = self.device.pose()
            print(f'x:{x} y:{y} z:{z} r:{r} j1:{j1} j2:{j2} j3:{j3} j4:{j4}')
            automation_command = 0

    def quit_automation_program(self,quit_command) :
        if quit_command == 1 :
            self.usb_check_connection = 2
            self.device.close()
            self.connected_complete = 0
            quit_command = 0

    def automation_emergency_stop(self,emmergency_command_stop ):
        if emmergency_command_stop == 1:
            self.device._set_queued_cmd_stop_exec()
            emmergency_command_stop = 0

    def intial_moving_pos(self):
        self.device.move_to( 17.8941 , 6.0331 ,  0.5921 , -134.5598, PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)
    def set_one_pos_up(self):
        self.device.move_to( 62.9159 , 13.689 , -10.0889 , 124.8797 , PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)

    def set_one__pos_down(self):
        self.device.move_to( 62.8941 , 16.9492 , 28.2911 , 124.8797 , PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)
    def set_two_pos_up (self):
        self.device.move_to( 80.2371 , 6.9371 , -12.9820 , 99.4637 , PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)
    def set_two_pos_down(self):
        self.device.move_to( 80.2371 , 6.9371 , 26.238 , 99.4637 , PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)
    def set_three_pos(self):
        self.device.move_to( 50.82 , -3.56 , -9.18 , -134.5598, PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)
        #device.move_to( 52.29 , 31.8271 , 13.82 , -85.6, PTPMode.MOVJ_ANGLE, wait=True)
        #device.wait(1000)
    def open_grip(self):
        self.device.grip(False)
        self.device_setupdevice.wait(1000)
        self.device.suck(False)
        self.device.wait(1000)
    def close_grip(self):
        self.device.grip(True)
        self.device.wait(1000)
        self.device.suck(True)
        self.device.wait(1000)
    def disable_grip(self):
        self.device.suck(False)
        self.device.wait(1000)
    def bath_one_pos_1_up(self):
        self.device.move_to( 3.1442 , 36.3588 , -14.6246 ,-68.4760  , PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)
    def bath_one_pos_1_down(self):
        self.device.move_to( 3.1442 , 36.3588 , -14.6246 , 89.4437 , PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)
        self.device.move_to( 3.1442 , 36.3588 , 20.5754 , 89.4437 , PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)
    def bath_one_pos_2_up(self):
        self.device.move_to ( 22.6588 , 46.7398 , -8.1826 , 99.4637 , PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)
    def bath_one_pos_2_down(self):
        self.device.move_to ( 22.6588 , 46.7398 , -8.1826 , -102.1199 , PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)
        self.device.move_to ( 22.6588 , 46.7398 , 16.3267 , -102.1199 , PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)

</code>```

Body:
Background:

I have 2 script , one for my robot (main_dobot.py ) , one for my GUI (tkinter_oop.py). MY robot script quite heavy which could freeze the GUI, so i try to use multiprocess. First few simple test work really ok. However, when I add while loop in serial_port_connecting() function the GUI is freeze.

What i want :

The reason I use while is to let the program run and checking for user input from GUI. For example, the program open with GUI and run at the background. The program keep check for connected command and if the user press connected , the program will find the port and connected to it . If connecting fail or not available , print message "not available".

Question:
Is there a way I could add the while loop to keep the program running without freeze it? I had try for loop , the freeze still appeared.

Extra question :

When I delete the while loop out  of  serial_port_connecting and test the result again , I notice the variable self.connected_complete in main_dobot.py could not pass to the button_connected_clicked function in tkinter_oop.py. Did this happen because the multiprocess not allow variable to directly pass from one class to another class ?

What I want ( for extra question):
I want the value of main_dobot.dobot_automation.connected_complete (tkinter_oop.py) or known as self.connected_complete (main_dobot.py)  variable could be use in the tkinter GUI , so the GUI could decide which text to shows on the interface.

Error display ( for extra question):
AttributeError: type object 'dobot_automation' has no attribute 'connected_complete'

tkinter_oop.py

import tkinter as tk
from tkinter import ttk
import multiprocessing
import main_dobot

class graphic(tk.Tk):
    def __init__(self):
        super().__init__()
        self.reset_clock = 0
        self.check_value = 0
        self.done = 0
        self.minute = 1
        self.second = 0

        #button value
        self.button_connecting_done  =  0
        self.button_home_cablirate_done = 0
        self.button_automation_cablirate_done = 0
        self.button_quit_done = 0
        self.emergency_stop_done = 0

        self.title('Automation Cleaning Process')
        self.geometry('1100x800+100+100')
        self.resizable(False, False)
        self.menubar = tk.Menu(self)
        filemenu = tk.Menu(self.menubar, tearoff=0)
        filemenu.add_command(label="New")
        filemenu.add_command(label="Open")
        filemenu.add_command(label="Save")
        filemenu.add_separator()
        filemenu.add_command(label="Exit", command=self.quit)
        self.menubar.add_cascade(label="File", menu=filemenu)

        helpmenu = tk.Menu(self.menubar, tearoff=0)
        helpmenu.add_command(label="Help Index")
        helpmenu.add_command(label="About...")
        self.menubar.add_cascade(label="Help",menu=helpmenu)

        #self.integer_variable_x_value = tk.IntVar()
        #self.integer_variable_y_value = tk.IntVar()
        #self.integer_variable_z_value = tk.IntVar()
        #self.integer_variable_r_value = tk.IntVar()
        #self.integer_variable_x_value.set(0)
        #self.integer_variable_y_value.set(0)
        #self.integer_variable_z_value.set(0)
        #self.integer_variable_r_value.set(0)

        self.tabControl = ttk.Notebook(self)
        self.tab_1 = ttk.Frame(self.tabControl)
        self.tab_2 = ttk.Frame(self.tabControl)
        self.tabControl.add(self.tab_2,text = 'HOME')
        self.tabControl.add(self.tab_1,text = 'Option')
        self.tabControl.pack(expand = 1, fill ="both")

        self.set_button()
        self.set_photo_gui()
        self.set_text_gui()

        self.set_timer_counter_process(self.minute,self.second)
        #self.update_output(200,300,400,500)
        self.config(menu=self.menubar)
        self.dobot_run ()

    def dobot_run (self):
       Dobot_run = multiprocessing.Process(target=main_dobot.dobot_automation, args=(self.button_connecting_done,self.button_home_cablirate_done,self.button_automation_cablirate_done,self.emergency_stop_done, self.button_quit_done))
       Dobot_run.start()
       Dobot_run.join()

    def set_button(self):
        self.button_home_cablirate = tk.Button (self.tab_1,text = "Home Cabliration", command = self.button_home_cablirate_clicked, width = 50 , height = 5 )
        self.button_home_cablirate.place(x=380,y=150)
        self.button_Automation_Process = tk.Button(self.tab_1, text='Automation Process',command=self.button_automation_clicked_clock_counting_down, width = 50 , height = 5)
        self.button_Automation_Process.place(x=380,y=300)
        self.button_Stop = tk.Button(self.tab_1, text='Stop',command=self.button_quit_clicked, width = 50 , height = 5 )
        self.button_Stop.place(x=380,y=450)
        self.button_connected = tk.Button (self.tab_2,text = "Connecting Dobot" , command=self.button_connected_clicked, width=50 , height =5 )
        self.button_connected.place(x=400,y=400)
        self.emergency_button = tk.Button(self, text='Emergency Stop ',command=self.button_emergency_stop, width = 25 , height = 8 )
        self.emergency_button.place(x= 900,y = 50)
        self.slot_1 =  tk.Button(self.tab_2, text='2',command=self.two_slot_selected, width = 20 , height = 4)
        self.slot_1.place(x= 100 ,y = 250 )
        self.slot_2 =  tk.Button(self.tab_2, text='4',command=self.four_slot_selected, width = 20 , height = 4)
        self.slot_2.place(x= 500,y = 250)
        self.slot_3 =  tk.Button(self.tab_2, text='6',command=self.sixth_slot_selected, width = 20 , height = 4)
        self.slot_3.place(x= 850 ,y = 250)

    def update_button_value(self):
       self.button_connecting_done = main_dobot.dobot_automation.connected_command
       self.after(100)

    def button_connected_clicked(self):
        self.button_connecting_done  = 1
        self.connecting = tk.Label(self.tab_2,text = "N/A", font=("Inter", 25))
        self.connecting.place(x = 500  , y = 350)
        if  main_dobot.dobot_automation.connected_complete ==  1 :
            self.connecting.config("Connected")
        elif main_dobot.dobot_automation.connected_complete == 2 :
            self.connecting.config("Not Connected")

    def button_home_cablirate_clicked(self):
      print ("button home cablirate click ")
      self.button_home_cablirate_done  = 1

    def button_automation_clicked_clock_counting_down(self):
     self.done = 1
     self.button_automation_cablirate_done = 1
     print ("button automation click ")

    def button_quit_clicked(self):
     self.button_quit_done = 1
     print ("button quit click")

    def button_emergency_stop (self):
        self.emergency_stop_done  = 1
        print ("button emergency clicked")

    def two_slot_selected ():
        pass

    def four_slot_selected ():
        pass

    def sixth_slot_selected () :
        pass

    def set_text_gui(self):
        #declare label
        self.choose_clean_slot = tk.Label(self.tab_2,text = "Please choose how many slot avaliable ", font=("Inter", 20))

        self.time_title = tk.Label(self.tab_2, text = "Time Process:", font=("Inter",30))
        self.time_colon= tk.Label(self.tab_2, text = ":", font=("Inter",  30))
        self.min_label= tk.Label(self.tab_2, text = "min", font=("Inter", 30))
        self.second_label=tk.Label(self.tab_2, text = "sec", font=("Inter",30))
        self.label_minute = tk.Label(self.tab_2,font=("Inter",30))
        self.label_second = tk.Label (self.tab_2,font=("Inter",30))
        self.label_minute_zero_add = tk.Label(self.tab_2,font=("Inter",30))
        self.label_second_zero_add = tk.Label(self.tab_2,font=("Inter",30))
        # position label

        self.choose_clean_slot.place(x = 85  , y = 100)

        self.time_title.place(x=85,y=590)
        self.time_colon.place(x =230,y=650)
        self.min_label.place(x=150,y=650)
        self.second_label.place(x=335,y=650)
        self.label_minute.place(x = 120 , y = 650)
        self.label_second.place(x=  278 , y = 650)
        self.label_minute_zero_add.place(x=  90 ,y=650)
        self.label_second_zero_add.place(x = 250 ,y= 650)

    #def update_output(self , input_dobot_x, input_dobot_y, input_dobot_z , input_dobot_r):
        # update x-axis
        #self.integer_variable_x_value.set(input_dobot_x)
        #self.x_axis_value.config(text=str(self.integer_variable_x_value.get()))
        # update y axis
        #self.integer_variable_y_value.set(input_dobot_y)
        #self.y_axis_value.config(text=str(self.integer_variable_y_value.get()))
        # update z axis
        #self.integer_variable_z_value.set(input_dobot_z)
        #self.z_axis_value.config(text=str(self.integer_variable_z_value.get()))

        # update r axis
        #self.integer_variable_r_value.set(input_dobot_r)
        #self.r_axis_value.config(text=str(self.integer_variable_r_value.get()))

        #update all the variable every 100secs to GUI
        #self.after(100,self.update)

    def set_timer_counter_process(self,minute,second):
        self.label_minute['text'] = minute
        self.label_second['text'] = second
        check_minute_length = len(str(minute))
        check_second_length = len(str(second))
        if check_minute_length == 1:
            self.label_minute_zero_add['text'] = 0
        else:
            self.label_minute_zero_add['text'] =''

        if check_second_length == 1:
            self.label_second_zero_add['text'] = 0
        else:
            self.label_second_zero_add['text'] =''

        if self.done == 1:
            if second  > 0 :
                second = second - 1
            elif second <= 0 :
                if minute > 0:
                    minute  = minute - 1
                    second  = 60
                else:
                    self.done = 0
        else:
            minute = 1
            second = 0
        self.after(1000, self.set_timer_counter_process, minute , second)

def run_GUI():

    User_graphic = graphic()
    User_graphic.mainloop()

if __name__ == '__main__':
    run_GUI()

main_dobot.py :

from serial.tools import list_ports

import pydobot
from pydobot.enums import PTPMode
from pydobot.enums import jogMode

class dobot_automation :
    def __init__(self,connected_command,home_cablibrate_command,automation_command,emergency_stop_command, quit_command):
        self.connected_complete = 0
        self.check_loop_after_connected = 0
        self.usb_check_connection  = 2
        self.connected_command = connected_command
        try:
           self.serial_port_connecting ()
           while (self.check_loop_after_connected > 1):
                self.home_cabliration(home_cablibrate_command)
                self.cleaning_automation_process(automation_command)
                self.automation_emergency_stop(emergency_stop_command)
                self.quit_automation_program(quit_command)
        except:
            print ("There is error in the program , please stop the program immediately ")

    def serial_port_connecting(self):
        while self.usb_check_connection > 1:
            if self.connected_command == 1:
                self.available_ports = list_ports.comports()
                print(f'available ports: {[x.device for x in self.available_ports]}')
                self.port = self.available_ports[0].device
                if len(self.available_ports) == 0:
                    print('No port avaliable')
                    print ('Please Check Connection')
                    self.connected_complete = 2
                else:
                    self.device = pydobot.Dobot(port=self.port, verbose=True)
                    self.usb_check_connection = 0
                    self.check_loop_after_connected = 2
                    self.connected_command = 0
                    self.connected_complete = 1
                    break

    def home_cabliration(self,home_cablibration_command):
        if home_cablibration_command == 1:
            self.device._set_queued_cmd_clear()
            self.device.set_jog_command( 1, jogMode.BP_DOWN, wait=True)
            self.device.wait(100)
            self.device.set_jog_command( 1, jogMode.IDLE , wait=True)
            self.device.wait(1000)
            self.device.set_home_params(178.9299, 3.3897 , -33.8784 , -82.7707, False)
            self.device.set_home_command (1,False)
            self.device.wait(1000)
            home_cablibration_command = 0

    def cleaning_automation_process(self,automation_command):
        if automation_command == 1:
            self.device._set_queued_cmd_clear()

            #initial position
            self.intial_moving_pos()

            #set 1
            self.set_one_pos_up()
            self.open_grip()

            self.set_one__pos_down()
            #close grip
            self.close_grip()
            #move up
            self.set_one_pos_up()

            self.bath_one_pos_1_up()
            self.bath_one_pos_1_down()
            self.open_grip()
            self.bath_one_pos_1_up()
            self.close_grip()
            self.disable_grip()

            #back to intial pos
            self.intial_moving_pos()
            self.set_two_pos_up()
            self.open_grip()
            self.set_two_pos_down()
            #close grip
            self.close_grip()
            #move up
            self.set_two_pos_up()
            self.bath_one_pos_2_up()
            self.bath_one_pos_2_down()
            self.open_grip()
            self.bath_one_pos_2_up()
            self.close_grip()
            self.disable_grip()

            #back to intial pos
            self.intial_moving_pos()
            self.bath_one_pos_1_up()
            self.open_grip()
            self.bath_one_pos_1_down()
            self.close_grip()
            self.bath_one_pos_1_up()
            self.set_one_pos_up()
            self.set_one__pos_down()
            self.open_grip()
            self.set_one_pos_up()
            self.close_grip()

            self.intial_moving_pos()
            self.bath_one_pos_2_up()
            self.open_grip()
            self.bath_one_pos_2_down()
            self.close_grip()
            self.bath_one_pos_2_up()
            self.set_two_pos_up()
            self.set_two_pos_down()
            self.open_grip()
            self.set_one_pos_up()
            self.close_grip()
            (x, y, z, r, j1, j2, j3, j4) = self.device.pose()
            print(f'x:{x} y:{y} z:{z} r:{r} j1:{j1} j2:{j2} j3:{j3} j4:{j4}')
            automation_command = 0

    def quit_automation_program(self,quit_command) :
        if quit_command == 1 :
            self.usb_check_connection = 2
            self.device.close()
            self.connected_complete = 0
            quit_command = 0

    def automation_emergency_stop(self,emmergency_command_stop ):
        if emmergency_command_stop == 1:
            self.device._set_queued_cmd_stop_exec()
            emmergency_command_stop = 0

    def intial_moving_pos(self):
        self.device.move_to( 17.8941 , 6.0331 ,  0.5921 , -134.5598, PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)
    def set_one_pos_up(self):
        self.device.move_to( 62.9159 , 13.689 , -10.0889 , 124.8797 , PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)

    def set_one__pos_down(self):
        self.device.move_to( 62.8941 , 16.9492 , 28.2911 , 124.8797 , PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)
    def set_two_pos_up (self):
        self.device.move_to( 80.2371 , 6.9371 , -12.9820 , 99.4637 , PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)
    def set_two_pos_down(self):
        self.device.move_to( 80.2371 , 6.9371 , 26.238 , 99.4637 , PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)
    def set_three_pos(self):
        self.device.move_to( 50.82 , -3.56 , -9.18 , -134.5598, PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)
        #device.move_to( 52.29 , 31.8271 , 13.82 , -85.6, PTPMode.MOVJ_ANGLE, wait=True)
        #device.wait(1000)
    def open_grip(self):
        self.device.grip(False)
        self.device_setupdevice.wait(1000)
        self.device.suck(False)
        self.device.wait(1000)
    def close_grip(self):
        self.device.grip(True)
        self.device.wait(1000)
        self.device.suck(True)
        self.device.wait(1000)
    def disable_grip(self):
        self.device.suck(False)
        self.device.wait(1000)
    def bath_one_pos_1_up(self):
        self.device.move_to( 3.1442 , 36.3588 , -14.6246 ,-68.4760  , PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)
    def bath_one_pos_1_down(self):
        self.device.move_to( 3.1442 , 36.3588 , -14.6246 , 89.4437 , PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)
        self.device.move_to( 3.1442 , 36.3588 , 20.5754 , 89.4437 , PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)
    def bath_one_pos_2_up(self):
        self.device.move_to ( 22.6588 , 46.7398 , -8.1826 , 99.4637 , PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)
    def bath_one_pos_2_down(self):
        self.device.move_to ( 22.6588 , 46.7398 , -8.1826 , -102.1199 , PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)
        self.device.move_to ( 22.6588 , 46.7398 , 16.3267 , -102.1199 , PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)

main_dobot.py ( for extra question):

from serial.tools import list_ports

import pydobot
from pydobot.enums import PTPMode
from pydobot.enums import jogMode

class dobot_automation :
    def __init__(self,connected_command,home_cablibrate_command,automation_command,emergency_stop_command, quit_command):
        self.connected_complete = 0
        self.check_loop_after_connected = 0
        self.usb_check_connection  = 2
        self.connected_command = connected_command
        try:
           self.serial_port_connecting ()
           while (self.check_loop_after_connected > 1):
                self.home_cabliration(home_cablibrate_command)
                self.cleaning_automation_process(automation_command)
                self.automation_emergency_stop(emergency_stop_command)
                self.quit_automation_program(quit_command)
        except:
            print ("There is error in the program , please stop the program immediately ")

    def serial_port_connecting(self):

        if self.connected_command == 1:
            self.available_ports = list_ports.comports()
            print(f'available ports: {[x.device for x in self.available_ports]}')
            self.port = self.available_ports[0].device
            if len(self.available_ports) == 0:
                print('No port avaliable')
                print ('Please Check Connection')
                self.connected_complete = 2
            else:
                self.device = pydobot.Dobot(port=self.port, verbose=True)
                self.usb_check_connection = 0
                self.check_loop_after_connected = 2
                self.connected_command = 0
                self.connected_complete = 1

    def home_cabliration(self,home_cablibration_command):
        if home_cablibration_command == 1:
            self.device._set_queued_cmd_clear()
            self.device.set_jog_command( 1, jogMode.BP_DOWN, wait=True)
            self.device.wait(100)
            self.device.set_jog_command( 1, jogMode.IDLE , wait=True)
            self.device.wait(1000)
            self.device.set_home_params(178.9299, 3.3897 , -33.8784 , -82.7707, False)
            self.device.set_home_command (1,False)
            self.device.wait(1000)
            home_cablibration_command = 0

    def cleaning_automation_process(self,automation_command):
        if automation_command == 1:
            self.device._set_queued_cmd_clear()

            #initial position
            self.intial_moving_pos()

            #set 1
            self.set_one_pos_up()
            self.open_grip()

            self.set_one__pos_down()
            #close grip
            self.close_grip()
            #move up
            self.set_one_pos_up()

            self.bath_one_pos_1_up()
            self.bath_one_pos_1_down()
            self.open_grip()
            self.bath_one_pos_1_up()
            self.close_grip()
            self.disable_grip()

            #back to intial pos
            self.intial_moving_pos()
            self.set_two_pos_up()
            self.open_grip()
            self.set_two_pos_down()
            #close grip
            self.close_grip()
            #move up
            self.set_two_pos_up()
            self.bath_one_pos_2_up()
            self.bath_one_pos_2_down()
            self.open_grip()
            self.bath_one_pos_2_up()
            self.close_grip()
            self.disable_grip()

            #back to intial pos
            self.intial_moving_pos()
            self.bath_one_pos_1_up()
            self.open_grip()
            self.bath_one_pos_1_down()
            self.close_grip()
            self.bath_one_pos_1_up()
            self.set_one_pos_up()
            self.set_one__pos_down()
            self.open_grip()
            self.set_one_pos_up()
            self.close_grip()

            self.intial_moving_pos()
            self.bath_one_pos_2_up()
            self.open_grip()
            self.bath_one_pos_2_down()
            self.close_grip()
            self.bath_one_pos_2_up()
            self.set_two_pos_up()
            self.set_two_pos_down()
            self.open_grip()
            self.set_one_pos_up()
            self.close_grip()
            (x, y, z, r, j1, j2, j3, j4) = self.device.pose()
            print(f'x:{x} y:{y} z:{z} r:{r} j1:{j1} j2:{j2} j3:{j3} j4:{j4}')
            automation_command = 0

    def quit_automation_program(self,quit_command) :
        if quit_command == 1 :
            self.usb_check_connection = 2
            self.device.close()
            self.connected_complete = 0
            quit_command = 0

    def automation_emergency_stop(self,emmergency_command_stop ):
        if emmergency_command_stop == 1:
            self.device._set_queued_cmd_stop_exec()
            emmergency_command_stop = 0

    def intial_moving_pos(self):
        self.device.move_to( 17.8941 , 6.0331 ,  0.5921 , -134.5598, PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)
    def set_one_pos_up(self):
        self.device.move_to( 62.9159 , 13.689 , -10.0889 , 124.8797 , PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)

    def set_one__pos_down(self):
        self.device.move_to( 62.8941 , 16.9492 , 28.2911 , 124.8797 , PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)
    def set_two_pos_up (self):
        self.device.move_to( 80.2371 , 6.9371 , -12.9820 , 99.4637 , PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)
    def set_two_pos_down(self):
        self.device.move_to( 80.2371 , 6.9371 , 26.238 , 99.4637 , PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)
    def set_three_pos(self):
        self.device.move_to( 50.82 , -3.56 , -9.18 , -134.5598, PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)
        #device.move_to( 52.29 , 31.8271 , 13.82 , -85.6, PTPMode.MOVJ_ANGLE, wait=True)
        #device.wait(1000)
    def open_grip(self):
        self.device.grip(False)
        self.device_setupdevice.wait(1000)
        self.device.suck(False)
        self.device.wait(1000)
    def close_grip(self):
        self.device.grip(True)
        self.device.wait(1000)
        self.device.suck(True)
        self.device.wait(1000)
    def disable_grip(self):
        self.device.suck(False)
        self.device.wait(1000)
    def bath_one_pos_1_up(self):
        self.device.move_to( 3.1442 , 36.3588 , -14.6246 ,-68.4760  , PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)
    def bath_one_pos_1_down(self):
        self.device.move_to( 3.1442 , 36.3588 , -14.6246 , 89.4437 , PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)
        self.device.move_to( 3.1442 , 36.3588 , 20.5754 , 89.4437 , PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)
    def bath_one_pos_2_up(self):
        self.device.move_to ( 22.6588 , 46.7398 , -8.1826 , 99.4637 , PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)
    def bath_one_pos_2_down(self):
        self.device.move_to ( 22.6588 , 46.7398 , -8.1826 , -102.1199 , PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)
        self.device.move_to ( 22.6588 , 46.7398 , 16.3267 , -102.1199 , PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)


来源: stackexchange

问:
Python how to format a string time from number time to name time
I have a string time :

```<code>ctime = 'Thu Sep  1 12:25:26 2022'
</code>```

How can I format it to :

```<code>01 Sep 2022 12:25:26
</code>```

I have tried:

```<code>ctime .strftime("%d %m %Y, %H:%M:%S")
</code>```

But received:

```<code>AttributeError: 'str' object has no attribute 'strftime'
</code>```

Any friend can help ?

ContentLicense: CC BY-SA 4.0

Body:
I have a string time :

ctime = 'Thu Sep  1 12:25:26 2022'

How can I format it to :

01 Sep 2022 12:25:26

I have tried:

ctime .strftime("%d %m %Y, %H:%M:%S")

But received:

AttributeError: 'str' object has no attribute 'strftime'

Any friend can help ?


问:
How can I add multiple headers with the same name in Swagger 2.0?
The user can add more than one customer list in the header. If I do it in the Swagger editor and add a header with the same name, I get the following error: "Sibling parameters must have unique names and values." How can I add multiple headers with the same name in Swagger 2.0?</p>
```<code>    parameters:
        - name: customerId
          in: path
          description: Customer ID
          required: true
          type: string
        - name: Authorization
          in: header
          description: Bearer Token
          required: true
          type: string
        - name: username
          in: header
          description: Username
          required: true
          type: string
        - name: customerList
          in: header
          description: List of authorized customer
          required: false
          type: string
        - name: customerList
          in: header
          description: List of authorized customer
          required: false
          type: string
</code>```

Body:
The user can add more than one customer list in the header. If I do it in the Swagger editor and add a header with the same name, I get the following error: "Sibling parameters must have unique names and values." How can I add multiple headers with the same name in Swagger 2.0?

    parameters:
        - name: customerId
          in: path
          description: Customer ID
          required: true
          type: string
        - name: Authorization
          in: header
          description: Bearer Token
          required: true
          type: string
        - name: username
          in: header
          description: Username
          required: true
          type: string
        - name: customerList
          in: header
          description: List of authorized customer
          required: false
          type: string
        - name: customerList
          in: header
          description: List of authorized customer
          required: false
          type: string


问:
How to set the monitor refresh rate for a playwright test?
I have a program that renders something to a Canvas using WebGL and JavaScript's requestAnimationFrame.

I am building a benchmark test that I want to test on different computers under various screen sizes and refresh-rates: for example, modern macbooks have 120fps screens, but most external monitors would be 30-60fps. Depending on the display where Chrome is rendered, it picks the refresh rate to match the display.

I am using playwright to run this test in headless mode on various devices and CI. You can set the screen size and zoom level according to the docs, but there is nothing about the refresh rate.

How to set or limit the refresh rate for Playwright? I am using Playwright with Chromium.


问:
Randbetween 1 and 4, excluding the value to the left, and maintaining the count for each number
I have the following array in excel. In the second column are numbers I have chosen between 1 and 4 so that the count of each value is either 3 or 4. I.e., four 1's, three 2's, four 3's, and three 4's. I chose these values arbitrarily.

This is meant to be a way to make sure members in the set do not have the same number (1-4) more than once.

The value in column C (Lab 3-4) should follow these criteria

Random integer between 1 and 4 that is not equal to the value in column B (Lab 1-2). CHOOSE(RANDBETWEEN(1,2),IF([@[Lab 1-2]]=1,2,RANDBETWEEN(1,[@[Lab 1-2]]-1)),IF([@[Lab 1-2]]=4,3,RANDBETWEEN([@[Lab 1-2]]+1,4)))

The number of 1's equals 4, the number of 2's equals 3, the number of 3's equals 4, and the number of 4's equals 3. This criteria can be relaxed so that 2 numbers only repeat 3 times and the remaining repeat 4 times.

The value in column D cannot be the same as the value in B.

The array below shows the result of applying the first condition. I successfully generated the random number, but I have no way of controlling the number of times each integer is repeated. I would have to apply a similar process for column D (Lab 5-6) but it would need to include columns B and C.

The if statements also include a 2 or 3 arbitrarily to make the script work and I guess this is where the code should be updated.

Is there a way to generate random integers like this while making sure the number of repetitions follows the criteria in my second bullet?
As I mentioned above, I can relax the second condition but I'm not sure if that makes it easier or harder to implement.


问:
How to get the scrollHeight of a cross-origin iframe
I would like to ask if how could we get the current scrollHeight of a cross-origin iframe because I need it so that once it is scrolled at the bottom, I can execute a functionality on it.

Here is the sample code that I will be using.

```<code>$(iFrameId).on('scroll', function() {
    if($(this).scrollTop() + $(this).innerHeight() + 1 >= $(this)[0].scrollHeight) {
        alert('Scrolled');
        //some code that uses document
    }
});
</code>```

Unfortunately, I am experiencing this kind of issue in the browser log

Uncaught DOMException: Permission denied to access property "document"
on cross-origin object

Please advise. Thanks!

Body:
I would like to ask if how could we get the current scrollHeight of a cross-origin iframe because I need it so that once it is scrolled at the bottom, I can execute a functionality on it.

Here is the sample code that I will be using.

$(iFrameId).on('scroll', function() {
    if($(this).scrollTop() + $(this).innerHeight() + 1 >= $(this)[0].scrollHeight) {
        alert('Scrolled');
        //some code that uses document
    }
});

Unfortunately, I am experiencing this kind of issue in the browser log

Uncaught DOMException: Permission denied to access property "document"
on cross-origin object

Please advise. Thanks!


问:
Is there a way to connect a CCTV camera to an Instagram live feed?
Does anyone know of a way to stream wirelessly from a cctv camera to an instagram live feed?

I've looked into yellow duck a bit but I'm not sure if that would work.


问:
React how to add defaultChecked in ToggleButtonGroup
These is my code

```<code><ToggleButtonGroup name='plotType' value={plotType} type="radio" onSelect={handlePlot} vertical={false} >
                        METROLOGY_TYPE_SHOW_PLOT[metrologyType].map((key, index) => (
        <OverlayTrigger
            key={index}
            placement="right"
            overlay={<Tooltip id="button-tooltip-2">{key}</Tooltip>}>
            <ToggleButton id={key} value={key}
                          variant="link"
                          size='sm'>
                  <img alt={key} src={getIconUrl(key)}/>
            </ToggleButton>
        </OverlayTrigger>
</ToggleButtonGroup>
</code>```

I try to add defaultChecked and defaulValue in ToggleButtonGroup ,but it didn't worked

I want to set the defaultValue and the button have default border.

Body:
These is my code

<ToggleButtonGroup name='plotType' value={plotType} type="radio" onSelect={handlePlot} vertical={false} >
                        METROLOGY_TYPE_SHOW_PLOT[metrologyType].map((key, index) => (
        <OverlayTrigger
            key={index}
            placement="right"
            overlay={<Tooltip id="button-tooltip-2">{key}</Tooltip>}>
            <ToggleButton id={key} value={key}
                          variant="link"
                          size='sm'>

            </ToggleButton>
        </OverlayTrigger>
</ToggleButtonGroup>

I try to add defaultChecked and defaulValue in ToggleButtonGroup ,but it didn't worked

I want to set the defaultValue and the button have default border.


问:
I used Google Cloud Platform App Engine and Google Cloud SQL, Sequelize, but Error: connect ETIMEDOUT error

The server is intended to be deployed via GCP, React is deployed as a separate instance.

I use Sequelize, Node, Express, MySQL.

Cloud SQL confirmed that Sequelize and DB were well linked through workbench.

I once distributed it through APP Engine, so I added Cloud SQL-related settings, and if there was no problem, I decided that it would be possible to call the desired data.

The deployment was successful through gcloud app deployment and tried to verify that the desired API was called well, but 500 errors were constantly occurring.

I don't know where to fix it, can you give me a tip?

```<code>config/config.js

require('dotenv').config();

module.exports = {
  development: {
    username: "root",
    password: process.env.SEQUELIZE_PASSWORD,
    database: "DBName",
    host: "SQL Instance Public IP Address",
    dialect: "mysql",
    timezone: "+09:00"
  },
  test: {
    username: "root",
    password: null,
    database: "database_test",
    host: "127.0.0.1",
    dialect: "mysql"
  },
  production: {
    username: "root",
    password: process.env.SEQUELIZE_PASSWORD,
    database: "DBName",
    host: "SQL Instance Public IP Address",
    dialect: "mysql",
    timezone: "+09:00",
    logging: false
  },
}
</code>```
```<code>server.js
const express = require('express')
const cors = require('cors')
const dotenv = require('dotenv')

const Test = require('./Routes/Test')

const { sequelize } = require('./models')

dotenv.config()

const app = express()

app.set("PORT", process.env.PORT || 8080)

sequelize.sync({force: false})
.then(() => {console.log('db Oneline')})
.catch((err) => {console.error(err)})

app.use(cors({origin: "*"}))
app.use(express.json())

app.use('/test',Test)

app.listen(app.get('PORT'), () => {
    console.log(app.get("PORT"), 'Online')
})

</code>```

In server.js, /test aims to receive this data from the front desk in a get request.

```<code>app.yaml

runtime: nodejs
env: flex
service: default

manual_scaling:
  instances: 1
resources:
  cpu: 1
  memory_gb: 0.5
  disk_size_gb: 10

env_variables:
  SQL_USER: "root"
  SQL_PASSWORD: "root password entered when SQL was created"
  SQL_DATABASE: "Instance ID"
  INSTANCE_CONNECTION_NAME: "logintest-b314a:asia-northeast3:Instance ID"
beta_settings:
  cloud_sql_instances: "logintest-b314a:asia-northeast3:Instance ID"
</code>```

Error Messages from Error Reporting

SequelizeConnectionError: connect ETIMEDOUT
at ConnectionManager.connect (/app/node_modules/sequelize/lib/dialects/mysql/connection-manager.js:102:17)
at processTicksAndRejections (internal/process/task_queues.js:97:5)

parent: Error: connect ETIMEDOUT
at Connection._handleTimeoutError (/app/node_modules/mysql2/lib/connection.js:189:17)
at listOnTimeout (internal/timers.js:554:17)
at processTimers (internal/timers.js:497:7) {

Body:
The server is intended to be deployed via GCP, React is deployed as a separate instance.

I use Sequelize, Node, Express, MySQL.

Cloud SQL confirmed that Sequelize and DB were well linked through workbench.

I once distributed it through APP Engine, so I added Cloud SQL-related settings, and if there was no problem, I decided that it would be possible to call the desired data.

The deployment was successful through gcloud app deployment and tried to verify that the desired API was called well, but 500 errors were constantly occurring.

I don't know where to fix it, can you give me a tip?

config/config.js

require('dotenv').config();

module.exports = {
  development: {
    username: "root",
    password: process.env.SEQUELIZE_PASSWORD,
    database: "DBName",
    host: "SQL Instance Public IP Address",
    dialect: "mysql",
    timezone: "+09:00"
  },
  test: {
    username: "root",
    password: null,
    database: "database_test",
    host: "127.0.0.1",
    dialect: "mysql"
  },
  production: {
    username: "root",
    password: process.env.SEQUELIZE_PASSWORD,
    database: "DBName",
    host: "SQL Instance Public IP Address",
    dialect: "mysql",
    timezone: "+09:00",
    logging: false
  },
}

server.js
const express = require('express')
const cors = require('cors')
const dotenv = require('dotenv')

const Test = require('./Routes/Test')

const { sequelize } = require('./models')

dotenv.config()

const app = express()

app.set("PORT", process.env.PORT || 8080)

sequelize.sync({force: false})
.then(() => {console.log('db Oneline')})
.catch((err) => {console.error(err)})

app.use(cors({origin: "*"}))
app.use(express.json())

app.use('/test',Test)

app.listen(app.get('PORT'), () => {
    console.log(app.get("PORT"), 'Online')
})

In server.js, /test aims to receive this data from the front desk in a get request.

app.yaml

runtime: nodejs
env: flex
service: default

manual_scaling:
  instances: 1
resources:
  cpu: 1
  memory_gb: 0.5
  disk_size_gb: 10

env_variables:
  SQL_USER: "root"
  SQL_PASSWORD: "root password entered when SQL was created"
  SQL_DATABASE: "Instance ID"
  INSTANCE_CONNECTION_NAME: "logintest-b314a:asia-northeast3:Instance ID"
beta_settings:
  cloud_sql_instances: "logintest-b314a:asia-northeast3:Instance ID"

Error Messages from Error Reporting

SequelizeConnectionError: connect ETIMEDOUT
at ConnectionManager.connect (/app/node_modules/sequelize/lib/dialects/mysql/connection-manager.js:102:17)
at processTicksAndRejections (internal/process/task_queues.js:97:5)

parent: Error: connect ETIMEDOUT
at Connection._handleTimeoutError (/app/node_modules/mysql2/lib/connection.js:189:17)
at listOnTimeout (internal/timers.js:554:17)
at processTimers (internal/timers.js:497:7) {


问:
OpenCV Haar Cascade Training Images for a Browser Mahjong Game
QUESTION: HOW DO I CHANGE PARAMETERS (XML, TERMINAL) OR DATA SET (SEE PICTURES) TO GET WORKING RESULTS USING OPEN CV HAAR CASCADE?

I previously used OpenCV template and feature matching to code a program that would play a game of Mahjong from here: https://www.freemahjong.com/games/mahjong-quest

'Data':
https://github.com/derkangkino/HAAR_Mahjong

When I tried a second time using Haar Cascades, the results are very poor. (see link for false positives picture)

For positives of a single tile, I have 4 different cuts and I copy
them over and over to get a larger set. Tried 100, 600, 1000 images
of positive copies.

For negatives, I have the 4 cuts of every other tile. Tried 5000

images of negative copies.

I also tried using backgrounds instead, which seemed to work better?
But it was only copies of one image.

Trained model: (see link above)

This was the most recent result. Other results have been worse.

My training finishes after 3 epochs and if I change the settings then the epochs would never finish beyond 5.

These were my settings:

terminal settings:

precalcValBufSize 4000 -precalcIdxBufSize 4000 -w 24 -h 24 -numPos 100 -numNeg 800 -numStages 5

.xml file settings:

```<code><?xml version="1.0"?>
<opencv_storage>
<params>
  <stageType>BOOST</stageType>
  <featureType>HAAR</featureType>
  <height>24</height>
  <width>24</width>
  <stageParams>
    <boostType>GAB</boostType>
    <minHitRate>9.9500000476837158e-01</minHitRate>
    <maxFalseAlarm>0.01</maxFalseAlarm>
    <weightTrimRate>9.4999999999999996e-01</weightTrimRate>
    <maxDepth>1</maxDepth>
    <maxWeakCount>100</maxWeakCount></stageParams>
  <featureParams>
    <maxCatCount>0</maxCatCount>
    <featSize>1</featSize>
    <mode>BASIC</mode></featureParams></params>
</opencv_storage>
</code>```

I tried max alarm 0.1 as well. 0.5 finishes the training on the first epoch.

Body:
QUESTION: HOW DO I CHANGE PARAMETERS (XML, TERMINAL) OR DATA SET (SEE PICTURES) TO GET WORKING RESULTS USING OPEN CV HAAR CASCADE?

I previously used OpenCV template and feature matching to code a program that would play a game of Mahjong from here: https://www.freemahjong.com/games/mahjong-quest

'Data':
https://github.com/derkangkino/HAAR_Mahjong

When I tried a second time using Haar Cascades, the results are very poor. (see link for false positives picture)

For positives of a single tile, I have 4 different cuts and I copy
them over and over to get a larger set. Tried 100, 600, 1000 images
of positive copies.

For negatives, I have the 4 cuts of every other tile. Tried 5000

images of negative copies.

I also tried using backgrounds instead, which seemed to work better?
But it was only copies of one image.

Trained model: (see link above)

This was the most recent result. Other results have been worse.

My training finishes after 3 epochs and if I change the settings then the epochs would never finish beyond 5.

These were my settings:

terminal settings:

precalcValBufSize 4000 -precalcIdxBufSize 4000 -w 24 -h 24 -numPos 100 -numNeg 800 -numStages 5

.xml file settings:

<?xml version="1.0"?>
<opencv_storage>
<params>
  <stageType>BOOST</stageType>
  <featureType>HAAR</featureType>
  <height>24</height>
  <width>24</width>
  <stageParams>
    <boostType>GAB</boostType>
    <minHitRate>9.9500000476837158e-01</minHitRate>
    <maxFalseAlarm>0.01</maxFalseAlarm>
    <weightTrimRate>9.4999999999999996e-01</weightTrimRate>
    <maxDepth>1</maxDepth>
    <maxWeakCount>100</maxWeakCount></stageParams>
  <featureParams>
    <maxCatCount>0</maxCatCount>
    <featSize>1</featSize>
    <mode>BASIC</mode></featureParams></params>
</opencv_storage>

I tried max alarm 0.1 as well. 0.5 finishes the training on the first epoch.


问:
New line in RGui (64-Bit), Shift + Enter doesn't work
I've just downloaded the RGui to poke around and cannot figure out how to create a new line unless I'm using a trailing comma or open bracket/parenthesis/quote.
Shift + Enter does not work for me.
Can't seem to find any more information on it.

I've tried google, r documentation, cran website, can't find the trick.


问:
Python ciscoconfparse - check specific line in a config
I'm trying to get the AAA configuration in my switch to compare the exact configuration, but when i try to gather with the exact same config it doesn't show that as a correct configuration.

Here's the example :

```<code>def check_config(config):
    parse = CiscoConfParse('test_config.txt', syntax='ios')
    tcs_obj = parse.find_lines(config)

    if parse.find_objects(config):
        print(parse.find_objects(config))
    else:
        print(f'Config {config} not found!!!')

check_config('aaa authentication login default group tacacs+ local')
</code>```

The result:

Config aaa authentication login default group tacacs+ local not found!!!

But when i tried to remove the 'local', it showed the line.

```<code>check_config('aaa authentication login default group tacacs+')
</code>```

[<IOSCfgLine # 34 'aaa authentication login default group tacacs+ local'>]

Body:
I'm trying to get the AAA configuration in my switch to compare the exact configuration, but when i try to gather with the exact same config it doesn't show that as a correct configuration.

Here's the example :

def check_config(config):
    parse = CiscoConfParse('test_config.txt', syntax='ios')
    tcs_obj = parse.find_lines(config)

    if parse.find_objects(config):
        print(parse.find_objects(config))
    else:
        print(f'Config {config} not found!!!')

check_config('aaa authentication login default group tacacs+ local')

The result:

Config aaa authentication login default group tacacs+ local not found!!!

But when i tried to remove the 'local', it showed the line.

check_config('aaa authentication login default group tacacs+')

[<IOSCfgLine # 34 'aaa authentication login default group tacacs+ local'>]


问:
Is there a way to measure the performance of an Angular microfront?
Hello everyone and sorry for my bad English.

I have a question and as the title says, I wanted to know if there is a way to measure the performance of a microfrontend (Custom elements + Shell) that each microfront is expressed in an Angular module (own routes, components, pipes, flows , etc...) and with these results (metrics), determine if the code or its performance can be improved.

I have been looking for tools such as Google's lighthouse, but the truth is that it does not help me much since, although it is true, it measures performance such as First Contentful Painting or SEO, but it is of the entire application and that is not what is sought anymore I want it to be by modules, why? What happens is that we have various teams developing microfronts individually, so we want to measure individual performance with some tool to determine if we are doing well with respect to performance, any help? I have searched and tried in many ways but I can't find any solution, thanks in advance.


问:
Error on printing html (with internal links and page breaks) to pdf
```<code><html>
  <body>
    <a href="#page2">page 2</a>
    <div style="break-after:page"></div>
    <a id="page2" href="#page3">page 3</a>
    <div style="break-after:page"></div>
    <a id="page3" href="#page4">page 4</a>
    <div style="break-after:page"></div>
    <div id="page4"></div>
  </body>
</html>
</code>```

When I try the following command on the above HTML file, it can not print the HTML file to pdf file correctly (I end up with a pdf file with an empty page).

```<code>'/Applications/Brave Browser.app/Contents/MacOS/Brave Browser' --headless --enable-logging --disable-extensions --print-to-pdf-no-header --disable-popup-blocking --run-all-compositor-stages-before-draw --disable-checker-imaging --disable-gpu --print-to-pdf=main.pdf main.html
</code>```

How can I fix the problem? I don't have chrome on my machine, can anybody test it on chrome to see if this problem is specific to brave or it appears on other browsers as well? If so, how can I fix the problem so that it works on all browsers?

Body:
    page 2

    page 3

    page 4

When I try the following command on the above HTML file, it can not print the HTML file to pdf file correctly (I end up with a pdf file with an empty page).

'/Applications/Brave Browser.app/Contents/MacOS/Brave Browser' --headless --enable-logging --disable-extensions --print-to-pdf-no-header --disable-popup-blocking --run-all-compositor-stages-before-draw --disable-checker-imaging --disable-gpu --print-to-pdf=main.pdf main.html

How can I fix the problem? I don't have chrome on my machine, can anybody test it on chrome to see if this problem is specific to brave or it appears on other browsers as well? If so, how can I fix the problem so that it works on all browsers?


问:
mediapipe .process() kills kernel
I am trying to use mediapipe pose to export the coordinates of the keypoints of the human body when rowing to a csv file. My main problem is with the .process() function that keeps throwing up an error whenever I execute the cell. I have previously tried doing the pose estimation with out the try-except (the part of the code that exports the keypoint data to a csv file) and it works, but for some reason, this code now kills the kernel every time the cell is run. Each codeblock  represents a cell in a jupyter notebook - THE LAST CELL IS THE SAME AS THE 3RD CELL, other than the different video being fed into the mediapipe pose model and the try-except that is supposed to export the data to a csv file, this is the cell where the kernel dies.</p>
```<code>import mediapipe as mp
import cv2
import numpy as np
</code>```
```<code>mp_drawing  = mp.solutions.drawing_utils
mp_pose = mp.solutions.pose
</code>```
```<code>cap = cv2.VideoCapture('') <----- THIS IS WHERE THE VIDEO OF SOMEONE ROWING WOULD BE

with mp_pose.Pose(min_detection_confidence=0.5, min_tracking_confidence=0.5) as pose:
    while cap.isOpened():
        ret, image = cap.read()

        #recolor
        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
        image.flags.writeable = False

        #detections
        results = pose.process(image)

        #recolor back to RGB
        image.flags.writeable = True
        image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
        mp_drawing.draw_landmarks(image, results.pose_landmarks, mp_pose.POSE_CONNECTIONS
                                 , mp_drawing.DrawingSpec(color=(245,117,66), thickness=2, circle_radius=4),
                                 mp_drawing.DrawingSpec(color=(245, 66, 230), thickness=2, circle_radius=2)
                                 )

        cv2.imshow('RawFeed', image)

        if cv2.waitKey(10) & 0xFF == ord('q'):
            break

cap.release()
cv2.destroyAllWindows()
</code>```
```<code>import csv
import os
import numpy as np
</code>```
```<code>landmarks = ['class']
for val in range (1, num_coords+1):
    landmarks += ['x{}'.format(val), 'y{}'.format(val), 'z{}'.format(val), 'v{}'.format(val)]
</code>```
```<code>with open ('trainData.csv', mode='w', newline ='') as f:
    csv_writer = csv.writer(f, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)
    csv_writer.writerow(landmarks)
</code>```
```<code>class_name = "Catch"
</code>```
```<code>cap = cv2.VideoCapture('CatchTrain.mp4')

with mp_pose.Pose(min_detection_confidence=0.5, min_tracking_confidence=0.5) as pose:
    while cap.isOpened():
        ret, image = cap.read()

        #recolor
        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
        image.flags.writeable = False

        #detections
        results = pose.process(image)

        #recolor back to RGB
        image.flags.writeable = True
        image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
        mp_drawing.draw_landmarks(image, results.pose_landmarks, mp_pose.POSE_CONNECTIONS
                                 , mp_drawing.DrawingSpec(color=(245,117,66), thickness=2, circle_radius=4),
                                 mp_drawing.DrawingSpec(color=(245, 66, 230), thickness=2, circle_radius=2)
                                 )

        #export coordinates
        try:
            pose = results.pose_landmarks.landmark #gets the pose landmarks
            pose_row = np.array([[landmark.x, landmark.y, landmark.z, landmark.visibility] for landmark in pose]).flatten()
                #gives each landmark component
                # .flatten() collapses an array into a single dimension, [[1,2],[3,4]] --> [1,2,3,4]

            pose_row.insert(0, class_name) #appends the class name to the CSV

                #Exports to CSV

            with open ('trainData.csv', 'a', newline ='') as f:
                csv_writer = csv.writer(f, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)
                csv_writer.writerow(pose_row)

        except Exception as e:
            pass

        cv2.imshow('CatchFeed', image)

        if cv2.waitKey(10) & 0xFF == ord('q'):
            break

cap.release()
cv2.destroyAllWindows()
</code>```

Title: mediapipe .process() kills kernel

Body:
I am trying to use mediapipe pose to export the coordinates of the keypoints of the human body when rowing to a csv file. My main problem is with the .process() function that keeps throwing up an error whenever I execute the cell. I have previously tried doing the pose estimation with out the try-except (the part of the code that exports the keypoint data to a csv file) and it works, but for some reason, this code now kills the kernel every time the cell is run. Each codeblock  represents a cell in a jupyter notebook - THE LAST CELL IS THE SAME AS THE 3RD CELL, other than the different video being fed into the mediapipe pose model and the try-except that is supposed to export the data to a csv file, this is the cell where the kernel dies.

import mediapipe as mp
import cv2
import numpy as np

mp_drawing  = mp.solutions.drawing_utils
mp_pose = mp.solutions.pose

cap = cv2.VideoCapture('') <----- THIS IS WHERE THE VIDEO OF SOMEONE ROWING WOULD BE

with mp_pose.Pose(min_detection_confidence=0.5, min_tracking_confidence=0.5) as pose:
    while cap.isOpened():
        ret, image = cap.read()

        #recolor
        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
        image.flags.writeable = False

        #detections
        results = pose.process(image)

        #recolor back to RGB
        image.flags.writeable = True
        image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
        mp_drawing.draw_landmarks(image, results.pose_landmarks, mp_pose.POSE_CONNECTIONS
                                 , mp_drawing.DrawingSpec(color=(245,117,66), thickness=2, circle_radius=4),
                                 mp_drawing.DrawingSpec(color=(245, 66, 230), thickness=2, circle_radius=2)
                                 )

        cv2.imshow('RawFeed', image)

        if cv2.waitKey(10) & 0xFF == ord('q'):
            break

cap.release()
cv2.destroyAllWindows()

import csv
import os
import numpy as np

landmarks = ['class']
for val in range (1, num_coords+1):
    landmarks += ['x{}'.format(val), 'y{}'.format(val), 'z{}'.format(val), 'v{}'.format(val)]

with open ('trainData.csv', mode='w', newline ='') as f:
    csv_writer = csv.writer(f, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)
    csv_writer.writerow(landmarks)

class_name = "Catch"

cap = cv2.VideoCapture('CatchTrain.mp4')

with mp_pose.Pose(min_detection_confidence=0.5, min_tracking_confidence=0.5) as pose:
    while cap.isOpened():
        ret, image = cap.read()

        #recolor
        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
        image.flags.writeable = False

        #detections
        results = pose.process(image)

        #recolor back to RGB
        image.flags.writeable = True
        image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
        mp_drawing.draw_landmarks(image, results.pose_landmarks, mp_pose.POSE_CONNECTIONS
                                 , mp_drawing.DrawingSpec(color=(245,117,66), thickness=2, circle_radius=4),
                                 mp_drawing.DrawingSpec(color=(245, 66, 230), thickness=2, circle_radius=2)
                                 )

        #export coordinates
        try:
            pose = results.pose_landmarks.landmark #gets the pose landmarks
            pose_row = np.array([[landmark.x, landmark.y, landmark.z, landmark.visibility] for landmark in pose]).flatten()
                #gives each landmark component
                # .flatten() collapses an array into a single dimension, [[1,2],[3,4]] --> [1,2,3,4]

            pose_row.insert(0, class_name) #appends the class name to the CSV

                #Exports to CSV

            with open ('trainData.csv', 'a', newline ='') as f:
                csv_writer = csv.writer(f, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)
                csv_writer.writerow(pose_row)

        except Exception as e:
            pass

        cv2.imshow('CatchFeed', image)

        if cv2.waitKey(10) & 0xFF == ord('q'):
            break

cap.release()
cv2.destroyAllWindows()


问:
GoogleDrive API - generateIds
Does anyone know if generated ids has lifetime? Do they expire?

I did not find any information in the docs

https://developers.google.com/drive/api/v3/reference/files/generateIds

Thanks in advance

https://developers.google.com/drive/api/v3/reference/files/generateIds

Title: GoogleDrive API - generateIds


问:
Trying to retrieve mail information using pop3 from "fake smtp server"
I have 3 virtual machines:

```<code>xxx.xxx.xxx.44 (server)
xxx.xxx.xxx.55 (send mails)
xxx.xxx.xxx.66 (read mails)
</code>```

For the server, I have this line:

```<code>python3 -m smtpd -c DebuggingServer -n  XXX.XXX.XXX.44:25
</code>```

to host the "smtp server"

When i use xxx.xxx.xxx.55 to send an email using a python code, I am able to get this result:

---------- MESSAGE FOLLOWS ----------

```<code>b'From:john@emailserver.com'

b'To:Robert@emailserver.com'

b'Date:03/01/2023 15:45:06'

b'Subject:lol'

b'X-Peer: XXX.XXX.XXX.55'

b''

b'lol'
</code>```

------------ END MESSAGE ------------

I was wondering if it is possible to retrieve this "message" using pop/imap on xxx.xxx.xxx.66

It would also help if anyone knows where this "message" is stored on the email server so that I could use poplib to retrieve this message.

Body:
I have 3 virtual machines:

xxx.xxx.xxx.44 (server)
xxx.xxx.xxx.55 (send mails)
xxx.xxx.xxx.66 (read mails)

For the server, I have this line:

python3 -m smtpd -c DebuggingServer -n  XXX.XXX.XXX.44:25

to host the "smtp server"

When i use xxx.xxx.xxx.55 to send an email using a python code, I am able to get this result:

---------- MESSAGE FOLLOWS ----------

b'From:john@emailserver.com'

b'To:Robert@emailserver.com'

b'Date:03/01/2023 15:45:06'

b'Subject:lol'

b'X-Peer: XXX.XXX.XXX.55'

b''

b'lol'

------------ END MESSAGE ------------

I was wondering if it is possible to retrieve this "message" using pop/imap on xxx.xxx.xxx.66

It would also help if anyone knows where this "message" is stored on the email server so that I could use poplib to retrieve this message.


问:
Is it Heroku's problem or my problem? I can't log in on my deployed app and the error log isn't telling me *anything*
Okay, so I have my app deployed and I can register a new user. However when I try to login, it just loads indefinitely. Doesn't matter if I input an incorrect password -- it just loads, the error message that tells me the password is wrong does not appear. The error log is blank.

I'm sure I'm connected to the database (using Heroku's postgres) because I can register a new user and see them in the database. I can't create a user that already exists in the database.

As I said earlier: the error log (using heroku logs --tail) isn't telling me anything. They show when I'm registering a new user, and it appears to me that everything is going where it's meant to when I'm registering. Even if it didn't -- this all works locally. I'd show code but once again, I'm not even sure where the error (?) is occurring.

Thanks!


问:
How do i fix the error "ffmpeg was not found." in my discord bot?
I am currently trying to make my discord bot play a youtube audio from a URL. However, I can't pass the error "ffmpeg was not found". I have tried to use different solutions but nothing has worked. My code currently looks like this:

```<code>import discord
import asyncio
from discord import FFmpegPCMAudio
from discord.utils import get
from discord.ext import commands
from youtube_dl import YoutubeDL

@bot.command(brief="Plays a single video, from a youtube URL")
async def play(ctx, url):
    if not ctx.message.author.voice:
        await ctx.send("{} is not connected to a voice channel".format(ctx.message.author.name))
        return
    else:
        global channel_player
        channel_player = ctx.message.author.voice.channel
    await channel_player.connect()
    YDL_OPTIONS = {'format': 'bestaudio', 'noplaylist':'True'}
    FFMPEG_OPTIONS = {'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5', 'options': '-vn'}
    voice = get(bot.voice_clients, guild=ctx.guild)

    if not voice.is_playing():
        with YoutubeDL(YDL_OPTIONS) as ydl:
            info = ydl.extract_info(url, download=False)
        URL = info['url']
        voice.play(FFmpegPCMAudio(URL, **FFMPEG_OPTIONS))
        voice.is_playing()
    else:
        await ctx.send("Already playing song")
        return
</code>```

I am relatively new to coding so if you have any other suggestions on top of (hopefully) the solution to the problem, feel free!

I am relatively new to coding so if you have any other suggestions on top of (hopefully) the solution to the problem, feel free!

I have as I said tried a few different other approaches but nothing has worked. The one that seemed to almost work was to download ffmpeg through libx264 and create files that python could be directed to.

I also tried downloadeing the most recent version of ffmpeg and 7zip to extract it.

Body:
I am currently trying to make my discord bot play a youtube audio from a URL. However, I can't pass the error "ffmpeg was not found". I have tried to use different solutions but nothing has worked. My code currently looks like this:

import discord
import asyncio
from discord import FFmpegPCMAudio
from discord.utils import get
from discord.ext import commands
from youtube_dl import YoutubeDL

@bot.command(brief="Plays a single video, from a youtube URL")
async def play(ctx, url):
    if not ctx.message.author.voice:
        await ctx.send("{} is not connected to a voice channel".format(ctx.message.author.name))
        return
    else:
        global channel_player
        channel_player = ctx.message.author.voice.channel
    await channel_player.connect()
    YDL_OPTIONS = {'format': 'bestaudio', 'noplaylist':'True'}
    FFMPEG_OPTIONS = {'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5', 'options': '-vn'}
    voice = get(bot.voice_clients, guild=ctx.guild)

    if not voice.is_playing():
        with YoutubeDL(YDL_OPTIONS) as ydl:
            info = ydl.extract_info(url, download=False)
        URL = info['url']
        voice.play(FFmpegPCMAudio(URL, **FFMPEG_OPTIONS))
        voice.is_playing()
    else:
        await ctx.send("Already playing song")
        return

I am relatively new to coding so if you have any other suggestions on top of (hopefully) the solution to the problem, feel free!

I am relatively new to coding so if you have any other suggestions on top of (hopefully) the solution to the problem, feel free!

I have as I said tried a few different other approaches but nothing has worked. The one that seemed to almost work was to download ffmpeg through libx264 and create files that python could be directed to.

I also tried downloadeing the most recent version of ffmpeg and 7zip to extract it.


问:
Loopback 4 DTO class-validator not working
can't validate my request body inside this dto using class-validator, based on the documentation class-validator is supported but they dont have any example how to setup this and now its not working, I did miss something? thanks

auth.controller

```<code>@api({basePath: '/auth'})
export class AuthController {
  constructor(@service(AuthService) public authService: AuthService) {}

  @post('/login')
  async login(@requestBody() {email, password}: UserLoginInput) {
    const response = await this.authService.login(email, password);

    return {
      data: response,
    };
  }
}
</code>```

UserLoginInput

```<code>export class UserLoginInput {
  @IsNotEmpty()
  @IsEmail()
  email: string;

  @IsNotEmpty()
  password: string;
}
</code>```

loopback 4 class-validator

Body:
can't validate my request body inside this dto using class-validator, based on the documentation class-validator is supported but they dont have any example how to setup this and now its not working, I did miss something? thanks

auth.controller

@api({basePath: '/auth'})
export class AuthController {
  constructor(@service(AuthService) public authService: AuthService) {}

  @post('/login')
  async login(@requestBody() {email, password}: UserLoginInput) {
    const response = await this.authService.login(email, password);

    return {
      data: response,
    };
  }
}

UserLoginInput

export class UserLoginInput {
  @IsNotEmpty()
  @IsEmail()
  email: string;

  @IsNotEmpty()
  password: string;
}

loopback 4 class-validator


问:
How to create IAM role access against s3 bucket deny policy
I have s3 bucket with bucket policy which deny's all the actions. i wanted to create IAM role to list, put, get object actions. How can i achieve that.

s3-bucket-policy

```<code>{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "denyInsecureTransport",
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::my-bucket/*",
                "arn:aws:s3:::my-bucket"
            ],
            "Condition": {
                "Bool": {
                    "aws:SecureTransport": "false"
                }
            }
        }
    ]
}
</code>```

i have created IAM policy to perform actions against this bucket.

IAM Policy

```<code>{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:*"
            ],
            "Resource": [
                "arn:aws:s3:::my-bucket",
                "arn:aws:s3:::my-bucket/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iam:PassRole"
            ],
            "Resource": [
                "arn:aws:iam::*:role/*"
            ]
        }
    ]
}
</code>```

with this i am getting access denied error. how to modify this policy to perform s3 bucket actions. any help would be appreciated.

EDITED

module block:

```<code>resource "aws_s3_bucket_public_access_block" "bucket_public_access" {
  count  = var.create ? 1 : 0
  bucket = aws_s3_bucket.s3_bucket[0].bucket
  block_public_acls   = true
  block_public_policy = true
}

resource "aws_s3_bucket_policy" "bucket_policy" {
  count  = var.create ? 1 : 0
  bucket = local.bucket_name
  #policy = templatefile(var.bucket_policy_template, { account_number = var.account_number, region = var.region, bucket_name = local.bucket_name })

  policy = data.aws_iam_policy_document.s3_comb_policy[0].json
}

data "aws_iam_policy_document" "policy" {
  count = var.create ? 1 : 0
  statement {
    sid    = "denyInsecureTransport"
    effect = "Deny"

    actions = [
      "s3:*",
    ]

    resources = [
      "arn:aws:s3:::${local.bucket_name}",
      "arn:aws:s3:::${local.bucket_name}/*"

    ]
    principals {
      type        = "*"
      identifiers = ["*"]
    }

    condition {
      test     = "Bool"
      variable = "aws:SecureTransport"
      values = [
        "false"
      ]
    }
  }
  depends_on = [
    aws_s3_bucket.s3_bucket[0],
  ]

}

data "aws_iam_policy_document" "object_lock_policy" {
  count = var.create && var.object_lock ? 1 : 0
  statement {
    sid    = "ObjectLockConfiguration"
    effect = "Deny"
    actions = [
      "s3:BypassGovernanceRetention",
            "s3:PutBucketObjectLockConfiguration",
            "s3:PutObjectLegalHold",
            "s3:PutObjectRetention"
    ]
    resources = [
      "arn:aws:s3:::${local.bucket_name}",
      "arn:aws:s3:::${local.bucket_name}/*"
    ]
    principals {
      type        = "*"
      identifiers = ["*"]
    }
    condition {
      test     = "ArnNotEquals"
      variable = "aws:PrincipalArn"
      values = [
        "arn:aws:iam::${var.account_number}:role/${var.department}-jenkins-assumed-role-${var.environment}"
      ]
    }
  }
  depends_on = [
    aws_s3_bucket.s3_bucket[0],
  ]
}

data "aws_iam_policy_document" "s3_comb_policy" {
  count = var.create ? 1 : 0

  source_policy_documents = compact([
    data.aws_iam_policy_document.policy[0].json,
    var.object_lock ? data.aws_iam_policy_document.object_lock_policy[0].json : "",
    var.additional_policy != null ? var.additional_policy : ""
  ])
}
</code>```

and also they created one IAM role in the module itself

```<code>resource "aws_iam_role" "replication_role" {
  count              = var.create && length(var.replication_bucket_arn) != 0 ? 1 : 0
  name               = "${local.bucket_name}-s3-replication-role"
  permissions_boundary = "arn:aws:iam::${var.account_number}:policy/AGT-IAM-BOUNDARY-BASE"
  assume_role_policy = <<POLICY
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Principal": {
        "Service": "s3.amazonaws.com"
      },
      "Effect": "Allow",
      "Sid": "s3ReplicationAssume"
    }
  ]
}
POLICY
}

resource "aws_iam_policy" "replication_policy" {
  count  = var.create && length(var.replication_bucket_arn) != 0 ? 1 : 0
  name   = "${local.bucket_name}-s3-replication-policy"
  policy = <<POLICY
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "s3:GetReplicationConfiguration",
        "s3:ListBucket"
      ],
      "Effect": "Allow",
      "Resource": [
        "${aws_s3_bucket.s3_bucket[0].arn}"
      ]
    },
    {
      "Action": [
        "s3:GetObjectVersionForReplication",
        "s3:GetObjectVersionAcl",
         "s3:GetObjectVersionTagging",
         "s3:GetObjectVersion"
      ],
      "Effect": "Allow",
      "Resource": [
        "${aws_s3_bucket.s3_bucket[0].arn}/*"
      ]
    },
    {
      "Action": [
        "s3:ReplicateObject",
        "s3:ReplicateDelete",
        "s3:ReplicateTags"
      ],
      "Effect": "Allow",
      "Resource": "${var.replication_bucket_arn}/*"
    }
  ]
}
POLICY
}

resource "aws_iam_role_policy_attachment" "replication_policy_attachment" {
  count      = var.create && length(var.replication_bucket_arn) != 0 ? 1 : 0
  role       = aws_iam_role.replication_role[0].name
  policy_arn = aws_iam_policy.replication_policy[0].arn
}
</code>```

Body:
I have s3 bucket with bucket policy which deny's all the actions. i wanted to create IAM role to list, put, get object actions. How can i achieve that.

s3-bucket-policy

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "denyInsecureTransport",
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::my-bucket/*",
                "arn:aws:s3:::my-bucket"
            ],
            "Condition": {
                "Bool": {
                    "aws:SecureTransport": "false"
                }
            }
        }
    ]
}

i have created IAM policy to perform actions against this bucket.

IAM Policy

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:*"
            ],
            "Resource": [
                "arn:aws:s3:::my-bucket",
                "arn:aws:s3:::my-bucket/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iam:PassRole"
            ],
            "Resource": [
                "arn:aws:iam::*:role/*"
            ]
        }
    ]
}

with this i am getting access denied error. how to modify this policy to perform s3 bucket actions. any help would be appreciated.

EDITED

module block:

resource "aws_s3_bucket_public_access_block" "bucket_public_access" {
  count  = var.create ? 1 : 0
  bucket = aws_s3_bucket.s3_bucket[0].bucket
  block_public_acls   = true
  block_public_policy = true
}

resource "aws_s3_bucket_policy" "bucket_policy" {
  count  = var.create ? 1 : 0
  bucket = local.bucket_name
  #policy = templatefile(var.bucket_policy_template, { account_number = var.account_number, region = var.region, bucket_name = local.bucket_name })

  policy = data.aws_iam_policy_document.s3_comb_policy[0].json
}

data "aws_iam_policy_document" "policy" {
  count = var.create ? 1 : 0
  statement {
    sid    = "denyInsecureTransport"
    effect = "Deny"

    actions = [
      "s3:*",
    ]

    resources = [
      "arn:aws:s3:::${local.bucket_name}",
      "arn:aws:s3:::${local.bucket_name}/*"

    ]
    principals {
      type        = "*"
      identifiers = ["*"]
    }

    condition {
      test     = "Bool"
      variable = "aws:SecureTransport"
      values = [
        "false"
      ]
    }
  }
  depends_on = [
    aws_s3_bucket.s3_bucket[0],
  ]

}

data "aws_iam_policy_document" "object_lock_policy" {
  count = var.create && var.object_lock ? 1 : 0
  statement {
    sid    = "ObjectLockConfiguration"
    effect = "Deny"
    actions = [
      "s3:BypassGovernanceRetention",
            "s3:PutBucketObjectLockConfiguration",
            "s3:PutObjectLegalHold",
            "s3:PutObjectRetention"
    ]
    resources = [
      "arn:aws:s3:::${local.bucket_name}",
      "arn:aws:s3:::${local.bucket_name}/*"
    ]
    principals {
      type        = "*"
      identifiers = ["*"]
    }
    condition {
      test     = "ArnNotEquals"
      variable = "aws:PrincipalArn"
      values = [
        "arn:aws:iam::${var.account_number}:role/${var.department}-jenkins-assumed-role-${var.environment}"
      ]
    }
  }
  depends_on = [
    aws_s3_bucket.s3_bucket[0],
  ]
}

data "aws_iam_policy_document" "s3_comb_policy" {
  count = var.create ? 1 : 0

  source_policy_documents = compact([
    data.aws_iam_policy_document.policy[0].json,
    var.object_lock ? data.aws_iam_policy_document.object_lock_policy[0].json : "",
    var.additional_policy != null ? var.additional_policy : ""
  ])
}

and also they created one IAM role in the module itself

resource "aws_iam_role" "replication_role" {
  count              = var.create && length(var.replication_bucket_arn) != 0 ? 1 : 0
  name               = "${local.bucket_name}-s3-replication-role"
  permissions_boundary = "arn:aws:iam::${var.account_number}:policy/AGT-IAM-BOUNDARY-BASE"
  assume_role_policy = <<POLICY
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Principal": {
        "Service": "s3.amazonaws.com"
      },
      "Effect": "Allow",
      "Sid": "s3ReplicationAssume"
    }
  ]
}
POLICY
}

resource "aws_iam_policy" "replication_policy" {
  count  = var.create && length(var.replication_bucket_arn) != 0 ? 1 : 0
  name   = "${local.bucket_name}-s3-replication-policy"
  policy = <<POLICY
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "s3:GetReplicationConfiguration",
        "s3:ListBucket"
      ],
      "Effect": "Allow",
      "Resource": [
        "${aws_s3_bucket.s3_bucket[0].arn}"
      ]
    },
    {
      "Action": [
        "s3:GetObjectVersionForReplication",
        "s3:GetObjectVersionAcl",
         "s3:GetObjectVersionTagging",
         "s3:GetObjectVersion"
      ],
      "Effect": "Allow",
      "Resource": [
        "${aws_s3_bucket.s3_bucket[0].arn}/*"
      ]
    },
    {
      "Action": [
        "s3:ReplicateObject",
        "s3:ReplicateDelete",
        "s3:ReplicateTags"
      ],
      "Effect": "Allow",
      "Resource": "${var.replication_bucket_arn}/*"
    }
  ]
}
POLICY
}

resource "aws_iam_role_policy_attachment" "replication_policy_attachment" {
  count      = var.create && length(var.replication_bucket_arn) != 0 ? 1 : 0
  role       = aws_iam_role.replication_role[0].name
  policy_arn = aws_iam_policy.replication_policy[0].arn
}