import datetime
from tkinter import *
from ..app.employees import Employee
from ..app import attendances
from ..data import db_connect
from tkinter import messagebox, filedialog
from tkcalendar import DateEntry
from tkinter import ttk
from tkinter import simpledialog

class CreateMenu:   # Creates the menu bar for the app
    def __init__(self, master=None, cur=None):
        self.master = master
        self.menu_base = Menu(master)
        master.config(menu=self.menu_base)  # Configure the connection between the window and the menu
        self.cur = cur

        self.file_menu = Menu(self.menu_base)
        self.set_file_menu()

        self.report_menu = Menu(self.menu_base)
        self.set_report_menu()

    def set_file_menu(self):
        self.menu_base.add_cascade(label='File', menu=self.file_menu)
        self.file_menu.add_command(label='Add employee', command=self.add_emp)
        self.file_menu.add_command(label='Add employees from file', command=self.add_emp_file)
        self.file_menu.add_separator()
        self.file_menu.add_command(label='Delete employee', command=self.del_emp)
        self.file_menu.add_command(label='Delete employees from file', command=self.del_emp_file)
        self.file_menu.add_separator()
        self.file_menu.add_command(label='Mark attendance', command=self.mark_att)
        self.file_menu.add_separator()
        self.file_menu.add_command(label='Exit', command=self.master.destroy)

    def set_report_menu(self):
        self.menu_base.add_cascade(label='Reports', menu=self.report_menu)
        self.report_menu.add_command(label='Attendance for employee', command=self.att_id_report)
        self.report_menu.add_separator()
        self.report_menu.add_command(label='Attendance by month', command=self.att_by_month)
        self.report_menu.add_command(label='Attendance by dates', command=self.att_by_date)
        self.report_menu.add_separator()
        self.report_menu.add_command(label='Late attendance by date and hour', command=self.att_by_hour)

    def add_emp(self):
        Add_emp_top_window(self.cur)

    def add_emp_file(self):
        add_or_del_emp_file(self.cur, 1)

    def check_entered_id(self, e_id):  # Checks the entered ID and returns prompt + color prompt
        id_exists, message, color = Employee.check_id(self.cur, e_id)
        if color == "blue":
            id_exists = 1
        elif color == "green":
            id_exists = 0
            message = "There is no employee with ID %s" % e_id
        elif color == "black":
            message = "You didn't enter an ID."
        return id_exists, message

    def del_emp(self):
        e_id = simpledialog.askstring("Delete Employee", "Please enter employee ID:")
        correct, message = self.check_entered_id(e_id)
        if correct == 1:
            Employee.delete_employee_manually(self.cur, e_id)
        messagebox.showinfo("Delete Employee", message)

    def del_emp_file(self):
        add_or_del_emp_file(self.cur, 0)

    def mark_att(self):  # Asks for ID, if correct marks an attendance. Else sends a prompt.
        e_id = simpledialog.askstring("Mark Attendance", "Please enter employee ID:")
        correct, message = self.check_entered_id(e_id)
        if correct == 1:
            attendances.mark_attendance(self.cur, e_id)
        else:
            messagebox.showinfo("Mark Attendance", message)

    def att_id_report(self, e_id=None):
        e_id = simpledialog.askstring("Attendance Report", "Please enter employee ID:")
        if e_id is not None:
            correct, message = self.check_entered_id(e_id)
            if correct == 1:
                attendances.attendance_report_by_id(self.cur, e_id)
            else:
                messagebox.showinfo("Attendance Report", message)

    def att_by_month(self):  # User selects month and gets the attendance for that month during last year.
        month = simpledialog.askstring("Attendance report by month", "Please enter a month (1-12):")
        if month is not None:
            test = attendances.month_check(month)
            if test:
                attendances.report_by_month(self.cur, int(month))
            else:
                messagebox.showwarning("Attendance report by month", "You should choose a month using 1-12 numbers.")

    def att_by_date(self):
        Create_report_top_window(self.cur, 'Dates')

    def att_by_hour(self):
        Create_report_top_window(self.cur, 'Hour')

class CreateFrames:  # Creates the frames and widgets that make the app
    def __init__(self, master, cur):
        self.master_frame = master
        self.top_frame = Frame(master, relief=SUNKEN, width=600, height=100, pady=3)
        self.center_frame = Frame(master, width=600, height=400, padx=3, pady=3)
        self.left_frame = Frame(self.center_frame, bg="lightblue", width=300, height=500, padx=3, pady=3)
        self.right_frame = Frame(self.center_frame, bg="lightgray", width=300, height=500, padx=3, pady=3)
        self.master_frame = Frame(master, relief=SUNKEN, width=600, height=100, pady=3)
        self.cur = cur

        self.top_frame.grid(row=0, sticky=NS)
        self.center_frame.grid(row=1, sticky=NSEW)
        self.left_frame.grid(row=0, column=0, sticky=NS)
        self.right_frame.grid(row=0, column=1, sticky=NS)
        self.master_frame.grid(row=2, sticky=NS)

        self.top_frame_widgets()
        self.left_frame_widgets()
        self.right_frame_widgets()
        self.bottom = Bottom_frame_widgets(self.master_frame, self.cur)

        self.master_frame.bind('<FocusIn>', self.del_entry)

    def top_frame_widgets(self):
        main_title = Label(self.top_frame, text="Employee Attendance Management System", font=20, anchor=CENTER)
        self.company_employees = StringVar()
        self.update_emp_num()
        label_emp_num = Label(self.top_frame, textvariable=self.company_employees)

        main_title.grid(row=0, columnspan=3, sticky=EW, padx=10)
        label_emp_num.grid(row=1, columnspan=3, sticky=EW)

        self.master_frame.bind('<FocusIn>', self.update_emp_num)

    def update_emp_num(self, event=None):
        self.emp_num = db_connect.employees_count(self.cur)
        self.company_employees.set('The company has %d employees.' % self.emp_num)
        return

    def left_frame_widgets(self):
        main_title = Label(self.left_frame, text="Employee management", bg="lightblue", font=18, anchor=CENTER)
        self.e_id = StringVar()
        self.entry_id = Entry(self.left_frame, textvariable=self.e_id)
        self.prompt_id = Label(self.left_frame, text="Please enter ID to proceed.", bg="lightblue")
        self.add_button = Button(self.left_frame, text="  Add employee  ", command=self.add_emp, state=DISABLED)
        self.del_button = Button(self.left_frame, text="Delete employee", command=self.del_emp, state=DISABLED)
        self.mark_button = Button(self.left_frame, text="Mark attendance", command=self.mark_att, state=DISABLED)
        self.report_button = Button(self.left_frame, text=" Generate report ", command=self.att_id_report, state=DISABLED)

        self.entry_id.bind('<KeyRelease>', self.id_input_prompt)

        main_title.grid(row=0, columnspan=2, sticky=EW, padx=45, pady=10)
        self.entry_id.grid(row=2, columnspan=2, sticky=EW, padx=60, pady=5)
        self.prompt_id.grid(row=3, columnspan=2, sticky=EW)
        self.add_button.grid(row=4, column=0, sticky=E, padx=5, pady=5)
        self.del_button.grid(row=5, column=0, sticky=E, padx=5, pady=5)
        self.mark_button.grid(row=4, column=1, sticky=W, padx=5, pady=5)
        self.report_button.grid(row=5, column=1, sticky=W, padx=5, pady=5)

    def right_frame_widgets(self):
        title = Label(self.right_frame, text="Multiple Employees", bg="lightgray", font=18, anchor=CENTER)
        entry_label1 = Label(self.right_frame, text="You can add/delete multiple employees\n by providing a file.\n "
                                                    "Please choose the desired action:", bg="lightgray")
        add_button = Button(self.right_frame, text="  Add employees  ", command=self.add_emp_file)
        del_button = Button(self.right_frame, text="Delete employees", command=self.del_emp_file)

        title.grid(row=0, columnspan=2, sticky=EW, padx=60, pady=10)
        entry_label1.grid(row=1, columnspan=2, sticky=EW)
        add_button.grid(row=3, columnspan=2, sticky=EW, padx=60, pady=5)
        del_button.grid(row=4, columnspan=2, sticky=EW, padx=60, pady=5)

    def del_entry(self, event=None):  # Clears the entry after pressing one of the functions
        self.entry_id.delete(0, END)
        self.id_input_prompt()
        if event is None:
            self.bottom.del_entry()

    def id_input_prompt(self, event=None):
        # Checks the input and returns the corresponding massage, color and makes actions available.
        self.prompt_id.destroy()
        self.add_button['state'] = DISABLED
        self.del_button['state'] = DISABLED
        self.mark_button['state'] = DISABLED
        self.report_button['state'] = DISABLED
        new_id, message, color = Employee.check_id(self.cur, self.e_id.get())
        self.prompt_id = Label(self.left_frame, text=message, fg=color, bg="lightblue")
        self.prompt_id.grid(row=3, columnspan=2, sticky=EW, padx=0, pady=0)
        if color == "blue":   # There is an employee with this ID
            self.del_button['state'] = NORMAL
            self.mark_button['state'] = NORMAL
            self.report_button['state'] = NORMAL
        elif color == "green":  # There is no employee with this ID
            self.add_button['state'] = NORMAL

    def add_emp(self):
        Add_emp_top_window(self.cur, str(self.e_id.get()))

    def add_emp_file(self):
        add_or_del_emp_file(self.cur, 1)

    def del_emp(self):
        Employee.delete_employee_manually(self.cur, self.e_id.get())

    def del_emp_file(self):
        add_or_del_emp_file(self.cur, 0)

    def mark_att(self):
        attendances.mark_attendance(self.cur, self.e_id.get())

    def att_id_report(self):
        attendances.attendance_report_by_id(self.cur, self.e_id.get())

class Bottom_frame_widgets(CreateFrames):
    # Creates the bottom frame and also can be called from the menu in a top window
    # for 2 functions: report by dates and report by hour
    def __init__(self, master, cur, top=None, report=None):
        self.top = top
        self.master_frame = master
        self.cur = cur
        self.report = report
        self.generate_report = [0,0,0]

        title = Label(self.master_frame, text="Attendance Reports", font=18, anchor=CENTER)
        clear_button = Button(self.master_frame, text="Clear", command=self.del_entry)
        entry_label_month = Label(self.master_frame, text="Please enter \na month (1-12): ")
        self.month = StringVar()
        self.entry_month = Entry(self.master_frame, textvariable=self.month)
        self.month_button = Button(self.master_frame, text="Generate monthly\n report ", command=self.att_by_month,
                                   state=DISABLED)
        line_label = Label(self.master_frame, text="--------------------------------------------------------------")
        self.entry_label_start_date = Label(self.master_frame, text="Please enter \nstart date: ")
        self.start_date = DateEntry(self.master_frame, date_pattern='d/m/y')
        self.prompt_start_date = Label(self.master_frame, text="")
        entry_label_end_date = Label(self.master_frame, text="End date: ")
        self.end_date = DateEntry(self.master_frame, date_pattern='d/m/y')
        self.dates_button = Button(self.master_frame, text="Generate report\n by dates", command=self.att_by_date,
                                   state=DISABLED)
        or_label = Label(self.master_frame, text="  or        ")
        self.prompt_reports = Label(self.master_frame, text="")
        entry_label_hour = Label(self.master_frame, text="Start hour:\n(hh:mm)")
        self.hour = StringVar()
        self.entry_hour = Entry(self.master_frame, textvariable=self.hour)
        self.hour_button = Button(self.master_frame, text="Generate report by\n hour and date",
                                  command=self.att_by_hour, state=DISABLED)

        self.entry_month.bind('<KeyRelease>', self.month_prompt)
        self.start_date.bind('<<DateEntrySelected>>', self.start_date_input_prompt)
        self.start_date.bind('<FocusOut>', self.start_date_input_prompt)
        self.end_date.bind('<<DateEntrySelected>>', self.end_date_input_prompt)
        self.end_date.bind('<FocusOut>', self.end_date_input_prompt)
        self.entry_hour.bind('<KeyRelease>', self.hour_prompt)

        self.entry_label_start_date.grid(row=3, column=1, sticky=E, padx=5, pady=5)
        self.start_date.grid(row=3, column=2, sticky=EW, padx=5, pady=10)
        self.prompt_start_date.grid(row=3, column=3, sticky=W, padx=5, pady=5)
        self.prompt_reports.grid(row=5, column=2, padx=0, pady=0, sticky=EW)

        if self.report is None or self.report == 'Dates':  # Top window for report by dates or view all
            entry_label_end_date.grid(row=4, column=1, sticky=E, padx=5, pady=5)
            self.end_date.grid(row=4, column=2, sticky=EW, padx=5, pady=5)
            self.dates_button.grid(row=4, column=3, sticky=EW, padx=5, pady=5)

        if self.report is None or self.report == 'Hour':  # Top window for report by date and hour or view all
            entry_label_hour.grid(row=6, column=1, sticky=E, padx=5, pady=5)
            self.entry_hour.grid(row=6, column=2, sticky=W, padx=5, pady=5)
            self.hour_button.grid(row=6, column=3, sticky=EW, padx=5, pady=5)

        if self.report is None:   # View all options
            title.grid(row=0, column=1, columnspan=3, sticky=EW, padx=40, pady=10)
            clear_button.grid(row=0, column=4, sticky=EW, padx=5, pady=10)
            entry_label_month.grid(row=1, column=1, columnspan=1, sticky=E, padx=5, pady=5)
            self.entry_month.grid(row=1, column=2, columnspan=1, sticky=W, padx=5, pady=5)
            self.month_button.grid(row=1, column=3, sticky=EW, padx=5, pady=5)
            line_label.grid(row=2, columnspan=5, sticky=EW, padx=30, pady=10)
            or_label.grid(row=5, column=1, sticky=E, padx=0, pady=8)

    def del_entry(self, event=None):  # Clears the entry after pressing one of the buttons
        self.entry_month.delete(0, END)
        self.month_prompt()
        if event is None:
            self.start_date.set_date(datetime.datetime.now().date())
            self.end_date.set_date(datetime.datetime.now().date())
            self.generate_report = [0,0,0]
            self.check_report()
            self.prompt_reports.destroy()
            self.entry_hour.delete(0, END)

    def month_prompt(self, event=None):  # Checks the month input and makes the button available
        test = attendances.month_check(self.month.get())
        if test:
            self.month_button['state'] = NORMAL
        else:
            self.month_button['state'] = DISABLED

    def att_by_month(self):
        attendances.report_by_month(self.cur, int(self.month.get()))

    def start_date_input_prompt(self, event=None):
        self.prompt_start_date.destroy()
        message = ""
        if self.start_date.get_date() <= datetime.datetime.now().date():
            self.generate_report[0] = 1
        else:
            self.generate_report[0] = 0
            message = "Make sure you \nchoose past date."
        if self.start_date.get_date() > self.end_date.get_date():
            message = "Make sure your end date \n is greater than start date."
            self.generate_report[1] = 0
        else:
            self.generate_report[1] = 1
        self.prompt_start_date = Label(self.master_frame, text=message, fg="red")
        self.prompt_start_date.grid(row=3, column=3, sticky=W, padx=5)
        self.check_report()

    def end_date_input_prompt(self, event=None):
        self.prompt_reports.destroy()
        message = ""
        if self.start_date.get_date() <= self.end_date.get_date() <= datetime.datetime.now().date():
            self.generate_report[1] = 1
            self.generate_report[0] = 1
        else:
            self.generate_report[1] = 0
            message = "Make sure you choose a past date \ngreater than start date."
        self.prompt_reports = Label(self.master_frame, text=message, fg="red")
        self.prompt_reports.grid(row=5, column=2, columnspan=2, sticky=W, padx=5)
        self.check_report()

    def check_report(self):  # Makes buttons available according to the input matrix(generate_report)
        if self.generate_report[0] == 1:
            if self.generate_report[1] == 1:
                self.dates_button['state'] = NORMAL
            else:
                self.dates_button['state'] = DISABLED
            if self.generate_report[2] == 1:
                self.hour_button['state'] = NORMAL
            else:
                self.hour_button['state'] = DISABLED
        else:
            self.dates_button['state'] = DISABLED
            self.hour_button['state'] = DISABLED

    def att_by_date(self):
        attendances.report_by_dates(self.cur, self.start_date.get_date(), self.end_date.get_date())
        if self.report is None:
            self.del_entry()
        else:
            self.top.destroy()

    def hour_prompt(self, event=None):
        self.prompt_reports.destroy()
        test, message = attendances.hour_check(self.hour.get())
        self.generate_report[2] = test
        self.prompt_reports = Label(self.master_frame, text=message, fg="red")
        self.prompt_reports.grid(row=5, column=2, columnspan=2, sticky=W, padx=5)
        self.check_report()

    def att_by_hour(self):
        attendances.report_by_hour(self.cur, self.start_date.get_date(), self.hour.get())
        if self.report is None:
            self.del_entry()
        else:
            self.top.destroy()

class Add_emp_top_window:  # Class for top window used for adding an employee
    def __init__(self, cur, e_id=None):
        self.top = Toplevel()
        w = 450
        h = 300
        sw = (self.top.winfo_screenwidth() - w) / 2
        sh = (self.top.winfo_screenheight() - h) / 2
        self.top.geometry('%dx%d+%d+%d' % (w, h, sw, sh))
        self.top_frame = Frame(self.top, width=w, height=h)
        self.top.title('Adding an employee')

        self.e_id = StringVar()
        self.name = StringVar()
        self.title = StringVar()
        self.phone = StringVar()
        self.birthday = datetime
        self.add_new = [0, 0, 0, 0, 0]

        if e_id is not None:
            self.e_id.set(e_id)
        self.cur = cur

        self.top_window_widgets()

        self.top.mainloop()

    def top_window_widgets(self):
        main_title = Label(self.top_frame, text="Adding a new Employee", font=18, anchor=CENTER)
        label1 = Label(self.top_frame, text="Enter Data:", font=10, bg="lightblue", padx=16, width =15, anchor=W)
        label2 = Label(self.top_frame, text="Annotations:", font=10, bg="lightblue", width=25, anchor=W)

        entry_id = Entry(self.top_frame, textvariable=self.e_id)
        if len(self.e_id.get()) == 9:
            self.prompt_id = Label(self.top_frame, fg="green", text="Let's add the employee")
            self.add_new[0] = 1
        else:
            self.prompt_id = Label(self.top_frame, text="Please enter ID to proceed.")

        entry_name = Entry(self.top_frame, textvariable=self.name)
        self.prompt_name = Label(self.top_frame, text="Please enter Employee Name to proceed.")

        self.title = StringVar()
        self.title.set("")
        drop_title = ttk.Combobox(self.top_frame, value=Employee.TITLES, textvariable=self.title, state="readonly")
        self.prompt_title = Label(self.top_frame, text="Please choose Title to proceed.")

        self.entry_birthday = DateEntry(self.top_frame, date_pattern='d/m/y')
        self.prompt_birthday = Label(self.top_frame, text="Please enter Birth Date to proceed.")

        entry_phone = Entry(self.top_frame, textvariable=self.phone)
        self.prompt_phone = Label(self.top_frame, text="Please enter Phone to proceed.")

        self.add_button = Button(self.top_frame, text=" Add employee ", command=self.add_emp, state=DISABLED)
        self.cancel_button = Button(self.top_frame, text="   Cancel   ", command=self.top.destroy)

        entry_id.bind('<KeyRelease>', self.id_input_prompt)
        entry_name.bind('<KeyRelease>', self.name_input_prompt)
        drop_title.bind('<<ComboboxSelected>>', self.title_input_prompt)
        self.entry_birthday.bind('<<DateEntrySelected>>', self.birthday_input_prompt)
        self.entry_birthday.bind('<FocusOut>', self.birthday_input_prompt)
        entry_phone.bind('<KeyRelease>', self.phone_input_prompt)

        self.top_frame.grid(row=0, sticky=NS)
        main_title.grid(row=0, columnspan=2, sticky=EW, padx=45, pady=10)
        label1.grid(row=1, sticky=W, pady=5)
        label2.grid(row=1, column=1, sticky=W, pady=5)

        entry_id.grid(row=2, sticky=EW, padx=20, pady=5)
        self.prompt_id.grid(row=2, column=1, sticky=W)
        entry_name.grid(row=3, sticky=EW, padx=20, pady=5)
        self.prompt_name.grid(row=3, column=1, sticky=W)
        drop_title.grid(row=4, sticky=EW, padx=20, pady=5)
        self.prompt_title.grid(row=4, column=1, sticky=W)
        self.entry_birthday.grid(row=5, sticky=EW, padx=20, pady=5)
        self.prompt_birthday.grid(row=5, column=1, sticky=W)
        entry_phone.grid(row=6, sticky=EW, padx=20, pady=5)
        self.prompt_phone.grid(row=6, column=1, sticky=W)
        self.add_button.grid(row=7, column=0, sticky=E, padx=5, pady=10)
        self.cancel_button.grid(row=7, column=1, sticky=W, padx=5, pady=10)

    def add_emp(self):
        db_connect.add_employee(self.cur, Employee(self.e_id.get(), self.name.get(), self.title.get(),
                                                   self.phone.get(), self.birthday))
        messagebox.showinfo("Employee added", "Added an employee with ID %s." % self.e_id.get())
        self.top.destroy()

    def can_add_amp(self):
        if sum(self.add_new) == 5:
            self.add_button['state'] = NORMAL
        else:
            self.add_button['state'] = DISABLED

    def id_input_prompt(self, event):
        self.prompt_id.destroy()
        self.add_new[0], message, color = Employee.check_id(self.cur, self.e_id.get())
        self.prompt_id = Label(self.top_frame, text=message, fg=color)
        self.prompt_id.grid(row=2, column=1, sticky=W)
        self.can_add_amp()

    def name_input_prompt(self, event):
        self.prompt_name.destroy()
        self.add_new[1], message = Employee.check_name(self.name.get())
        self.prompt_name = Label(self.top_frame, fg="red", text=message)
        self.prompt_name.grid(row=3, column=1, sticky=W)
        self.can_add_amp()

    def title_input_prompt(self, event):
        if self.title.get() != "":
            self.add_new[2] = 1
            self.prompt_title.destroy()
        self.can_add_amp()

    def birthday_input_prompt(self, event):
        self.birthday = self.entry_birthday.get_date()
        self.add_new[3], message = Employee.check_birthday(self.birthday)
        if self.birthday is not None:
            self.prompt_birthday.destroy()
            self.prompt_birthday = Label(self.top_frame, fg="red", text=message)
            self.prompt_birthday.grid(row=5, column=1, sticky=W)
        self.can_add_amp()

    def phone_input_prompt(self, event):
        self.prompt_phone.destroy()
        self.add_new[4], message = Employee.check_phone(self.phone.get())
        self.prompt_phone = Label(self.top_frame, fg="red", text=message)
        self.prompt_phone.grid(row=6, column=1, sticky=W)
        self.can_add_amp()

class Create_report_top_window:  # Class for top window used for 2 report functions (by dates/by hour)
    def __init__(self, cur, report=None):
        self.top = Toplevel()
        w = 450
        h = 300
        sw = (self.top.winfo_screenwidth() - w) / 2
        sh = (self.top.winfo_screenheight() - h) / 2
        self.top.geometry('%dx%d+%d+%d' % (w, h, sw, sh))
        self.top_frame = Frame(self.top, width=w, height=h)
        self.top.title(f'Report by {report}')

        self.top_frame.grid(row=0, sticky=NS)

        self.report = report
        self.cur = cur

        Bottom_frame_widgets(self.top_frame, self.cur, self.top, self.report)

        self.top.mainloop()

def add_or_del_emp_file(cur, add_emp):  # Function used for the adding/deleting employees
    file_path = filedialog.askopenfilename()
    if len(file_path) > 1:
        if add_emp == 1:
            Employee.add_employee_from_file(cur, file_path)
        else:
            Employee.delete_employee_from_file(cur, file_path)
    else:
        if add_emp == 1:
            title = "Add Employees by File"
        else:
            title = "Delete Employees by File"
        messagebox.showwarning(title, "No file was selected.")


import os
import re
import csv
import subprocess
import tqdm
from itertools import product
from datetime import datetime, timedelta, timezone

def get_date_str():
    return datetime.now(timezone(timedelta(hours=+9), "JST")).strftime("%Y-%m-%d-%H-%M-%S")

def read_result(filename):
    r_solved= re.compile(r"solved=(\d+)")
    r_service_time = re.compile(r"service_time=(.+)")
    r_makespan = re.compile(r"makespan=(\d+)")
    r_comp_time = re.compile(r"comp_time=(\d+)")

    solved, service_time, makespan, comp_time = -1, -1, -1, -1
    with open(result_file, 'r') as f_read:
        for row in f_read:
            m = re.match(r_solved, row)
            if m:
                solved = int(m.group(1))
            m = re.match(r_service_time, row)
            if m:
                service_time = float(m.group(1))
            m = re.match(r_makespan, row)
            if m:
                makespan = int(m.group(1))
            m = re.match(r_comp_time, row)
            if m:
                comp_time = int(m.group(1))
    return solved, service_time, makespan, comp_time

MAX_TIMESTEP = 3000
MAX_COMP_TIME = 30000
SOLVERS = [ "PIBT", "TP", ]
MAP_NAMES = [ "warehouse.map", ]
TASK_FREQS = [ 0.2, 0.5, 1, 2, 5, 10 ]
NUM_AGENTS = [ 10, 20, 30, 40, 50 ]
TASK_NUM = 500
REPEAT_NUM = 100

if __name__ == '__main__':
    ins_file = "local/ins.txt"
    result_file = "local/result.txt"

    command = os.path.join("..", "build", "mapd")
    output_dir = os.path.join("..", "..", "data", get_date_str())
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)
    output_file = os.path.join(output_dir, "result.csv")

    # write header
    with open(output_file, "w") as f:
        writer = csv.writer(f, lineterminator='\n')
        writer.writerow([
            "map_name", "seed", "num_agents", "solver", "task_frequency", "task_num",
            "solved", "service_time", "makespan", "comp_time",
        ])

    for solver, map_name, task_frequency, num_agents, seed in tqdm.tqdm(product(
            SOLVERS, MAP_NAMES, TASK_FREQS, NUM_AGENTS, range(REPEAT_NUM)
    )):
        with open(ins_file, 'w') as f_write:
            f_write.write(f'map_file={map_name}\n')
            f_write.write(f'agents={num_agents}\n')
            f_write.write(f'seed={seed}\n')
            f_write.write(f'task_frequency={task_frequency}\n')
            f_write.write(f'task_num={TASK_NUM}\n')
            f_write.write(f'max_timestep={MAX_TIMESTEP}\n')
            f_write.write(f'max_comp_time={MAX_COMP_TIME}\n')
            f_write.write('specify_pickup_deliv_locs=1\n')

        # solve
        subprocess.run(f"{command} -i {ins_file} -o {result_file} -s {solver} -d -L", shell=True)

        # read result
        res = read_result(result_file)

        # write result to csv
        with open(output_file, "a") as f:
            writer = csv.writer(f, lineterminator='\n')
            writer.writerow([map_name, seed, num_agents, solver,
                             task_frequency, TASK_NUM, *res])


import sys
input = sys.stdin.readline
s = set()
n, m = map(int, input().split())
answer = 0
for _ in range(n):
    s.add(input())
for _ in range(m):
    t = set()
    t.add(input())
    if len(s.intersection(t)):
        answer += 1
print(answer)


import numpy as np
import tensorflow as tf

# Weight (row=4 x col=2).
a = tf.Variable(np.random.rand(4, 2))

# Bias (row=4 x col=1).
b = tf.Variable(np.random.rand(4, 1))

# Input(x) (row=2 x col=1).
x = tf.compat.v1.placeholder(tf.float64, shape=(2, 1))

# Output(y) (row=4 x col=1).
y = tf.matmul(a, x) + b

with tf.Session() as sess:
    # Initialize variable.
    init = tf.global_variables_initializer()
    sess.run(init)

    # Make batch.
    batch = []
    for i in range(3):
        x_value = np.random.rand(2, 1)
        batch.append(x_value)

    # Execute culculation.
    y_outputs = []
    for x_value in batch:
        y_output = sess.run(y, feed_dict={x: x_value})
        y_outputs.append(y_output)

    y_output = np.array(y_outputs)
    print(y_output.shape)  # Will be (3, 4, 1)


from elegantrl.agents.AgentSAC import AgentSAC
from elegantrl.agents.net import Critic, ActorSAC, ActorFixSAC, CriticREDQ
import torch
import numpy as np
from copy import deepcopy

class AgentREDQ(AgentSAC):  # [ElegantRL.2021.11.11]
    """
    Bases: ``AgentBase``

    Randomized Ensemble Double Q-learning algorithm. “Randomized Ensembled Double Q-Learning: Learning Fast Without A Model”. Xinyue Chen et al.. 2021.

    :param net_dim[int]: the dimension of networks (the width of neural networks)
    :param state_dim[int]: the dimension of state (the number of state vector)
    :param action_dim[int]: the dimension of action (the number of discrete action)
    :param reward_scale: scale the reward to get a appropriate scale Q value
    :param gamma: the discount factor of Reinforcement Learning
    :param learning_rate: learning rate of optimizer
    :param if_per_or_gae: PER (off-policy) or GAE (on-policy) for sparse reward
    :param env_num: the env number of VectorEnv. env_num == 1 means don't use VectorEnv
    :param gpu_id: the gpu_id of the training device. Use CPU when cuda is not available.
    :param G: Update to date ratio
    :param M: subset size of critics
    :param N: ensemble number of critics
    """

    def __init__(self, net_dim, state_dim, action_dim, gpu_id=0, args=None):
        self.ClassCri = Critic
        self.get_obj_critic = self.get_obj_critic_raw
        self.ClassAct = ActorSAC
        self.if_use_cri_target = True
        self.if_use_act_target = False
        self.alpha_log = None
        self.alpha_optim = None
        self.target_entropy = None
        self.obj_critic = (-np.log(0.5)) ** 0.5  # for reliable_lambda

        self.act_class = getattr(self, "act_class", ActorFixSAC)
        self.cri_class = getattr(self, "cri_class", CriticREDQ)

        super().__init__(net_dim, state_dim, action_dim, gpu_id, args)
        self.obj_c = (-np.log(0.5)) ** 0.5  # for reliable_lambda

    def init(
        self,
        net_dim=256,
        state_dim=8,
        action_dim=2,
        reward_scale=1.0,
        gamma=0.99,
        learning_rate=3e-4,
        if_per_or_gae=False,
        env_num=1,
        gpu_id=0,
        G=20,
        M=2,
        N=10,
    ):
        self.gamma = gamma
        self.state_dim = state_dim
        self.action_dim = action_dim
        self.reward_scale = reward_scale
        self.traj_list = [[] for _ in range(env_num)]
        self.G = G
        self.M = M
        self.N = N
        self.device = torch.device(
            f"cuda:{gpu_id}" if (torch.cuda.is_available() and (gpu_id >= 0)) else "cpu"
        )
        self.cri_list = [
            self.ClassCri(net_dim, state_dim, action_dim).to(self.device)
            for i in range(self.N)
        ]
        self.act = self.ClassAct(net_dim, state_dim, action_dim).to(self.device)
        self.cri_target_list = [deepcopy(self.cri_list[i]) for i in range(N)]
        self.cri_optim_list = [
            torch.optim.Adam(self.cri_list[i].parameters(), learning_rate)
            for i in range(self.N)
        ]
        self.act_optim = torch.optim.Adam(self.act.parameters(), learning_rate)
        assert isinstance(if_per_or_gae, bool)
        if env_num == 1:
            self.explore_env = self.explore_one_env
        else:
            self.explore_env = self.explore_vec_env
        self.alpha_log = torch.zeros(
            1, requires_grad=True, device=self.device
        )  # trainable parameter
        self.alpha_optim = torch.optim.Adam([self.alpha_log], lr=learning_rate)
        self.target_entropy = np.log(action_dim)
        self.criterion = torch.nn.MSELoss()

    def get_obj_critic_raw(self, buffer, batch_size):
        with torch.no_grad():
            reward, mask, action, state, next_s = buffer.sample_batch(batch_size)

            next_a, next_log_prob = self.act_target.get_action_logprob(
                next_s
            )  # stochastic policy
            next_q = self.cri_target.get_q_min(next_s, next_a)

            alpha = self.alpha_log.exp().detach()
            q_label = reward + mask * (next_q + next_log_prob * alpha)
        qs = self.cri.get_q_values(state, action)
        obj_critic = self.criterion(qs, q_label * torch.ones_like(qs))
        return obj_critic, state

    def get_obj_critic_per(self, buffer, batch_size):
        with torch.no_grad():
            reward, mask, action, state, next_s, is_weights = buffer.sample_batch(
                batch_size
            )

            next_a, next_log_prob = self.act_target.get_action_logprob(
                next_s
            )  # stochastic policy
            next_q = self.cri_target.get_q_min(next_s, next_a)

            alpha = self.alpha_log.exp().detach()
            q_label = reward + mask * (next_q + next_log_prob * alpha)
        qs = self.cri.get_q_values(state, action)
        td_error = self.criterion(qs, q_label * torch.ones_like(qs)).mean(dim=1)
        obj_critic = (td_error * is_weights).mean()

        buffer.td_error_update(td_error.detach())
        return obj_critic, state

    def get_obj_critic_raw_(self, buffer, batch_size, alpha):
        """
        Calculate the loss of networks with **uniform sampling**.

        :param buffer: the ReplayBuffer instance that stores the trajectories.
        :param batch_size: the size of batch data for Stochastic Gradient Descent (SGD).
        :param alpha: the trade-off coefficient of entropy regularization.
        :return: the loss of the network and states.
        """
        with torch.no_grad():
            batch = buffer.sample_batch(batch_size)
            state = torch.Tensor(batch["obs1"]).to(self.device)
            next_s = torch.Tensor(batch["obs2"]).to(self.device)
            action = torch.Tensor(batch["acts"]).to(self.device)
            reward = torch.Tensor(batch["rews"]).unsqueeze(1).to(self.device)
            mask = torch.Tensor(batch["done"]).unsqueeze(1).to(self.device)
            # state, next_s, actions, reward, mask = buffer.sample_batch(batch_size)
            # print(batch_size,reward.shape,mask.shape,action.shape, state.shape, next_s.shape)
            next_a, next_log_prob = self.act.get_action_logprob(
                next_s
            )  # stochastic policy
            g = torch.Generator()
            g.manual_seed(torch.randint(high=10000000, size=(1,))[0].item())
            a = torch.randperm(self.N, generator=g)
            # a = np.random.choice(self.N, self.M, replace=False)
            # print(a[:M])
            q_tmp = [self.cri_target_list[a[j]](next_s, next_a) for j in range(self.M)]
            q_prediction_next_cat = torch.cat(q_tmp, 1)
            min_q, min_indices = torch.min(q_prediction_next_cat, dim=1, keepdim=True)
            next_q_with_log_prob = min_q - alpha * next_log_prob
            y_q = reward + (1 - mask) * self.gamma * next_q_with_log_prob
        q_values = [
            self.cri_list[j](state, action) for j in range(self.N)
        ]  # todo ensemble
        q_values_cat = torch.cat(q_values, dim=1)
        y_q = y_q.expand(-1, self.N) if y_q.shape[1] == 1 else y_q
        obj_critic = self.criterion(q_values_cat, y_q) * self.N
        return obj_critic, state
        # return y_q, state,action

    def select_actions_(self, state, size, env):
        """
        Select continuous actions for exploration

        :param state: states.shape==(batch_size, state_dim, )
        :return: actions.shape==(batch_size, action_dim, ),  -1 < action < +1
        """
        state = state.to(self.device)
        actions = self.act.get_action(state)
        return actions.detach().cpu()

    def cri_multi_train_(self, k):
        q_values = self.cri_list[k](self.state, self.action)
        obj = self.criterion(q_values, self.y_q)
        self.cri_optim_list[k].zero_grad()
        obj.backward()
        self.cri_optim_list[k].step()

    def update_net_(self, buffer, batch_size, soft_update_tau):
        # buffer.update_now_len()
        """
        Update the neural networks by sampling batch data from ``ReplayBuffer``.

        :param buffer: the ReplayBuffer instance that stores the trajectories.
        :param batch_size: the size of batch data for Stochastic Gradient Descent (SGD).
        :param soft_update_tau: the soft update parameter.
        :return: a tuple of the log information.
        """
        for i in range(self.G):
            alpha = self.alpha_log.cpu().exp().item()
            """objective of critic (loss function of critic)"""
            obj_critic, state = self.get_obj_critic(buffer, batch_size, alpha)
            # self.y_q, self.state,self.action = self.get_obj_critic(buffer, batch_size, alpha)
            for q_i in range(self.N):
                self.cri_optim_list[q_i].zero_grad()
            obj_critic.backward()
            if ((i + 1) % self.G == 0) or i == self.G - 1:
                a_noise_pg, logprob = self.act.get_action_logprob(
                    state
                )  # policy gradient
                """objective of alpha (temperature parameter automatic adjustment)"""
                cri_tmp = []
                for j in range(self.N):
                    self.cri_list[j].requires_grad_(False)
                    cri_tmp.append(self.cri_list[j](state, a_noise_pg))
                q_value_pg = torch.cat(cri_tmp, 1)
                q_value_pg = torch.mean(q_value_pg, dim=1, keepdim=True)
                obj_actor = (-q_value_pg + logprob * alpha).mean()  # todo ensemble
                self.act_optim.zero_grad()
                obj_actor.backward()
                for j in range(self.N):
                    self.cri_list[j].requires_grad_(True)
                obj_alpha = -(self.alpha_log * (logprob - 1).detach()).mean()
                self.optim_update(self.alpha_optim, obj_alpha)
            for q_i in range(self.N):
                self.cri_optim_list[q_i].step()
            if ((i + 1) % self.G == 0) or i == self.G - 1:
                self.act_optim.step()
            for q_i in range(self.N):
                self.soft_update(
                    self.cri_target_list[q_i], self.cri_list[q_i], soft_update_tau
                )
        return obj_actor, alpha


__author__ = 'Thomas Rampelberg'
__author_email__ = 'thomas@saunter.org'

from django.utils import simplejson as json
from google.appengine.ext import webapp
import logging
import urlparse

class JankyMiddleware(object):
    """WSGI middleware that adds janky support."""

    tmpl = """

"""

    def __init__(self, app):
        self.app = app

    def __call__(self, environ, start_response):
        def my_start_response(status, headers, exc_info=None):
            write = start_response(status, headers, exc_info)
            def my_write(body):
                if not body: return
                origin = webapp.Request(environ).get('_origin')
                if origin:
                    body = self.tmpl % {
                        'resp': json.dumps(body),
                        'origin': json.dumps(urlparse.urljoin(
                                webapp.Request(environ).get('_origin'),
                                '/janky.html'))
                        }
                write(body)
            return my_write
        return self.app(environ, my_start_response)


from PyQt5.QtCore import QObject, pyqtSignal, pyqtSlot, QJsonValue
import requests
import platform

class UpdateChecker(QObject):
    showUpdate = pyqtSignal(QJsonValue, arguments='infos')

    def __init__(self) -> None:
        super().__init__()

        # Actual version
        with open('./version.txt') as version:
            self.__VERSION__  = version.read()
            version.close()
        self.isUpdate = True

    @pyqtSlot()
    def checkUpdate(self):
        # GitHub API url
        gitHubApiUrl = 'https://api.github.com/repos/HighEloDevs/Analysis-Tool-for-Undergrad-Students/releases/latest'
        response = requests.get(gitHubApiUrl)

        if response.status_code == 200:
            infos = response.json()
            version = infos['tag_name']
            if version != self.__VERSION__:
                self.showUpdate.emit(QJsonValue.fromVariant(infos))

    @pyqtSlot(result=str)
    def getVersion(self):
        return 'v' + self.__VERSION__

    @pyqtSlot(result=str)
    def getOS(self):
        return platform.system()
        # return 'Darwin'


import collections
import contextlib
import functools
import logging
import numbers
import sys
import threading
from datetime import timedelta

import torch
import torch.distributed as dist

from . import (
    RpcBackendOptions,
    WorkerInfo,
    _cleanup_python_rpc_handler,
    _delete_all_user_rrefs,
    _destroy_rref_context,
    _get_current_rpc_agent,
    _invoke_remote_builtin,
    _invoke_remote_python_udf,
    _invoke_remote_torchscript,
    _invoke_rpc_builtin,
    _invoke_rpc_python_udf,
    _invoke_rpc_torchscript,
    _is_current_rpc_agent_set,
    _reset_current_rpc_agent,
    _set_and_start_rpc_agent,
    _set_rpc_timeout,
    backend_registry,
)
from .internal import (
    PythonUDF,
    RPCExecMode,
    _internal_rpc_pickler,
    _start_record_function,
)

logger = logging.getLogger(__name__)

# NB: Ignoring RRef leaks during shutdown. Without this, applications have to
# make sure there is no references to any RRef in the application code and
# Python GC has done its job to delete those RRefs. This is could result in bad
# debugging experiences especially when for large applications. Therefore, by
# default, we are going to ignore RRef leaks during shutdown. This is usually
# fine as shutdown means applications have done training and no longer care
# about states.
#
# To enable RRef leak checking, set this _ignore_rref_leak to False
_ignore_rref_leak = True
_default_pickler = _internal_rpc_pickler

@contextlib.contextmanager
def _use_rpc_pickler(rpc_pickler):
    r"""
    rpc_pickler: (.internal._InternalRPCPickler) Overrides the default RPC pickler
    """
    global _default_pickler
    _default_pickler = rpc_pickler
    try:
        yield
    finally:
        _default_pickler = _internal_rpc_pickler

def _require_initialized(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        if not _is_current_rpc_agent_set():
            raise RuntimeError(
                "RPC has not been initialized. Call "
                "torch.distributed.rpc.init_rpc first."
            )
        return func(*args, **kwargs)

    return wrapper

class WaitAllWorkersStates(object):
    def __init__(self):
        # Each `intent_worker_names` is an empty set at beginning.
        # It's only used by leader worker. Leader worker is user-specified or
        # elected as the first worker in a sorted worker name list.
        # Whenever there is a worker showing shutdown intention to the leader, by
        # calling `_wait_all_workers()`, the leader adds this worker's name to the set.
        # The leader also adds itself's name to the set on calling
        # `_wait_all_workers()`. We need this because, we confine `_wait_all_workers()`
        # to be called only once, by examing if leader's name has been added to the set.
        self.intent_worker_names = set()
        # Once `intent_worker_names == _ALL_WORKER_NAMES`,
        # we flip `_SHUTDOWN_PROCEED_SIGNAL` on the leader, and leader will send RPCs
        # to follower workers to flip their `_SHUTDOWN_PROCEED_SIGNAL`s.
        self.proceed_signal = threading.Event()

# States used by `def _wait_all_workers()`.
# `_ALL_WORKER_NAMES` is initialized on initiaizing RPC layer.
_ALL_WORKER_NAMES = None
_wait_all_workers_dict_lock = threading.Lock()
_wait_all_workers_sequence_id = 0
_wait_all_workers_sequence_id_to_states = collections.defaultdict(WaitAllWorkersStates)

def _on_leader_follower_report_shutdown_intent(sequence_id, worker_name):
    assert (
        worker_name in _ALL_WORKER_NAMES
    ), "{worker_name} is not expected by leader.".format(worker_name=worker_name)
    intent_worker_names = _wait_all_workers_sequence_id_to_states[
        sequence_id
    ].intent_worker_names
    assert (
        worker_name not in intent_worker_names
    ), "{worker_name} reported intent sequence id {sequence_id} twice. ".format(
        worker_name=worker_name, sequence_id=sequence_id
    )
    intent_worker_names.add(worker_name)
    if _ALL_WORKER_NAMES == intent_worker_names:
        _set_proceed_shutdown_signal(sequence_id)

def _set_proceed_shutdown_signal(sequence_id):
    proceed_signal = _wait_all_workers_sequence_id_to_states[sequence_id].proceed_signal
    assert (
        not proceed_signal.is_set()
    ), "Termination signal sequence id {} got set twice.".format(
        sequence_id=sequence_id
    )
    proceed_signal.set()

@_require_initialized
def _wait_all_workers():
    r"""
    Block until all local and remote RPC processes reach this method and wait
    for all outstanding work to complete. Every RPC process must call this
    method before exit to perform a graceful shutdown. This should be used to
    terminate the RPC framework, and there is no guarantee that the RPC
    framework will work after this method returns.
    """
    assert (
        _ALL_WORKER_NAMES is not None
    ), "`_ALL_WORKER_NAMES` is not initialized for `def _wait_all_workers`."
    leader_worker_name = sorted(_ALL_WORKER_NAMES)[0]

    self_worker_name = _get_current_rpc_agent().get_worker_info().name

    global _wait_all_workers_sequence_id
    with _wait_all_workers_dict_lock:
        sequence_id = _wait_all_workers_sequence_id
        _wait_all_workers_sequence_id += 1

    is_leader_worker = leader_worker_name == self_worker_name

    # Phase 1: Followers send intents.
    # All followers report intents to the leader.
    if is_leader_worker:
        _on_leader_follower_report_shutdown_intent(sequence_id, self_worker_name)
    else:
        rpc_sync(
            leader_worker_name,
            _on_leader_follower_report_shutdown_intent,
            args=(sequence_id, self_worker_name,),
        )

    proceed_signal = _wait_all_workers_sequence_id_to_states[
        sequence_id
    ].proceed_signal
    proceed_signal.wait()

    # Phase 2: Leader asks followers to proceed.
    # Leader's signal is the first to be unblocked,
    # after receiving all followers' intents.
    if is_leader_worker:
        # The leader sends out proceeed signals to all followers.
        timeout = timedelta(seconds=5)
        _set_rpc_timeout(timeout)
        worker_name_to_response_future_dict = dict()
        for follower_worker_name in _ALL_WORKER_NAMES - {leader_worker_name}:
            fut = rpc_async(follower_worker_name, _set_proceed_shutdown_signal, args=(sequence_id,))
            worker_name_to_response_future_dict[follower_worker_name] = fut
        for follower_worker_name, fut in worker_name_to_response_future_dict.items():
            try:
                fut.wait()
            except RuntimeError as ex:
                logger.error(
                    "{worker_name} failed to respond to 'Shutdown Proceed.' request in {timeout}".format(
                        worker_name=follower_worker_name, timeout=timeout
                    )
                )

@_require_initialized
def shutdown(graceful=True):
    r"""
    Perform a shutdown of the RPC agent, and then destroy the RPC agent. This
    stops the local agent from accepting outstanding requests, and shuts
    down the RPC framework by terminating all RPC threads. If ``graceful=True``,
    this will block until all local and remote RPC processes reach this method
    and wait for all outstanding work to complete. Otherwise, if
    ``graceful=False``, this is a local shutdown, and it does not wait for other
    RPC processes to reach this method.

    Arguments:
        graceful (bool): Whether to do a graceful shutdown or not. If True,
                         this will 1) wait until there is no pending system
                         messages for ``UserRRefs`` and delete them; 2) block
                         until all local and remote RPC processes have reached
                         this method and wait for all outstanding work to
                         complete.

    Example::
        Make sure that ``MASTER_ADDRESS`` and ``MASTER_PORT`` are set properly
        on both workers. Refer to :meth:`~torch.distributed.init_process_group`
        API for more details. For example,

        >>> export MASTER_ADDRESS=localhost
        >>> export MASTER_port=5678

        Then run the following code in two different processes:

        >>> # On worker 0:
        >>> import torch
        >>> import torch.distributed.rpc as rpc
        >>> rpc.init_rpc("worker0", rank=0, world_size=2)
        >>> # do some work
        >>> result = rpc.rpc_sync("worker1", torch.add, args=(torch.ones(1), 1))
        >>> # ready to shutdown
        >>> rpc.shutdown()

        >>> # On worker 1:
        >>> import torch.distributed.rpc as rpc
        >>> rpc.init_rpc("worker1", rank=1, world_size=2)
        >>> # wait for worker 0 to finish work, and then shutdown.
        >>> rpc.shutdown()
    """
    if graceful:
        _wait_all_workers()
        _delete_all_user_rrefs()
        _get_current_rpc_agent().join()
    try:
        # This raises a `TORCH_CHECK()` exception on RRef leak detected.
        _destroy_rref_context(_ignore_rref_leak)
    finally:
        _get_current_rpc_agent().shutdown()
        # clean up python rpc handler in shutdown(), see comments in
        # PythonRpcHandler::cleanup(), call it in python API because the
        # cleanup() function has python dependency, it assumes python
        # interpreter exists.
        # No matter if RRef leak exception is raised, this clean-up code
        # must run to avoid destruction segfault in Python 3.5.
        _cleanup_python_rpc_handler()
        _reset_current_rpc_agent()

# TODO: add a context manager to wrap _init_rpc_backend and shutdown
def _init_rpc_backend(
    backend=backend_registry.BackendType.PROCESS_GROUP,
    store=None,
    name=None,
    rank=-1,
    world_size=-1,
    rpc_backend_options=None,
):

    if sys.version_info < (3, 0):
        raise RuntimeError("RPC package does not support Python2.")

    _validate_rpc_args(backend, store, name, rank, world_size, rpc_backend_options)

    if _is_current_rpc_agent_set():
        raise RuntimeError("RPC is already initialized")

    # Initialize RPC.
    rpc_agent = backend_registry.init_backend(
        backend,
        store=store,
        name=name,
        rank=rank,
        world_size=world_size,
        rpc_backend_options=rpc_backend_options,
    )

    worker_infos = rpc_agent.get_worker_infos()
    global _ALL_WORKER_NAMES
    _ALL_WORKER_NAMES = {worker_info.name for worker_info in worker_infos}

    _set_and_start_rpc_agent(rpc_agent)

@_require_initialized
def get_worker_info(worker_name=None):
    r"""
    Get :class:`~torch.distributed.rpc.WorkerInfo` of a given worker name.
    Use this :class:`~torch.distributed.rpc.WorkerInfo` to avoid passing an
    expensive string on every invocation.

    Arguments:
        worker_name (str): the string name of a worker. If ``None``, return the
                           the id of the current worker. (default ``None``)

    Returns:
        :class:`~torch.distributed.rpc.WorkerInfo` instance for the given
        ``worker_name`` or :class:`~torch.distributed.rpc.WorkerInfo` of the
        current worker if ``worker_name`` is ``None``.
    """
    if worker_name:
        return _get_current_rpc_agent().get_worker_info(worker_name)
    else:
        return _get_current_rpc_agent().get_worker_info()

def _to_worker_info(name_or_info):
    if isinstance(name_or_info, WorkerInfo):
        return name_or_info
    elif isinstance(name_or_info, str):
        return get_worker_info(name_or_info)
    else:
        raise ValueError("Cannot get WorkerInfo from name {}".format(name_or_info))

def _validate_rpc_args(backend, store, name, rank, world_size, rpc_backend_options):
    type_mapping = {
        backend: backend_registry.BackendType,
        store: dist.Store,
        name: str,
        rank: numbers.Integral,
        world_size: numbers.Integral,
        rpc_backend_options: RpcBackendOptions,
    }
    for arg, arg_type in type_mapping.items():
        if not isinstance(arg, arg_type):
            raise RuntimeError(
                "Argument {} must be of type {} but got type {}".format(
                    arg, arg_type, type(arg)
                )
            )

@_require_initialized
def remote(to, func, args=None, kwargs=None):
    r"""
    Make a remote call to run ``func`` on worker ``to`` and return an
    :class:`~torch.distributed.rpc.RRef` to the result value immediately.
    Worker ``to`` will be the owner of the returned
    :class:`~torch.distributed.rpc.RRef`, and the worker calling ``remote`` is
    a user. The owner manages the global reference count of its
    :class:`~torch.distributed.rpc.RRef`, and the owner
    :class:`~torch.distributed.rpc.RRef` is only destructed when globally there
    are no living references to it.

    Arguments:
        to (str or WorkerInfo): id or name of the destination worker.
        func (callable): a callable function, such as Python callables, builtin
                         operators (e.g. :meth:`~torch.add`) and annotated
                         TorchScript functions.
        args (tuple): the argument tuple for the ``func`` invocation.
        kwargs (dict): is a dictionary of keyword arguments for the ``func``
                       invocation.

    Returns:
        A user :class:`~torch.distributed.rpc.RRef` instance to the result
        value. Use the blocking API :meth:`torch.distributed.rpc.RRef.to_here`
        to retrieve the result value locally.

    .. warning ::
        Using GPU tensors as arguments or return values of ``func`` is not
        supported since we don't support sending GPU tensors over the wire. You
        need to explicitly copy GPU tensors to CPU before using them as
        arguments or return values of ``func``.

    .. warning ::
        The ``remote`` API does not copy storages of argument tensors until
        sending them over the wire, which could be done by a different thread
        depending on the RPC backend type. The caller should make sure that the
        contents of those tensors stay intact until the returned RRef is
        confirmed by the owner, which can be checked using the
        :meth:`torch.distributed.rpc.RRef.confirmed_by_owner` API.

    Example::
        Make sure that ``MASTER_ADDRESS`` and ``MASTER_PORT`` are set properly
        on both workers. Refer to :meth:`~torch.distributed.init_process_group`
        API for more details. For example,

        >>> export MASTER_ADDRESS=localhost
        >>> export MASTER_port=5678

        Then run the following code in two different processes:

        >>> # On worker 0:
        >>> import torch
        >>> import torch.distributed.rpc as rpc
        >>> rpc.init_rpc("worker0", rank=0, world_size=2)
        >>> rref1 = rpc.remote("worker1", torch.add, args=(torch.ones(2), 3))
        >>> rref2 = rpc.remote("worker1", torch.add, args=(torch.ones(2), 1))
        >>> x = rref1.to_here() + rref2.to_here()
        >>> rpc.shutdown()

        >>> # On worker 1:
        >>> import torch.distributed.rpc as rpc
        >>> rpc.init_rpc("worker1", rank=1, world_size=2)
        >>> rpc.shutdown()

        Below is an example of running a TorchScript function using RPC.

        >>> # On both workers:
        >>> @torch.jit.script
        >>> def my_script_add(t1, t2):
        >>>    return torch.add(t1, t2)

        >>> # On worker 0:
        >>> import torch.distributed.rpc as rpc
        >>> rpc.init_rpc("worker0", rank=0, world_size=2)
        >>> rref = rpc.remote("worker1", my_script_add, args=(torch.ones(2), 3))
        >>> rref.to_here()
        >>> rpc.shutdown()

        >>> # On worker 1:
        >>> import torch.distributed.rpc as rpc
        >>> rpc.init_rpc("worker1", rank=1, world_size=2)
        >>> rpc.shutdown()
    """
    qualified_name = torch.jit._find_builtin(func)
    dst_worker_info = _to_worker_info(to)

    # If profiling is enabled, kick off the timer and retrieve back a
    # RecordFunction instance.
    rf = None
    if torch.autograd._profiler_enabled():
        rf = _start_record_function(
            RPCExecMode.REMOTE,
            str(qualified_name) if qualified_name is not None else func.__qualname__,
            get_worker_info().name,
            dst_worker_info.name,
        )

    args = args if args else ()
    kwargs = kwargs if kwargs else {}

    if qualified_name is not None:
        return _invoke_remote_builtin(dst_worker_info, qualified_name, rf, *args, **kwargs)
    elif isinstance(func, torch.jit.ScriptFunction):
        return _invoke_remote_torchscript(
            dst_worker_info.name, torch._jit_internal._qualified_name(func), *args, **kwargs
        )
    else:
        (pickled_python_udf, tensors) = _default_pickler.serialize(
            PythonUDF(func, args, kwargs)
        )
        return _invoke_remote_python_udf(dst_worker_info, pickled_python_udf, tensors, rf)

def _invoke_rpc(to, func, rpc_type, args=None, kwargs=None):
    if not callable(func):
        raise TypeError("function should be callable.")

    qualified_name = torch.jit._find_builtin(func)
    dst_worker_info = _to_worker_info(to)
    # If profiling is enabled, kick off the timer and retrieve back a
    # RecordFunction instance.
    rf = None
    if torch.autograd._profiler_enabled():
        rf = _start_record_function(
            rpc_type,
            str(qualified_name) if qualified_name is not None else func.__qualname__,
            get_worker_info().name,
            dst_worker_info.name,
        )

    args = args if args else ()
    kwargs = kwargs if kwargs else {}

    if qualified_name is not None:
        fut = _invoke_rpc_builtin(dst_worker_info, qualified_name, rf, *args, **kwargs)
    elif isinstance(func, torch.jit.ScriptFunction):
        fut = _invoke_rpc_torchscript(dst_worker_info.name, func, args, kwargs)
    else:
        (pickled_python_udf, tensors) = _default_pickler.serialize(
            PythonUDF(func, args, kwargs)
        )
        fut = _invoke_rpc_python_udf(dst_worker_info, pickled_python_udf, tensors, rf)
    return fut

@_require_initialized
def rpc_sync(to, func, args=None, kwargs=None):
    r"""
    Make a blocking RPC call to run function ``func`` on worker ``to``. RPC
    messages are sent and received in parallel to execution of Python code. This
    method is thread-safe.

    Arguments:
        to (str or WorkerInfo): id or name of the destination worker.
        func (callable): a callable function, such as Python callables, builtin
                         operators (e.g. :meth:`~torch.add`) and annotated
                         TorchScript functions.
        args (tuple): the argument tuple for the ``func`` invocation.
        kwargs (dict): is a dictionary of keyword arguments for the ``func``
                       invocation.

    Returns:
        Returns the result of running ``func`` with ``args`` and ``kwargs``.

    .. warning ::
        Using GPU tensors as arguments or return values of ``func`` is not
        supported since we don't support sending GPU tensors over the wire. You
        need to explicitly copy GPU tensors to CPU before using them as
        arguments or return values of ``func``.

    Example::
        Make sure that ``MASTER_ADDRESS`` and ``MASTER_PORT`` are set properly
        on both workers. Refer to :meth:`~torch.distributed.init_process_group`
        API for more details. For example,

        >>> export MASTER_ADDRESS=localhost
        >>> export MASTER_port=5678

        Then run the following code in two different processes:

        >>> # On worker 0:
        >>> import torch
        >>> import torch.distributed.rpc as rpc
        >>> rpc.init_rpc("worker0", rank=0, world_size=2)
        >>> ret = rpc.rpc_sync("worker1", torch.add, args=(torch.ones(2), 3))
        >>> rpc.shutdown()

        >>> # On worker 1:
        >>> import torch.distributed.rpc as rpc
        >>> rpc.init_rpc("worker1", rank=1, world_size=2)
        >>> rpc.shutdown()

        Below is an example of running a TorchScript function using RPC.

        >>> # On both workers:
        >>> @torch.jit.script
        >>> def my_script_add(t1, t2):
        >>>    return torch.add(t1, t2)

        >>> # On worker 0:
        >>> import torch.distributed.rpc as rpc
        >>> rpc.init_rpc("worker0", rank=0, world_size=2)
        >>> ret = rpc.rpc_sync("worker1", my_script_add, args=(torch.ones(2), 3))
        >>> rpc.shutdown()

        >>> # On worker 1:
        >>> import torch.distributed.rpc as rpc
        >>> rpc.init_rpc("worker1", rank=1, world_size=2)
        >>> rpc.shutdown()

    """
    fut = _invoke_rpc(to, func, RPCExecMode.SYNC, args, kwargs)
    return fut.wait()

@_require_initialized
def rpc_async(to, func, args=None, kwargs=None):
    r"""
    Make a non-blocking RPC call to run function ``func`` on worker ``to``. RPC
    messages are sent and received in parallel to execution of Python code. This
    method is thread-safe. This method will immediately return a Future that can
    be awaited on.

    Arguments:
        to (str or WorkerInfo): id or name of the destination worker.
        func (callable): a callable function, such as Python callables, builtin
                         operators (e.g. :meth:`~torch.add`) and annotated
                         TorchScript functions.
        args (tuple): the argument tuple for the ``func`` invocation.
        kwargs (dict): is a dictionary of keyword arguments for the ``func``
                       invocation.

    Returns:
        Returns a Future object that can be waited
        on. When completed, the return value of ``func`` on ``args`` and
        ``kwargs`` can be retrieved from the Future object.

    .. warning ::
        Using GPU tensors as arguments or return values of ``func`` is not
        supported since we don't support sending GPU tensors over the wire. You
        need to explicitly copy GPU tensors to CPU before using them as
        arguments or return values of ``func``.

    .. warning ::
        The ``rpc_async`` API does not copy storages of argument tensors until
        sending them over the wire, which could be done by a different thread
        depending on the RPC backend type. The caller should make sure that the
        contents of those tensors stay intact until the returned Future
        completes.

    Example::
        Make sure that ``MASTER_ADDRESS`` and ``MASTER_PORT`` are set properly
        on both workers. Refer to :meth:`~torch.distributed.init_process_group`
        API for more details. For example,

        >>> export MASTER_ADDRESS=localhost
        >>> export MASTER_port=5678

        Then run the following code in two different processes:

        >>> # On worker 0:
        >>> import torch
        >>> import torch.distributed.rpc as rpc
        >>> rpc.init_rpc("worker0", rank=0, world_size=2)
        >>> fut1 = rpc.rpc_async("worker1", torch.add, args=(torch.ones(2), 3))
        >>> fut2 = rpc.rpc_async("worker1", min, args=(1, 2))
        >>> result = fut1.wait() + fut2.wait()
        >>> rpc.shutdown()

        >>> # On worker 1:
        >>> import torch.distributed.rpc as rpc
        >>> rpc.init_rpc("worker1", rank=1, world_size=2)
        >>> rpc.shutdown()

        Below is an example of running a TorchScript function using RPC.

        >>> # On both workers:
        >>> @torch.jit.script
        >>> def my_script_add(t1, t2):
        >>>    return torch.add(t1, t2)

        >>> # On worker 0:
        >>> import torch.distributed.rpc as rpc
        >>> rpc.init_rpc("worker0", rank=0, world_size=2)
        >>> fut = rpc.rpc_async("worker1", my_script_add, args=(torch.ones(2), 3))
        >>> ret = fut.wait()
        >>> rpc.shutdown()

        >>> # On worker 1:
        >>> import torch.distributed.rpc as rpc
        >>> rpc.init_rpc("worker1", rank=1, world_size=2)
        >>> rpc.shutdown()
    """
    return _invoke_rpc(to, func, RPCExecMode.ASYNC, args, kwargs)


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

# In[33]:

# write code here
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# In[34]:

import seaborn as sns
import warnings
warnings.filterwarnings('ignore')

from collections import Counter

# In[3]:

gp = pd.read_csv('googleplaystore.csv')
gp.head(20)

# In[4]:

gp['Price'].isnull().sum()

# In[ ]:

# In[5]:

gp.shape

# In[6]:

gp.isnull().sum()

# In[ ]:

# In[ ]:

# In[9]:

free= gp['Type'].fillna('free',inplace=True)
gp['Content Rating'].fillna('Everyone',inplace=True)
gp['Current Ver'].fillna('1.0',inplace=True)
gp['Android Ver'].fillna('2.2 And up ', inplace=True)
gp.isnull().sum()

# **1. What is the download rate by categories?**

# In[10]:

gp.Installs[0]

# In[11]:

gp['Installs']= gp['Installs'].str.replace(',','')
gp['Installs']= gp['Installs'].str.replace('+','')
gp['Installs']= gp['Installs'].str.replace('Free','0')

# In[12]:

gp['Installs']= pd.to_numeric(gp['Installs'])

gp['Installs']

# In[13]:

gp.groupby('Category')['Installs'].sum().plot.bar(x='Category',y='Installs',color=['orange', 'red', 'green', 'blue', 'cyan','orange','black'])

# **2. What is the name of the 15 most downloaded applications?**

# In[14]:

A=gp.groupby('App')['Installs'].sum()
A.sort_values(ascending=False).head(15)

# **3. What is the download rate for paid applications?**

# In[15]:

gp[gp['Type']=='Paid'].head(17).groupby('App')['Installs'].sum().plot.bar(x='App',y='Category',color=['orange', 'red', 'green', 'blue', 'cyan','orange','black'])

# In[ ]:

# **4. Sort by category.**

# In[16]:

gp.sort_values(by=['Category'], inplace=True) # dataframe sorting

# In[17]:

gp.head()

# **5. What is the download rate and user rating by category?**

# In[18]:

bar=gp.groupby('Category')['Rating'].sum()
bar.head(35).plot.bar(x='Category',y='Rating',color=['orange', 'red', 'green', 'blue', 'cyan','orange','black'])

# In[ ]:

# In[ ]:

# In[21]:

# In[ ]:

# In[23]:

# for dummy variable encoding for Categories
x = gp.drop(['Installs'], axis=1)

# In[24]:

x.head()

# In[25]:

y = gp['Installs']

y.head()

# In[ ]:

# In[ ]:

# **6. Apply Machine learning models?**

# In[26]:

# train and test split

from sklearn.model_selection import train_test_split

# In[27]:

x_train,x_test,y_train,y_test = train_test_split(x,y)

# In[28]:

x_train

# In[29]:

x_test

# In[30]:

y_train

# In[31]:

y_test

# In[ ]:

# In[ ]:

# In[ ]:


#!/usr/bin/env python

RANKS = "__23456789TJQKA"
TYPES = ["", "RoyalFlush", "StraightFlush", "FourOfAKind", "FullHouse",
         "Flush", "Straight", "ThreeOfAKind", "TwoPair", "OnePair", "HighCard"]

def filter_repetition(ranks, repetition):
    return [rank for rank in set(ranks) if ranks.count(rank) == repetition]

def value_of_hand(hand):
    # high -> low
    ranks = sorted([RANKS.index(card[0]) for card in hand], reverse=True)
    # A - Z
    suits = sorted([card[1] for card in hand])
    is_straight = all([max(ranks) - ranks[i] == i for i in range(5)])
    is_flush = len(set(suits)) == 1
    rankcounts = [ranks.count(r) for r in set(ranks)]
    if is_straight and is_flush and max(ranks) == 14:
        return 10, 14  # Royal flush
    if is_straight and is_flush:
        return 9, max(ranks)  # Straight flush
    if 4 in rankcounts:
        return 8, filter_repetition(ranks, 4)[0]  # Four of a kind
    if 3 in rankcounts and 2 in rankcounts:
        return 7, filter_repetition(ranks, 3)[0]  # Full house
    if is_flush:
        return 6, max(ranks)  # Flush
    if is_straight:
        return 5, ranks  # Straight
    if 3 in rankcounts:
        return 4, filter_repetition(ranks, 3)[0]  # Three of a kind
    if rankcounts.count(2) == 2:
        return 3, max(filter_repetition(ranks, 2))  # Two pair
    if rankcounts.count(2) == 1:
        return 2, filter_repetition(ranks, 2)[0]  # One pair
    return 1, max(ranks)  # Highest card

winsPlayerA = 0
with open('problem054_poker.txt') as in_file:
    for line in in_file.readlines():
        handsAB = line[:-1].split(' ')
        typeA, highA = value_of_hand(handsAB[:5])
        typeB, highB = value_of_hand(handsAB[5:])
        if typeA > typeB or (typeA == typeB and highA > highB):
            winsPlayerA += 1
print(winsPlayerA)


import requests
import json
import re
from datetime import datetime
from .config import Config
from .exceptions import ConnectorException

class Connector:
    """
    Class responsible for getting data
    from TimeDoctor via API
    """

    def __init__(self):
        self._TOKEN_AUTH_URL = 'https://webapi.timedoctor.com/oauth/v2/auth_login'
        self._DOCUMENTATION_LINK = 'https://webapi.timedoctor.com/doc#documentation'
        self._API_URL = 'https://webapi.timedoctor.com/v1.1/'
        self._API_METHODS = {
            'user': 'companies',
            'worklogs': 'companies/{}/worklogs'
        }
        self._CACHE_DAY = 'day'
        self._CACHE_RANGE = 'range'
        self._DATE_FORMAT = '[0-9]{4}-[0-1][0-2]-[0-3][0-9]'
        self._loaded_data = {}
        self._cache_values = {self._CACHE_DAY: '', self._CACHE_RANGE: []}
        self.config = Config()

        # Init methods
        self._user = self._get_user_data()

    def _get_user_data(self):
        api_response = self._make_request(self._API_METHODS['user'])
        return api_response['user']

    def _make_request(self, api_method, params=None):
        if params is None:
            params = {}
        api_token = self.config.get_api_token()
        url = self._API_URL + api_method

        if '_format' not in params:
            params['_format'] = 'json'
        params['access_token'] = api_token
        response = requests.get(url, params=params)
        try:
            json_response = json.loads(response.text)
        except Exception as e:
            raise ConnectorException('\nThere has been problem with processing response from Time Doctor API. Error '
                                     'message:\n {}\n\n Response from Time Doctor was not data, but message:\n {}'
                                     '\n'.format(e, response.text))

        if response.status_code == 401:
            self.config.invalidate_api_token()
            raise ConnectorException(
                '\nAPI connection problem. ( Reason: {} ) \n '
                'Try to refresh your ACCESS TOKEN visit {} and click "Get Your Access Token'.format(
                    response.reason, self._DOCUMENTATION_LINK)
            )
        if response.status_code != 200:
            raise ConnectorException(
                'Not successful response from TimeDoctor API \n\n'
                'Status: {}, \nError: {} \nError Description: {}'.format(
                    response.status_code, json_response['error'], json_response['error_description']))
        return json_response

    def _get_user_id(self):
        return self._user['id']

    def _get_company_id(self):
        return self._user['company_id']

    def _get_range_value(self):
        cached_range = self._cache_values[self._CACHE_RANGE]
        if isinstance(cached_range, list):
            cached_range = []
        if len(cached_range) == 2:
            use_cached_range = self._yes_no_question('Do you want to use already used range ?')
            if use_cached_range:
                return cached_range

        start_date = self._get_date_value('Enter start date : ')
        end_date = self._get_date_value('Enter end date: ')
        self._cache_values[self._CACHE_RANGE] = [start_date, end_date]
        return self._cache_values[self._CACHE_RANGE]

    def _get_day_value(self):
        """
        Returns day, for which worklogs should be retrieved. Working
        also with cache value ( cache_day )

        :return: str
        """
        cached_day = self._cache_values[self._CACHE_DAY]
        if len(cached_day):
            day = cached_day
            if not self._yes_no_question('Do you want to use {} day'.format(cached_day)):
                day = self._get_date_value('Please enter day you want to get worklogs: ')
        else:
            day = self._get_date_value('Please enter day you want to get worklogs: ')
            self._cache_values[self._CACHE_DAY] = day
        return day

    def _get_date_value(self, question):
        date_value = input(question)
        #        while re.match(self._DATE_FORMAT, date_value) or not len(date_value):
        #            print('Wrong format. "YYYY-MM-DD" required ( value was {}. Len was {} ) '.format(date_value, len(date_value)))
        #            date_value = input(question)

        return date_value

    def _yes_no_question(self, question):
        positive_answer = ' ( y/n [yes/no] ) '
        answer = input(question + positive_answer)
        if answer.lower() in ('y', 'yes'):
            return True
        return False

    def get_user_day_worklogs(self, auto_mode=False):
        """
        Gets users worklogs for given day.

        :return:
        """
        company_id = self._get_company_id()
        api_endpoint = self._API_METHODS['worklogs'].format(company_id)

        if auto_mode:
            day = datetime.today().strftime('%Y-%m-%d')
        else:
            day = self._get_day_value()

        if day in self._loaded_data:
            return self._loaded_data[day]
        params = {'start_date': day, 'end_date': day, 'user_ids': self._get_user_id(), 'consolidated': 0}
        api_response = self._make_request(api_endpoint, params)
        self._loaded_data[day] = api_response['worklogs']['items']
        return self._loaded_data[day]

    def get_user_range_worklogs(self):
        company_id = self._get_company_id()
        api_endpoint = self._API_METHODS['worklogs'].format(company_id)

        date_range = self._get_range_value()
        range_id = '-'.join(date_range)
        if range_id in self._loaded_data:
            return self._loaded_data[range_id]

        params = {'start_date': date_range[0], 'end_date': date_range[1], 'user_ids': self._get_user_id(),
                  'consolidated': 0}
        api_response = self._make_request(api_endpoint, params)
        self._loaded_data[range_id] = api_response['worklogs']['items']

        return self._loaded_data[range_id]


from keras.datasets import cifar10 # from tensorflow.keras.datasets.cifar10 import load_data
from keras.utils import np_utils
import tensorflow as tf
import random

tf.set_random_seed(777)

(x_train, y_train), (x_test, y_test) = cifar10.load_data()
# print('X_train shape : ', X_train.shape) #(50000, 32, 32, 3)
# print('X_test shape : ', X_test.shape) # (10000, 32, 32, 3)

# hyper parameters
learning_rate = 0.001
training_epochs = 15
batch_size = 100

# ■■■■■■■■■■ categorical ■■■■■■■■■■
y_train = np_utils.to_categorical(y_train)
y_test = np_utils.to_categorical(y_test)

# input place holders
X = tf.placeholder(tf.float32, [None, 32, 32, 3])
X_img = tf.reshape(X, [-1, 32, 32, 3])  # img 28x28x1 (black/white)
Y = tf.placeholder(tf.float32, [None, 10])

W1 = tf.Variable(tf.random_normal([3, 3, 3, 32], stddev=0.01))
L1 = tf.nn.conv2d(X_img, W1, strides=[1, 1, 1, 1], padding='SAME')
L1 = tf.nn.relu(L1)
L1 = tf.nn.max_pool(L1, ksize=[1, 2, 2, 1],
                      strides=[1, 2, 2, 1], padding='SAME')
# print("L1: ", L1)   # shape=(?, 16, 16, 32)

W2 = tf.Variable(tf.random_normal([3, 3, 32, 64], stddev=0.01)) # W1의 32
L2 = tf.nn.conv2d(L1, W2, strides=[1, 1, 1, 1], padding='SAME')
L2 = tf.nn.relu(L2)
L2 = tf.nn.max_pool(L2, ksize=[1, 2, 2, 1],
                      strides=[1, 2, 2, 1], padding='SAME')
# print("L2: ", L2)   # shape=(?, 8, 8, 64)

W3 = tf.Variable(tf.random_normal([3, 3, 64, 32], stddev=0.01)) # W1의 32
L3 = tf.nn.conv2d(L2, W3, strides=[1, 1, 1, 1], padding='SAME')
L3 = tf.nn.relu(L3)
L3 = tf.nn.max_pool(L3, ksize=[1, 2, 2, 1],
                      strides=[1, 2, 2, 1], padding='SAME')
# print("L3: ", L3)   # shape=(?, 4, 4, 32)
L3_flat = tf.reshape(L3, [-1, 4 * 4 * 32])

W4 = tf.get_variable("W4", shape=[4 * 4 * 32, 16],
                     initializer=tf.contrib.layers.xavier_initializer())
b4 = tf.Variable(tf.random_normal([16]))
logits = tf.matmul(L3_flat, W4) + b4

W5 = tf.get_variable("W5", shape=[16, 10],
                     initializer=tf.contrib.layers.xavier_initializer())
b5 = tf.Variable(tf.random_normal([10]))
logits = tf.matmul(logits, W5) + b5

# define cost/loss & optimizer
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(
    logits=logits, labels=Y))
train = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost)

# hypothesis = tf.nn.softmax(tf.matmul(X, W) + b)
# cost = tf.reduce_mean(-tf.reduce_sum(Y * tf.log(hypothesis), axis=1))
# optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.1).minimize(cost)

# initialize
sess = tf.Session()
sess.run(tf.global_variables_initializer())

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print('Train')
    for step in range(100):
        avg_cost = 0

        for i in range(500):
            batch_xs, batch_ys = x_train[i*100:i*100+100], y_train[i*100:i*100+100]
            cost_val, _ = sess.run([cost, train], feed_dict={X: batch_xs, Y: batch_ys})
            avg_cost += cost_val/ 500
        print('Epoch>>', step, ' Cost>>', avg_cost)

    print('Learning Finished!')

    # Test model and check accuracy
    correct_prediction = tf.equal(tf.argmax(logits, 1), tf.argmax(Y, 1))
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
    print('Accuracy:', sess.run(accuracy, feed_dict={X: x_test, Y: y_test}))


import json
import pika, django, os
from dotenv import load_dotenv

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'admin.settings')
django.setup()

from products.models import Product

load_dotenv()

queue_url = os.getenv('RABBIT_MQ_URL')

params = pika.URLParameters(queue_url)

connection = pika.BlockingConnection(params)

channel = connection.channel()

if channel.is_open:

    channel.queue_declare(queue='admin')

    def callback(ch, method, properties, body):
        print('Received in Admin')
        print(body)
        id = json.loads(body)
        print(id)
        product = Product.objects.get(id=id)
        product.likes = product.likes + 1
        product.save()
        print('Product likes imcreased')

    channel.basic_consume(queue='admin', on_message_callback=callback, auto_ack=True)

    print('Started Consuming')

    channel.start_consuming()

    channel.close()
else :
    print('Failed to consume')


import time

import config
from rears import Rears
from rears.utils import (
    evaluate_model,
    load_model,
    load_review_data,
    load_vectorizer,
    preprocess_review_data,
    save_model,
    save_vectorizer,
)
from utils import (
    get_anime_reviews,
    get_model_path,
    get_sentiment_path,
    get_users_reviews,
    get_users_with_most_reviews,
    get_vectorized_path,
    get_vectorizer_path,
    init_directory,
    load_data,
)

def evaluate(verbose=True, timed=True):
    start_time = time.time()

    init_directory()
    data = load_data(config.CLEANED_DIR)
    animes, users, reviews = data["animes"], data["users"], data["reviews"]
    anime_reviews = get_anime_reviews(animes, reviews)
    test_users = get_users_with_most_reviews(anime_reviews, config.MAX_USERS)
    train_users = users["id"][~users["id"].isin(test_users)]

    for vectorizer in config.vectorizers:
        for sia in config.sias:
            for similarity in config.similarities:
                print("Evaluating", "_".join([vectorizer, sia, similarity]) + "...")
                model_path = get_model_path(vectorizer, sia, similarity)
                model = load_model(model_path)
                vectorized_anime_reviews = load_review_data(
                    anime_reviews,
                    get_vectorized_path(vectorizer),
                    get_sentiment_path(sia),
                )
                if model is None:
                    loaded_vectorizer = load_vectorizer(get_vectorizer_path(vectorizer))
                    if loaded_vectorizer is None:
                        loaded_vectorizer = vectorizer
                    model = Rears.init_with(
                        vectorized_anime_reviews=vectorized_anime_reviews,
                        vectorizer=loaded_vectorizer,
                        sia=sia,
                        similarity=similarity,
                    )
                    if vectorized_anime_reviews is None:
                        model.train(
                            get_users_reviews(anime_reviews, train_users),
                            verbose=verbose,
                        )
                    save_model(model, model_path)
                    save_vectorizer(model.vectorizer, get_vectorizer_path(vectorizer))
                if vectorized_anime_reviews is None:
                    vectorized_anime_reviews = preprocess_review_data(
                        model,
                        anime_reviews,
                        get_vectorized_path(vectorizer),
                        get_sentiment_path(sia),
                        save_only=False,
                        verbose=verbose,
                    )
                vectorized_anime_reviews = get_users_reviews(
                    vectorized_anime_reviews, test_users
                )
                evaluate_model(model, vectorized_anime_reviews, verbose=verbose)
                print("Done")

    if timed:
        print()
        print(f"Finished in {time.time() - start_time:.4f} seconds.")

if __name__ == "__main__":
    evaluate(verbose=True, timed=True)


#!/usr/bin/python3
import sys
import os
import argparse

parser = argparse.ArgumentParser(description ="aollect perf output", formatter_class=argparse.RawTextHelpFormatter)
parser.add_argument('-i', '--input', required=True)
parser.add_argument('-o', '--output', default="result.csv")
parser.add_argument('-e', '--event',  default="instructions,branches")
args = parser.parse_args()

print(args,file=sys.stderr)

result_dir = args.input

event_list = args.event.split(",")
print(event_list)

dir_list = os.listdir(result_dir)
dir_list = [f for f in dir_list if not f.startswith('.')]
dir_list.sort()
print(dir_list)
data_dict = {}
for item in dir_list:
    data_dict[item] = {event:None for event in event_list}
    filename = os.path.join(result_dir, item)
    with open(filename, "r") as f:
        for line in f.readlines():
            line = line.replace(',', '').strip()
            for event in event_list:
                if event in line:
                    assert not data_dict[item][event]
                    data_dict[item][event] = line.split()[0]

print(data_dict)
result_filename = args.output
with open(result_filename, "w") as result_file:
    result_file.write("benchmark," + ','.join(event_list) + '\n')
    for item in dir_list:
        result_file.write(item+',')
        for event in event_list:
            result_file.write("%s," % data_dict[item][event])
        result_file.write("\n")


import math

try:
    a=float(input("Enter 'a' value: "))
    b=float(input("Enter 'b' value: "))
    c=float(input("Enter 'c' value: "))

    D=b**2-4*a*c

    if D<0: raise Exception ("Discriminant is less than 0, so there are no roots")
    x1= (-b + math.sqrt(D))/2*a
    x2= (-b - math.sqrt(D))/2*a

    print("Discriminant = "+str(D))
    if (x1 == x2):
        print("x = "+str(x1))
    else:
        print("x1 = "+str(x1)+"\n"+"x2 = "+str(x2))
except TypeError as er:
    print("'Float/Int' types only"+str(er))
except ZeroDivisionError as errrr:
    print("'A' must be > 0. No divission by zero!"+"Defenition of your error: "+str(errrr))
except ValueError as errr:
    print("There must be 3 digit numbers!"+" Defenition of your error: "+str(errr))
except Exception as err:
    print(err)


import os

from pathlib import Path
import tensorflow as tf

from hlp.mt.config import get_config as _config

class LanguageModel(tf.keras.Model):
    """
    语言模型，将input输入
    """

    def __init__(self, vocab_size, d_embedding, batch_size, d_rnn):
        super(LanguageModel, self).__init__()
        # 初始参数
        self.batch_size = batch_size
        self.d_rnn = d_rnn
        self.d_embedding = d_embedding
        self.embedding = tf.keras.layers.Embedding(vocab_size+1, d_embedding)
        self.state0 = [tf.zeros([batch_size, d_rnn]), tf.zeros([batch_size, d_rnn])]
        self.state1 = [tf.zeros([batch_size, d_rnn]), tf.zeros([batch_size, d_rnn])]

        self.cell0 = tf.keras.layers.LSTMCell(d_rnn)
        self.cell1 = tf.keras.layers.LSTMCell(d_rnn)

        self.output_layer = tf.keras.layers.Dense(vocab_size)

    def call(self, sequences):
        """
        传入已编码的句子,shape ---> (batch_size, seq_len)
        返回预测序列
        """
        output = []
        sequences = self.embedding(sequences)  # shape ---> (batch_size, seq_len, vocab_size)
        sequences *= tf.math.sqrt(tf.cast(self.d_embedding, tf.float32))
        # output 为输出的字符列表，每个列表元素shape --> (batch_size, vocab_size)
        for sequences_t in tf.unstack(sequences, axis=1):  # sequences_t.shape --> (batch_size, vocab_size)
            out0, self.state0 = self.cell0(sequences_t, self.state0)  # out0.shape --> (batch_size, vocab_size)
            out1, self.state1 = self.cell1(out0, self.state1)
            out1 = self.output_layer(out1)
            output.append(out1)

        predictions = tf.stack(output, axis=1)  # prediction.shape --> (batch_size, seq_len, vocab_size)
        return predictions

    def reset_states(self):
        super(LanguageModel, self).reset_states()
        self.state0 = [tf.zeros([self.batch_size, self.d_rnn]), tf.zeros([self.batch_size, self.d_rnn])]
        self.state1 = [tf.zeros([self.batch_size, self.d_rnn]), tf.zeros([self.batch_size, self.d_rnn])]

def check_point():
    """
    检测检查点目录下是否有文件
    """
    # 进行语言对判断从而确定检查点路径
    checkpoint_dir = _config.lm_checkpoint_path
    is_exist = Path(checkpoint_dir)
    if not is_exist.exists():
        os.makedirs(checkpoint_dir, exist_ok=True)
    if_ckpt = tf.io.gfile.listdir(checkpoint_dir)
    return if_ckpt


from django.shortcuts import redirect
from nourish.models import EventUser, GroupUser, Group, EventGroup, UserProfile, Event, MealInvite
from django.core.urlresolvers import reverse
from django.views.generic import TemplateView
from fbcanvas.views import HybridCanvasView
import re

class RootPageView(HybridCanvasView, TemplateView):
    template_name = "nourish/RootPageView.html"

    def get_context_data(self, **kwargs):
        context = super(RootPageView, self).get_context_data(**kwargs)
        context['events'] = Event.objects.filter(display=True)
        return context

    def get(self, request, *args, **kwargs):
        if 'fbcanvas' in kwargs and kwargs['fbcanvas']:
            if 'request_ids' in request.GET:
                return redirect('/nourish/fb/_notif/?request_ids=' + request.GET['request_ids'])
            if 'ref' in request.GET and request.GET['ref'] == 'bookmarks':
                if 'count' in request.GET and request.GET['count']:
                    return redirect('/nourish/fb/_notif/?last=%s&ref=bookmarks' % request.GET['count'])
                return redirect('/nourish/fb/home/')
        return super(RootPageView, self).get(request, **kwargs)

class HomePageView(HybridCanvasView, TemplateView):
    template_name = "nourish/HomePageView.html"

    def get_context_data(self, **kwargs):
        context = super(HomePageView, self).get_context_data(**kwargs)

        context['groups'] = [ ]
        context['events'] = []
        context['egs'] = []

        if self.request.user.is_authenticated():
            for gm in GroupUser.objects.filter(user=self.request.user):
                context['groups'].append(gm.group)

            context['egs'] = list(EventGroup.objects.filter(group__in=context['groups']))

            context['host_invites'] = list(MealInvite.objects.filter(host_eg__in=context['egs']))
            context['guest_invites'] = list(MealInvite.objects.filter(guest_eg__in=context['egs']))

            for eu in EventUser.objects.filter(user=self.request.user):
                context['events'].append(eu.event)

        return context

def homepage_chooser(request, fbcanvas=False):
    url = homepage_chooser_url(request, fbcanvas)
    if fbcanvas:
        p = re.compile("\/nourish\/")
        url = p.sub('/nourish/fb/', url)
    return redirect(url)

def homepage_chooser_url(request, fbcanvas=False):
    user = request.user
    try:
        profile = UserProfile.objects.get(user=user)
        if profile.role == 'E':
            eus = EventUser.objects.filter(user=user,admin=True)
            if len(eus) > 1:
                return reverse('homepage')
            if not len(eus):
                return reverse('register-event')
            return eus[0].event.get_absolute_url()
        if profile.role == 'T':
            gus = GroupUser.objects.get(user=user,admin=True)
            egs = EventGroup.objects.get(group=gus[0].group)
            return egs[0].get_absolute_url()
        if profile.role == 'A':
            gus = GroupUser.objects.filter(user=user,admin=True)
            if len(gus) > 1:
                return reverse('homepage')
            if not len(gus):
                if 'nourish_event' in request.session:
                    event = Event.objects.get(id = request.session['nourish_event'])
                    return event.get_absolute_url() + 'register/guest/'
                return reverse('event-list')
            egs = EventGroup.objects.get(group=gus[0].group)
            return egs[0].get_absolute_url()
    except:
        return reverse('homepage')
    return reverse('homepage')


def main():
    matrix = []
    with open('input.txt') as matrix:
        matrix = [[int(x) for x in list(y)] for y in matrix.read().split("\n")]

    for i, row in enumerate(matrix):
        for j, _ in enumerate(row):
            if i == 0 and j == 0:
                continue
            elif j - 1 < 0:
                matrix[i][j] += matrix[i - 1][j]
            elif i - 1 < 0:
                matrix[i][j] += matrix[i][j - 1]
            else:
                matrix[i][j] += min(matrix[i][j - 1], matrix[i - 1][j])
    # for r in matrix:
    #     print(r)
    print(matrix[len(matrix) - 1][len(matrix) - 1] - matrix[0][0])

if __name__ == "__main__":
    main()


from turtle import Screen
from snake import Snake
from food import Food
from score_board import Scoreboard
import time

# Screen setup and creating snake body
screen = Screen()
screen.setup(width=600, height=600)
screen.bgcolor("black")
screen.title("My Snake Game")
screen.tracer(0)

snake = Snake()
food = Food()
scoreboard = Scoreboard()

# Listen To Arrow Keys on The Keyboard
screen.listen()
screen.onkey(snake.up, "Up")
screen.onkey(snake.down, "Down")
screen.onkey(snake.right, "Right")
screen.onkey(snake.left, "Left")

# Move Snake
game_is_on = True
while game_is_on:
    screen.update()
    time.sleep(0.1)
    snake.move()

    # Detect Collision With Food
    if snake.head.distance(food) < 15:
        food.refresh()
        snake.extend()
        scoreboard.increase_score()

    # Detect Collision with Wall
    if snake.head.xcor() > 280 or snake.head.xcor() < -280 or snake.head.ycor() > 280 or snake.head.ycor() < -280:
        scoreboard.reset()
        snake.reset()

        # Detect collision with Tail
        for segments in snake.segments[1:]:
            if snake.head.distance(segments) < 10:
                scoreboard.reset()
                snake.reset()

screen.exitonclick()


from tkinter import *
from tkinter import ttk

ventana= Tk()
ventana.title("Calculadora2")
ventana.configure(bg="#F3C7AA")
ventana.configure(cursor="pencil")
ventana.geometry('420x200')
style =ttk.Style()
style.configure("Transparent.TLabel", background=ventana["bg"])

def calcularsuma():
    try:
        num1 = float(numero1.get())
        num2 = float(numero2.get())
        resultado = num1 + num2
        resulatdo.config(state=NORMAL)
        resulatdo.delete(0, END)
        resulatdo.insert(0, resultado)
        resulatdo.config(state="readonly")
    except ValueError:
        resulatdo.config(state=NORMAL)
        resulatdo.delete(0, END)
        resulatdo.insert(0, "Error")
        resulatdo.config(state="readonly")

def calcularesta():
    try:
        num1 = float(numero1.get())
        num2 = float(numero2.get())
        resultado = num1 - num2
        resulatdo.config(state=NORMAL)
        resulatdo.delete(0, END)
        resulatdo.insert(0, resultado)
        resulatdo.config(state="readonly")
    except ValueError:
        resulatdo.config(state=NORMAL)
        resulatdo.delete(0, END)
        resulatdo.insert(0, "Error")
        resulatdo.config(state="readonly")

def calcularmult():
    try:
        num1 = float(numero1.get())
        num2 = float(numero2.get())
        resultado = num1 * num2
        resulatdo.config(state=NORMAL)
        resulatdo.delete(0, END)
        resulatdo.insert(0, resultado)
        resulatdo.config(state="readonly")
    except ValueError:
        resulatdo.config(state=NORMAL)
        resulatdo.delete(0, END)
        resulatdo.insert(0, "Error")
        resulatdo.config(state="readonly")

def calculardiv():
    try:
        num1 = float(numero1.get())
        num2 = float(numero2.get())
        resultado = num1 / num2
        resulatdo.config(state=NORMAL)
        resulatdo.delete(0, END)
        resulatdo.insert(0, resultado)
        resulatdo.config(state="readonly")
    except ValueError:
        resulatdo.config(state=NORMAL)
        resulatdo.delete(0, END)
        resulatdo.insert(0, "Error")
        resulatdo.config(state="readonly")
    except ZeroDivisionError:
        resulatdo.config(state=NORMAL)
        resulatdo.delete(0, END)
        resulatdo.insert(0, "División por 0")
        resulatdo.config(state="readonly")

def calcularporc():
    try:
        num1 = float(numero1.get())
        num2 = float(numero2.get())
        resultado = (num1 * num2) / 100
        resulatdo.config(state=NORMAL)
        resulatdo.delete(0, END)
        resulatdo.insert(0, resultado)
        resulatdo.config(state="readonly")
    except ValueError:
        resulatdo.config(state=NORMAL)
        resulatdo.delete(0, END)
        resulatdo.insert(0, "Error")
        resulatdo.config(state="readonly")

def clean_display():
    numero1.delete(0, END)
    numero2.delete(0, END)
    resulatdo.config(state=NORMAL)
    resulatdo.delete(0, END)
    resulatdo.config(state="readonly")

valor1=ttk.Label(ventana, text="Valor 1", style="Transparent.TLabel")
valor1.grid(row=1, column=2, pady=(30, 10), padx=(10,10))
numero1=ttk.Entry(ventana, width=15)
numero1.insert(END, "")
numero1.grid(row=1, column=3, pady=(30, 0), padx=(22,10), sticky=W+E)

valor2=ttk.Label(ventana, text="Valor 2", style="Transparent.TLabel")
valor2.grid(row=3, column=2, padx=(22,10), pady=(1,1))
numero2=ttk.Entry(ventana, width=15)
numero2.insert(END, "")
numero2.grid(row=3, column=3, pady=(0, 10), padx=(22,10), sticky=W+E)

displayresult=ttk.Label(ventana, text="Resultado", style="Transparent.TLabel")
displayresult.grid(row=4, column=2, pady=(15, 10), padx=(30,30))
resulatdo=ttk.Entry(ventana, width=15)
resulatdo.grid(row=4, column=3, pady=(0, 0), padx=(22,10), sticky=W+E)#pady=(abajo, arriba)
resulatdo.config(state="readonly")

operaciones=ttk.Label(ventana, text="Operaciones", style="Transparent.TLabel")
operaciones.grid(row=1, column=4, padx=(55,0), pady=(5,0))

BotonSumar=ttk.Radiobutton(ventana, text=" SUMAR ", value=1, command=calcularsuma).grid(row=2, column=4, sticky=W+E, padx=10)
BotonRestar=ttk.Radiobutton(ventana, text=" RESTAR ", value=2, command=calcularesta).grid(row=3, column=4, sticky=W+E, padx=10)
BotonMultiplicar= ttk.Radiobutton(ventana, text=" MULTIPLICAR ", value=3, command=calcularmult).grid(row=4, column=4, sticky=W+E, padx=10, pady=(0,10))
BotonDividir= ttk.Radiobutton(ventana, text=" Dividir ", value=4, command=calculardiv).grid(row=5, column=4, padx=10, sticky=W+E, pady=0)

ventana.mainloop()


import sys
#sys.stdin = open("input.txt", "r")
from collections import deque
def min_cost(s):
    key = [[987654321]*N for _ in range(N)]
    key[s[0]][s[1]] = 0
    q = deque([s])
    while q:
        a, b = q.popleft()
        if a == end and b == end:
            continue
        for d in delta:
            na = a + d[0]
            nb = b + d[1]
            if 0 <= na < N and 0 <= nb < N:
                if arr[a][b] < arr[na][nb]:
                    f = key[a][b] + 1 +(arr[na][nb]-arr[a][b])
                else:
                    f = key[a][b] + 1
                if key[na][nb] > f:
                    q.append((na,nb))
                    key[na][nb] = f

    return key[N-1][N-1]

for test_case in range(1, int(input()) + 1):
    N = int(input())
    arr = [list(map(int,input().split())) for _ in range(N)]
    start = (0,0)
    end = N-1
    delta = [(-1,0), (1,0), (0,-1), (0,1)]
    print('#{} {}'.format(test_case,min_cost(start)))