# -*- coding: utf-8 -*-
"""
Created on Sat Feb  6 18:50:46 2021

@author: Nikita
"""

import tkinter as tk
#from tkinter import colorchooser
from tkinter import ttk
from jinja2 import Template

#All frames that the GUI has
root = tk.Tk()
mainframe = ttk.Frame(root)
secondframe = ttk.Frame(root)
thirdframe = ttk.Frame(root)
fourthframe = ttk.Frame(root)
fifthframe = ttk.Frame(root)
sixthframe = ttk.Frame(root)
seventhframe = ttk.Frame(root)

mainframe.grid(column=0, row=0, sticky=(tk.N, tk.W, tk.E, tk.S))
secondframe.grid(column=0, row=0, sticky=(tk.N, tk.W, tk.E, tk.S))
thirdframe.grid(column=0, row=0, sticky=(tk.N, tk.W, tk.E, tk.S))
fourthframe.grid(column=0, row=0, sticky=(tk.N, tk.W, tk.E, tk.S))
fifthframe.grid(column=0, row=0, sticky=(tk.N, tk.W, tk.E, tk.S))
sixthframe.grid(column=0, row=0, sticky=(tk.N, tk.W, tk.E, tk.S))
seventhframe.grid(column=0, row=0, sticky=(tk.N, tk.W, tk.E, tk.S))

# global variables
current_frame = 0
displayed_frame = mainframe
frames = [mainframe, secondframe, thirdframe, fourthframe, fifthframe,
          sixthframe,seventhframe]
total_frames =  len(frames)
last_buttons = [ttk.Button(), ttk.Button()]

root.title("CV Builder")

def click():
    print("Click")

def nextFrame( number : int):
    global current_frame
    global total_frames
    global frames
    global displayed_frame
    global last_buttons
    global label_skills
    global label_languages

    # Get rid of arrow
    if (displayed_frame == mainframe):
        menu_employment.entryconfigure(1,label = "Personal Details")
    elif(displayed_frame == secondframe):
        menu_employment.entryconfigure(2,label = "Summary")
    elif(displayed_frame == thirdframe):
        menu_employment.entryconfigure(3,label = "Academic History")
    elif(displayed_frame == fourthframe):
        menu_employment.entryconfigure(4,label = "Employment History")
    elif(displayed_frame == fifthframe):
        menu_employment.entryconfigure(5,label = "Skills")
    elif(displayed_frame == sixthframe):
        menu_employment.entryconfigure(6,label = "Languages")
    elif(displayed_frame == seventhframe):
        menu_employment.entryconfigure(7,label = "Wrap Up")

    # Add arrow
    current_frame += number
    current_frame %= total_frames
    frames[current_frame].tkraise()
    displayed_frame = frames[current_frame]
    last_buttons[0].destroy()
    last_buttons[1].destroy()
    total = 0

    if (displayed_frame == fifthframe):
        total = 2*len(label_skills) + 4
    elif (displayed_frame == sixthframe):
        total = 2*len(label_languages) + 4
    else:
        total = 6

    # Add arrow
    if (displayed_frame == mainframe):
        menu_employment.entryconfigure(1,label = "->Personal Details")
    elif(displayed_frame == secondframe):
        menu_employment.entryconfigure(2,label = "->Summary")
    elif(displayed_frame == thirdframe):
        menu_employment.entryconfigure(3,label = "->Academic History")
    elif(displayed_frame == fourthframe):
        menu_employment.entryconfigure(4,label = "->Employment History")
    elif(displayed_frame == fifthframe):
        menu_employment.entryconfigure(5,label = "->Skills")
    elif(displayed_frame == sixthframe):
        menu_employment.entryconfigure(6,label = "->Languages")
    elif(displayed_frame == seventhframe):
        menu_employment.entryconfigure(7,label = "->Wrap Up")

    button_next = ttk.Button(displayed_frame, text = "Next >",command = lambda:nextFrame(1))
    button_next.grid(column = 1, row = total, sticky = tk.E, padx = (0,20))
    button_previous = ttk.Button(displayed_frame, text = "< Previous", command = lambda:nextFrame(-1))
    button_previous.grid(column = 0, row = total, sticky = tk.W , padx = (20,0))

    last_buttons[0] = button_next
    last_buttons[1] = button_previous

def addLanguage():
    global label_languages
    global languages
    global label_languages_level
    global languages_level
    global last_buttons_language
    global last_buttons

    label_languages.append(ttk.Label(sixthframe, text = 'Language '+str(len(label_languages)+1)))
    languages.append(ttk.Entry(sixthframe, font = ('Helvetica',16)))
    label_languages_level.append(ttk.Label(sixthframe, text = 'Language level ' + str(len(label_languages_level)+1)))
    languages_level.append(ttk.Entry(sixthframe, font = ('Helvetica',16)))
    total = 2*len(label_languages)

    label_languages[-1].grid(column = 0, row = total+1, sticky = (tk.W), padx = (20,0),pady = 10)
    languages[-1].grid(column = 1, row = total+1, sticky = (tk.E), padx = (0,20),pady = 10)
    label_languages_level[-1].grid(column = 0, row = total+2, sticky = tk.W , padx = (20,0),pady = 10)
    languages_level[-1].grid(column = 1, row = total+2, sticky = tk.E , padx = (0,20),pady = 10)

    last_buttons_language[0].destroy()
    last_buttons_language[1].destroy()

    last_buttons_language.append(ttk.Button())
    last_buttons_language.append(ttk.Button())

    last_buttons_language[0] = ttk.Button(sixthframe, text = "+ Add Language",command = addLanguage)
    last_buttons_language[0].grid(column = 1, row = total + 3, sticky = tk.E, padx = (0,20))
    last_buttons_language[1] = ttk.Button(sixthframe, text = "- Remove Language", command = removeLanguage)
    last_buttons_language[1].grid(column = 0, row = total + 3, sticky = tk.W , padx = (20,0))

    last_buttons[0].destroy()
    last_buttons[1].destroy()

    button_next = ttk.Button(displayed_frame, text = "Next >",command = lambda:nextFrame(1))
    button_next.grid(column = 1, row = total+4, sticky = tk.E, padx = (0,20))
    button_previous = ttk.Button(displayed_frame, text = "< Previous", command = lambda:nextFrame(-1))
    button_previous.grid(column = 0, row = total+4, sticky = tk.W , padx = (20,0))

    last_buttons[0] = button_next
    last_buttons[1] = button_previous

def removeLanguage():
    global label_languages
    global languages
    global label_languages_level
    global languages_level
    global last_buttons_language
    global last_buttons

    total = 2*len(label_languages)
    if (total > 0):

        label_languages[-1].destroy()
        languages[-1].destroy()
        label_languages_level[-1].destroy()
        languages_level[-1].destroy()

        label_languages.pop()
        languages.pop()
        label_languages_level.pop()
        languages_level.pop()

        total = 2*len(label_languages)

        last_buttons_language[0].destroy()
        last_buttons_language[1].destroy()

        last_buttons_language.append(ttk.Button())
        last_buttons_language.append(ttk.Button())

        last_buttons_language[0] = ttk.Button(sixthframe, text = "+ Add Entry",command = addLanguage)
        last_buttons_language[0].grid(column = 1, row = total + 3, sticky = tk.E, padx = (0,20))
        last_buttons_language[1] = ttk.Button(sixthframe, text = "- Remove Entry", command = removeLanguage)
        last_buttons_language[1].grid(column = 0, row = total + 3, sticky = tk.W , padx = (20,0))

        last_buttons[0].destroy()
        last_buttons[1].destroy()

        button_next = ttk.Button(displayed_frame, text = "Next >",command = lambda:nextFrame(1))
        button_next.grid(column = 1, row = total+4, sticky = tk.E, padx = (0,20))
        button_previous = ttk.Button(displayed_frame, text = "< Previous", command = lambda:nextFrame(-1))
        button_previous.grid(column = 0, row = total+4, sticky = tk.W , padx = (20,0))

        last_buttons[0] = button_next
        last_buttons[1] = button_previous

def addSkill():
    global label_skills
    global skills
    global label_skills_level
    global skills_level
    global last_buttons_skill
    global last_buttons

    label_skills.append(ttk.Label(fifthframe,  text = 'Skill ' + str(len(label_skills) + 1)))
    skills.append(ttk.Entry(fifthframe, font = ('Helvetica',16)))
    label_skills_level.append(ttk.Label(fifthframe,  text = 'Skill level ' + str(len(label_skills_level) + 1)))
    skills_level.append(ttk.Entry(fifthframe, font = ('Helvetica',16)))
    total = 2*len(label_skills)

    label_skills[-1].grid(column = 0, row = total+1, sticky = (tk.W), padx = (20,0),pady = 10)
    skills[-1].grid(column = 1, row = total+1, sticky = (tk.E), padx = (0,20),pady = 10)
    label_skills_level[-1].grid(column = 0, row = total+2, sticky = tk.W , padx = (20,0),pady = 10)
    skills_level[-1].grid(column = 1, row = total+2, sticky = tk.E , padx = (0,20),pady = 10)

    last_buttons_skill[0].destroy()
    last_buttons_skill[1].destroy()

    last_buttons_skill.append(ttk.Button())
    last_buttons_skill.append(ttk.Button())

    last_buttons_skill[0] = ttk.Button(fifthframe, text = "+ Add Entry",command = addSkill)
    last_buttons_skill[0].grid(column = 1, row = total + 3, sticky = tk.E, padx = (0,20))
    last_buttons_skill[1] = ttk.Button(fifthframe, text = "- Remove Entry", command = removeSkill)
    last_buttons_skill[1].grid(column = 0, row = total + 3, sticky = tk.W , padx = (20,0))

    last_buttons[0].destroy()
    last_buttons[1].destroy()

    button_next = ttk.Button(displayed_frame, text = "Next >",command = lambda:nextFrame(1))
    button_next.grid(column = 1, row = total+4, sticky = tk.E, padx = (0,20))
    button_previous = ttk.Button(displayed_frame, text = "< Previous", command = lambda:nextFrame(-1))
    button_previous.grid(column = 0, row = total+4, sticky = tk.W , padx = (20,0))

    last_buttons[0] = button_next
    last_buttons[1] = button_previous

def removeSkill():

    global label_skills
    global skills
    global label_skills_level
    global skills_level
    global last_buttons_skill
    global last_buttons

    total = 2*len(label_skills)
    if (total > 0):

        label_skills[-1].destroy()
        skills[-1].destroy()
        label_skills_level[-1].destroy()
        skills_level[-1].destroy()

        label_skills.pop()
        skills.pop()
        label_skills_level.pop()
        skills_level.pop()

        total = 2*len(label_skills)

        last_buttons_skill[0].destroy()
        last_buttons_skill[1].destroy()

        last_buttons_skill.append(ttk.Button())
        last_buttons_skill.append(ttk.Button())

        last_buttons_skill[0] = ttk.Button(fifthframe, text = "+ Add Entry",command = addSkill)
        last_buttons_skill[0].grid(column = 1, row = total + 3, sticky = tk.E, padx = (0,20))
        last_buttons_skill[1] = ttk.Button(fifthframe, text = "- Remove Entry", command = removeSkill)
        last_buttons_skill[1].grid(column = 0, row = total + 3, sticky = tk.W , padx = (20,0))

        last_buttons[0].destroy()
        last_buttons[1].destroy()

        button_next = ttk.Button(displayed_frame, text = "Next >",command = lambda:nextFrame(1))
        button_next.grid(column = 1, row = total+4, sticky = tk.E, padx = (0,20))
        button_previous = ttk.Button(displayed_frame, text = "< Previous", command = lambda:nextFrame(-1))
        button_previous.grid(column = 0, row = total+4, sticky = tk.W , padx = (20,0))

        last_buttons[0] = button_next
        last_buttons[1] = button_previous

def navigate(page : int):
    global displayed_frame

    # Get rid of arrow
    if (displayed_frame == mainframe):
        nextFrame(page-0)
        menu_employment.entryconfigure(1,label = "Personal Details")
    elif(displayed_frame == secondframe):
        nextFrame(page-1)
        menu_employment.entryconfigure(2,label = "Summary")
    elif(displayed_frame == thirdframe):
        nextFrame(page-2)
        menu_employment.entryconfigure(3,label = "Academic History")
    elif(displayed_frame == fourthframe):
        nextFrame(page-3)
        menu_employment.entryconfigure(4,label = "Employment History")
    elif(displayed_frame == fifthframe):
        nextFrame(page-4)
        menu_employment.entryconfigure(5,label = "Skills")
    elif(displayed_frame == sixthframe):
        nextFrame(page-5)
        menu_employment.entryconfigure(6,label = "Languages")
    elif(displayed_frame == seventhframe):
        nextFrame(page-6)
        menu_employment.entryconfigure(7,label = "Wrap Up")

    # Add arrow
    if (displayed_frame == mainframe):
        menu_employment.entryconfigure(1,label = "->Personal Details")
    elif(displayed_frame == secondframe):
        menu_employment.entryconfigure(2,label = "->Summary")
    elif(displayed_frame == thirdframe):
        menu_employment.entryconfigure(3,label = "->Academic History")
    elif(displayed_frame == fourthframe):
        menu_employment.entryconfigure(4,label = "->Employment History")
    elif(displayed_frame == fifthframe):
        menu_employment.entryconfigure(5,label = "->Skills")
    elif(displayed_frame == sixthframe):
        menu_employment.entryconfigure(6,label = "->Languages")
    elif(displayed_frame == seventhframe):
        menu_employment.entryconfigure(7,label = "->Wrap Up")

def printToTemplate():

    all_entries = {}
    for label,entry in zip(labels,entries):
        print (label['text'])
        if ( isinstance(entry , ttk.Entry)):
            all_entries[label['text'].replace(" ","")] = entry.get()
            print(label['text'])
        elif (isinstance( entry, tk.Text)):
            all_entries[label['text'].replace(" ","")] = entry.get("1.0","end")

    extracted_skills = []
    extracted_skill_levels = []
    extracted_languages = []
    extracted_language_levels = []
    for skill, skill_level in zip(skills,skills_level):
        extracted_skills.append(skill.get())
        extracted_skill_levels.append(skill_level.get())

    for language, language_level in zip(languages,languages_level):

        extracted_languages.append(language.get())
        extracted_language_levels.append(language_level.get())

    template = open("LaTeXTemplates\BlueBasicTexTemplate\BlueBasicTemplate.tex", "r")
    text = Template(template.read())
    template.close()
    write_to = open( "CreatedLatexFiles\CV.tex", "w")
    write_to.write(text.render(all_entries, languages = zip(extracted_languages,extracted_language_levels),
                               skills = zip(extracted_skills,extracted_skill_levels)) )
    write_to.close()

def addAcademicEntry():
    global total_academic_history_entries
    total = total_academic_history_entries
    menu_academic_history.entryconfigure(total + 1,label = "Academic History " + str(total+1))
    menu_academic_history.entryconfigure(total + 1, command = lambda:navigate(2))
    if (total_academic_history_entries == 1):
        menu_academic_history.add_command(label = "+ Academic History Entry", command = addAcademicEntry)
        menu_academic_history.add_command(label = "- Academic History Entry", command = deleteAcademicEntry)
    else:
        menu_academic_history.entryconfigure(total + 2,label = "+ Academic History Entry")
        menu_academic_history.entryconfigure(total + 2, command = addAcademicEntry)
        menu_academic_history.add_command(label = "- Academic History Entry", command = deleteAcademicEntry)

    total_academic_history_entries += 1

def deleteAcademicEntry():
    global total_academic_history_entries
    total = total_academic_history_entries
    menu_academic_history.delete(total,total+2)
    total -= 1
    total_academic_history_entries -= 1
    if (total == 1):
        menu_academic_history.add_command(label = "+ Academic History Entry", command = addAcademicEntry)
    else:
        menu_academic_history.add_command(label = "+ Academic History Entry", command = addAcademicEntry)
        menu_academic_history.add_command(label = "- Academic History Entry", command = deleteAcademicEntry)

# This is the menu that navigates through all the pages

menu_employment = tk.Menu(root)
menu_employment.add_command(label = "->Personal Details", command = lambda:navigate(0))

menu_employment.add_command(label = "Summary",command = lambda:navigate(1))

menu_academic_history = tk.Menu(menu_employment)
menu_employment.add_cascade(label = "Academic History", menu=menu_academic_history)
menu_academic_history.add_command(label = "Academic History 1", command = lambda:navigate(2))
total_academic_history_entries = 1
menu_academic_history.add_command(label = "+ Academic History Entry", command = addAcademicEntry)

menu_employment.add_command(label = "Employment History", command = lambda:navigate(3))

menu_employment.add_command(label = "Skills", command = lambda:navigate(4))

menu_employment.add_command(label = "Languages", command = lambda:navigate(5))

menu_employment.add_command(label = "Wrap Up", command = lambda:navigate(6))

root.config(menu = menu_employment)

entries = []
labels = []

# Everything here is related to the first frame

label_name = ttk.Label(mainframe, text = 'Name')
label_name.grid(column = 0, row = 0, sticky = (tk.W), padx = (20,0),pady = 10)
name = ttk.Entry(mainframe, font = ('Helvetica',16))
name.grid(column = 1, row = 0, sticky = (tk.E), padx = (0,20),pady = 10)

label_surname = ttk.Label(mainframe, text = 'Surname')
label_surname.grid(column = 0, row = 1, sticky = tk.W , padx = (20,0),pady = 10)
surname = ttk.Entry(mainframe, font = ('Helvetica',16))
surname.grid(column = 1, row = 1, sticky = tk.E , padx = (0,20),pady = 10)

label_telephone_number = ttk.Label(mainframe, text = 'Phone number')
label_telephone_number.grid(column = 0, row = 2, sticky = tk.W , padx = (20,0),pady = 10)
telephone_number = ttk.Entry(mainframe, font = ('Helvetica',16))
telephone_number.grid(column = 1, row = 2, sticky = tk.E , padx = (0,20),pady = 10)

label_mail = ttk.Label(mainframe, text = 'Email')
label_mail.grid(column = 0, row = 3, sticky = tk.W, padx = (20,0),pady = 10)
mail = ttk.Entry(mainframe, font = ('Helvetica',16))
mail.grid(column = 1, row = 3, sticky = tk.E, padx = (0,20),pady = 10)

label_Linkedin = ttk.Label(mainframe, text = 'Linkedin URL')
label_Linkedin.grid(column = 0, row = 4, sticky = tk.W, padx = (20,0),pady = 10)
Linkedin = ttk.Entry(mainframe, font = ('Helvetica',16))
Linkedin.grid(column = 1, row = 4, sticky =tk.E, padx = (0,20),pady = 10)

button_next = ttk.Button(displayed_frame, text = "Next >",command = lambda:nextFrame(1))
button_next.grid(column = 1, row = 5, sticky = tk.E, padx = (0,20))
button_previous = ttk.Button(displayed_frame, text = "< Previous", command = lambda:nextFrame(-1))
button_previous.grid(column = 0, row = 5, sticky = tk.W , padx = (20,0))
last_buttons[0] = button_next
last_buttons[1] = button_previous

entries.append(surname)
labels.append(label_surname)
entries.append(name)
labels.append(label_name)
entries.append(Linkedin)
labels.append(label_Linkedin)
entries.append(mail)
labels.append(label_mail)
entries.append(telephone_number)
labels.append(label_telephone_number)

for i in range(0,2):
    for j in range (0,5):
        mainframe.rowconfigure(i, weight = 1)
        mainframe.columnconfigure(j, weight = 3)

# Everything here is related to the second frame

label_summary = ttk.Label(secondframe, text = 'Profile')
label_summary.grid(column = 0, row = 0, sticky = (tk.W), padx = (20,20),pady = 10)
text_summary = tk.Text(secondframe, font = ('Helvetica',12),  height = 5, width = 40)
text_summary.grid(column = 1, row = 0, sticky = (tk.S,tk.N,tk.E,tk.W), padx = (20,20),pady = 10)
text_summary.insert("1.0","Give employers a summary of your life. \n")

entries.append(text_summary)
labels.append(label_summary)

# Everything here is related to the third frame

label_establishment = ttk.Label(thirdframe, text = 'Establishment')
label_establishment.grid(column = 0, row = 0, sticky = (tk.W), padx = (20,0),pady = 10)
establishment = ttk.Entry(thirdframe, font = ('Helvetica',16))
establishment.grid(column = 1, row = 0, sticky = (tk.E), padx = (0,20),pady = 10)

label_start_date = ttk.Label(thirdframe, text = 'Start date')
label_start_date.grid(column = 0, row = 1, sticky = (tk.W), padx = (20,0),pady = 10)
start_date = ttk.Entry(thirdframe, font = ('Helvetica',16))
start_date.grid(column = 1, row = 1, sticky = (tk.E), padx = (0,20),pady = 10)

label_end_date = ttk.Label(thirdframe, text = 'End date')
label_end_date.grid(column = 0, row = 2, sticky = (tk.W), padx = (20,0),pady = 10)
end_date = ttk.Entry(thirdframe, font = ('Helvetica',16))
end_date.grid(column = 1, row = 2, sticky = (tk.E), padx = (0,20),pady = 10)

label_specialization = ttk.Label(thirdframe, text = 'Specialization')
label_specialization.grid(column = 0, row = 3, sticky = (tk.W), padx = (20,0),pady = 10)
specialization = ttk.Entry(thirdframe, font = ('Helvetica',16))
specialization.grid(column = 1, row = 3, sticky = (tk.E), padx = (0,20),pady = 10)

label_description = ttk.Label(thirdframe, text = 'Description')
label_description.grid(column = 0, row = 4, sticky = (tk.W), padx = (20,0),pady = 10)
text_description = tk.Text(thirdframe, font = ('Helvetica',16), height = 5, width = 40)
text_description.grid(column = 1, row = 4, sticky = (tk.E), padx = (0,20),pady = 10)
text_description.insert("1.0", "List highlights of your time spent in said establishment. \n")

entries.append(establishment)
labels.append(label_establishment)
entries.append(start_date)
labels.append(label_start_date)
entries.append(end_date)
labels.append(label_end_date)
entries.append(specialization)
labels.append(label_specialization)
entries.append(text_description)
labels.append(label_description)

# Everything here is related to the fourth frame

label_company_name = ttk.Label(fourthframe, text = 'Company')
label_company_name.grid(column = 0, row = 0, sticky = (tk.W), padx = (20,0),pady = 10)
company_name = ttk.Entry(fourthframe, font = ('Helvetica',16))
company_name.grid(column = 1, row = 0, sticky = (tk.E), padx = (0,20),pady = 10)

label_start_date_job = ttk.Label(fourthframe, text = 'Job start date')
label_start_date_job.grid(column = 0, row = 1, sticky = (tk.W), padx = (20,0),pady = 10)
start_date_job = ttk.Entry(fourthframe, font = ('Helvetica',16))
start_date_job.grid(column = 1, row = 1, sticky = (tk.E), padx = (0,20),pady = 10)

label_end_date_job = ttk.Label(fourthframe, text = 'Job end date')
label_end_date_job.grid(column = 0, row = 2, sticky = (tk.W), padx = (20,0),pady = 10)
end_date_job = ttk.Entry(fourthframe, font = ('Helvetica',16))
end_date_job.grid(column = 1, row = 2, sticky = (tk.E), padx = (0,20),pady = 10)

label_position = ttk.Label(fourthframe, text = 'Position')
label_position.grid(column = 0, row = 3, sticky = (tk.W), padx = (20,0),pady = 10)
position = ttk.Entry(fourthframe, font = ('Helvetica',16))
position.grid(column = 1, row = 3, sticky = (tk.E), padx = (0,20),pady = 10)

label_description_job = ttk.Label(fourthframe, text = 'Job description')
label_description_job.grid(column = 0, row = 4, sticky = (tk.W), padx = (20,0),pady = 10)
text_description_job = tk.Text(fourthframe, font = ('Helvetica',16), height = 5, width = 40)
text_description_job.grid(column = 1, row = 4, sticky = (tk.E), padx = (0,20),pady = 10)
text_description_job.insert("1.0","Give employers an idea of what your job entitled. \n")

entries.append(company_name)
labels.append(label_company_name)
entries.append(start_date_job)
labels.append(label_start_date_job)
entries.append(end_date_job)
labels.append(label_end_date_job)
entries.append(position)
labels.append(label_position)
entries.append(text_description_job)
labels.append(label_description_job)

# Everything here is related to the fifth frame

label_skills = [ttk.Label()]
skills = [ttk.Entry()]
label_skills_level = [ttk.Label()]
skills_level = [ttk.Entry()]

label_skills[0] = ttk.Label(fifthframe, text = 'Skill 1')
label_skills[0].grid(column = 0, row = 0, sticky = (tk.W), padx = (20,0),pady = 10)
skills[0] = ttk.Entry(fifthframe, font = ('Helvetica',16))
skills[0].grid(column = 1, row = 0, sticky = (tk.E), padx = (0,20),pady = 10)

label_skills_level[0] = ttk.Label(fifthframe, text = 'Skill level 1')
label_skills_level[0].grid(column = 0, row = 1, sticky = tk.W , padx = (20,0),pady = 10)
skills_level[0] = ttk.Entry(fifthframe, font = ('Helvetica',16))
skills_level[0].grid(column = 1, row = 1, sticky = tk.E , padx = (0,20),pady = 10)

last_buttons_skill = []

last_buttons_skill.append(ttk.Button(fifthframe, text = "+ Add Entry",command = addSkill))
last_buttons_skill[0].grid(column = 1, row = 5, sticky = tk.E, padx = (0,20))
last_buttons_skill.append(ttk.Button(fifthframe, text = "- Remove Entry", command = removeSkill))
last_buttons_skill[1].grid(column = 0, row = 5, sticky = tk.W , padx = (20,0))

# Everything here is related to the sixth frame

label_languages = [ttk.Label()]
languages = [ttk.Entry()]
label_languages_level = [ttk.Label()]
languages_level = [ttk.Entry()]

label_languages[0] = ttk.Label(sixthframe, text = 'Language 1')
label_languages[0].grid(column = 0, row = 0, sticky = (tk.W), padx = (20,0),pady = 10)
languages[0] = ttk.Entry(sixthframe, font = ('Helvetica',16))
languages[0].grid(column = 1, row = 0, sticky = (tk.E), padx = (0,20),pady = 10)

label_languages_level[0] = ttk.Label(sixthframe, text = 'Language level 1')
label_languages_level[0].grid(column = 0, row = 1, sticky = tk.W , padx = (20,0),pady = 10)
languages_level[0] = ttk.Entry(sixthframe, font = ('Helvetica',16))
languages_level[0].grid(column = 1, row = 1, sticky = tk.E , padx = (0,20),pady = 10)

last_buttons_language = []

last_buttons_language.append(ttk.Button(sixthframe, text = "+ Add Language",command = addLanguage))
last_buttons_language[0].grid(column = 1, row = 5, sticky = tk.E, padx = (0,20))
last_buttons_language.append(ttk.Button(sixthframe, text = "- Remove Language", command = removeLanguage))
last_buttons_language[1].grid(column = 0, row = 5, sticky = tk.W , padx = (20,0))

# Everything here is related to the seventh frame

label_cv_name = ttk.Label(seventhframe, text = 'CV name')
label_cv_name.grid(column = 0, row = 0, sticky = (tk.W), padx = (20,0),pady = 10)
cv_name = ttk.Entry(seventhframe, font = ('Helvetica',16))
cv_name.grid(column = 1, row = 0, sticky = (tk.E), padx = (0,20),pady = 10)

button_finish = ttk.Button(seventhframe, text = "Print To Template",command = printToTemplate)
button_finish.grid(column = 0, row = 2, sticky = tk.W, padx = (20,0))

#template = Template(template)

#file = open("template.tex","r+")
#hello = file.read()
#doc = Document('basic')
#doc.append(hello)
#doc.generate_pdf('basic_maketitle2', clean_tex=False)
#file.close()

"""
        might want to call pack last or set the
        height last OR at least set it as a variable
        and call all packs last
"""
"""
        the next button ideally iterates through all entries
        and registers everything in a dictionary of the form
        dict(label : entry)

"""
#tk.colorchooser.askcolor(initialcolor='#ff0000') - might come in handy

mainframe.tkraise()
root.mainloop()


# 爬取论坛精选 要求返回作品类型
import os
import re

import parsel
import requests

url = 'http://www.fengniao.com/'
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36 Edg/89.0.774.75'
}
response = requests.get(url=url, headers=headers)
response.encoding = 'GBK'
html = parsel.Selector(response.text)
lis = html.xpath('//*[@id="bbsPart"]/dl/dd/div[1]/ul/li')
for li in lis:
    href = li.xpath('./div/a/@href').get()
    title = li.xpath('./div/div[1]/a/@title').get()
    category = li.xpath('./div/div[2]/a[1]/@title').get()
    pattern = re.compile(u'[\u4e00-\u9fa5]+')
    t_title = re.findall(pattern, title)
    path = 'C:/Users/AKA阿飞/Desktop/蜂鸟网论坛经典/' + t_title[0] + '-' + category + '/'
    print(f'开始下载{title}')
    if os.path.exists(path) == False:
        os.mkdir(path)
    peopleName = li.xpath('./div/div[2]/div/a/@title').get()
    img_html = parsel.Selector(requests.get(url=href, headers=headers).text)
    imgs = img_html.xpath(f'//*[@username="{peopleName}"]')
    i = 0
    for img1 in imgs:
        img_srcs = img1.xpath('./div[@class="aMain"]/div[@class="cont"]/div[@class="img"]')
        for img2 in img_srcs:
            exifBox = img1.xpath('./div[@class="aMain"]/dl[@class="exifBox"]/dd/span//text()').extract()
            if len(exifBox) != 0:
                with open(path + f'{i}.txt', mode='wb') as f1:
                    for k in exifBox:
                        f1.write((k + '\n').encode())
            with open(path + f'{i}.jpg', mode='wb') as f:
                img_src = img2.xpath('./a/img/@src').get()
                img_download = requests.get(url=img_src, headers=headers).content
                f.write(img_download)
                i += 1


# -*- coding: utf-8 -*-
"""
Routes and views for the flask application.
"""

from datetime import datetime
from flask import render_template, request
from AdvWeb import app
from enum import Enum
import os

DEFAULT_CONTENT_KEY = 'home'

DETAILS_DICTIONARY = {'Hebrew': [("טל':", "03-9042273"), ("נייד:", "052-3586954"), ("פקס:", "03-904xxxx")],
                      'Russian': [("Phone:", "03-9042273"), ("CellPhone:", "052-3586954"), ("Fax:", "03-904xxxx")]}

HEBREW_CONTENT_DICTIONARY = {'home': 'home_he.txt', 'about': 'about_he.txt'}
RUSSIAN_CONTENT_DICTIONARY = {'home': 'home_ru.txt'}

class Language(Enum):
    HEBREW = 'Hebrew'
    RUSSIAN = 'Russian'

def get_content(key=None, is_hebrew=True):
    if is_hebrew:
        content_dictionary = HEBREW_CONTENT_DICTIONARY
    else:
        content_dictionary = RUSSIAN_CONTENT_DICTIONARY

    if key is None or content_dictionary.get(key) is None:
        key = DEFAULT_CONTENT_KEY

    path = os.path.join(os.path.dirname(__file__),
                        'static/content/{file_name}'.format(file_name=content_dictionary[key]))
    with open(path, 'rb') as f:
        data = f.readlines()
        for i in xrange(len(data)):
            data[i] = data[i].decode('utf-8')
        return data

def get_details(lang):
    details = DETAILS_DICTIONARY[lang]
    details_content = []
    for key, value in details:
        details_content.append('{key} {value}'.format(key=key, value=value).decode('utf-8'))
    return details_content

@app.route('/', methods=['GET'])
@app.route('/home', methods=['GET'])
def home():
    """
        Renders the home page.
    """
    if request.args.get('lang'):
        return home_ru(request.args.get('key'))

    name = 'אינה ציפרסון'.decode('utf-8')
    profession = 'עורכת דין ונוטריון'.decode('utf-8')
    bottom_title = 'צור קשר'.decode('utf-8')

    return render_template('home.html',
                           name=name,
                           date=datetime.strftime(datetime.today(), '%d/%m/%Y'),
                           main_title=name,
                           description_title=name,
                           description_sub_title=profession,
                           main_content=get_content(request.args.get('key')),
                           bottom_title=bottom_title,
                           details=get_details(Language.HEBREW)
                           )

def home_ru(key=None):
    name = 'Inna Tsiperson'.decode('utf-8')
    profession = 'Advocate'.decode('utf-8')
    bottom_title = 'Contact'.decode('utf-8')

    default_content_key = 'home'

    return render_template('HomeRussian.html',
                           name=name,
                           date=datetime.strftime(datetime.today(), '%d/%m/%Y'),
                           main_title=name,
                           description_title=name,
                           description_sub_title=profession,
                           main_content=get_content(key or default_content_key, is_hebrew=False),
                           bottom_title=bottom_title,
                           details=get_details(Language.RUSSIAN)
                           )


import json
import os
import sys

import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd

from exprimo.benchmarking.benchmark import benchmark_all_placements
from exprimo.optimize import optimize_with_config
from exprimo.utils.convert_nets_to_placements import convert_to_placement
from exprimo import PLOT_STYLE

sns.set(style=PLOT_STYLE)

config_path = 'configs/experiments/e2_ga-malvik-alexnet.json'
model_type = 'alexnet'
batches = 50
NORMALIZE_PLOT = True
PLOT_INDIVIDUAL = False
DROP_LAST_DATASET_BATCH = True

if len(sys.argv) > 1:
    config_path = sys.argv[1]

if __name__ == '__main__':
    # Force checkpointing to occur every 5th generation
    with open(config_path) as f:
        config = json.load(f)
    config['optimizer_args']['checkpoint_period'] = 2

    DROP_LAST_DATASET_BATCH = config.get('drop_last_dataset_batch', DROP_LAST_DATASET_BATCH)

    log_dir = os.path.expanduser(config['log_dir'])

    # Create a set of configurations by running an optimization process with checkpointing
    optimize_with_config(config=config, set_log_dir=True)

    # Convert all configurations to placements for benchmarking
    convert_to_placement(os.path.join(log_dir, 'checkpoints'), os.path.join(log_dir, 'checkpoints', 'placements'))

    # Benchmark all the placements that were created above
    benchmark_all_placements(os.path.join(log_dir, 'checkpoints', 'placements'), os.path.join(log_dir, 'batch_times.csv'),
                             model_type, batches=batches, drop_batches=0, drop_last=DROP_LAST_DATASET_BATCH)

    # Load and plot benchmark results
    def plot_times(data, title, output_file=None):
        plt.plot(data)
        plt.xlabel('Batch')
        if NORMALIZE_PLOT:
            plt.ylabel('Residual batch training time (fraction of mean)')
        else:
            plt.ylabel('Batch training time (ms)')
        plt.title(title)

        if output_file:
            plt.savefig(output_file, bbox_inches='tight')

        plt.show()
        plt.close()

    batch_times = pd.read_csv(os.path.join(log_dir, 'batch_times.csv'), header=None, index_col=0)
    if NORMALIZE_PLOT:
        means = batch_times.mean(axis=1)
        batch_times = batch_times.sub(means, axis=0).divide(means, axis=0)

    if PLOT_INDIVIDUAL:
        for i in range(batch_times.shape[0]):
            generation = batch_times.index[0].replace('gen_', '').replace('.json', '')
            times = batch_times.iloc[i, 1:]

            output_file = os.path.join(log_dir, 'batch_training_time', f'gen_{generation}.pdf')

            plot_times(times, f'Generation {generation}', output_file)
    else:
        avg_batch_times = batch_times.mean(axis=0)
        plot_times(avg_batch_times, 'Average batch time residuals',
                   output_file=os.path.join(log_dir, 'batch_times.pdf'))


"""medi_liver URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/1.11/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  url(r'^$', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  url(r'^$', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.conf.urls import url, include
    2. Add a URL to urlpatterns:  url(r'^blog/', include('blog.urls'))
"""
from django.conf.urls import url
from django.contrib import admin
from .views import index, logout, login, doc_registration, profile, approve_med, decline_med

urlpatterns = [

    url(r'^$', index, name="index"),

    url(r'^logout/$', logout, name="doc_logout"),
    url(r'^login/$', login, name="doc_login"),
    url(r'^register/$', doc_registration, name="doc_registration"),
    url(r'^profile/$', profile, name="doc_profile"),

]


from flask import request, g
from flask_restful import Resource, reqparse

from app_config import auth, database
from app_utils import AppUtils
from common.constants.response_code import ResponseClass, ResponseCode

class ThreadsHandler(Resource):
    parser = reqparse.RequestParser()
    page_num_per_request = 10  # 每次返回10篇

    def __init__(self):
        self.parser.add_argument('page')

    # 发布帖子
    @auth.login_required
    def post(self):
        code_id = request.json.get('code_id', None)
        title = request.json.get('title', None)
        subtitile = request.json.get('subtitle', '')
        from app.database_models import Threads
        if not Threads.verify_title(title):
            return ResponseClass.warn(ResponseCode.FORMAT_ERROR)
        thread = Threads()
        thread.user_id = g.user.id
        thread.title = title
        thread.code_id = code_id
        thread.subtitle = subtitile
        AppUtils.add_to_sql(thread).close()
        return ResponseClass.ok()

    @auth.login_required
    # 获取最新帖子，一页10篇
    def get(self):
        args = self.parser.parse_args()
        page_num = int(args.get('page', None))
        if page_num is None or type(page_num) != int or page_num <= 0:
            return ResponseClass.warn(ResponseCode.FORMAT_ERROR)
        # 将page_num-1，适应计算
        page_num = page_num - 1
        session = AppUtils.get_session()
        try:
            from app.database_models import Threads
            threads = session.query(Threads).order_by(database.desc(Threads.id)).offset(
                page_num * self.page_num_per_request).limit(
                self.page_num_per_request).all()
            threads = [tr.get_public_dict() for tr in threads]
            return ResponseClass.ok_with_data(threads)
        finally:
            session.close()

# 获取用户自身的帖子
class GetUserThread(Resource):
    parser = reqparse.RequestParser()
    page_num_per_request = 10  # 每次返回10篇

    def __init__(self):
        self.parser.add_argument('page')

    @auth.login_required
    def get(self):
        args = self.parser.parse_args()
        page_num = int(args.get('page', None))
        if page_num is None or type(page_num) != int or page_num <= 0:
            return ResponseClass.warn(ResponseCode.FORMAT_ERROR)
        # 将page_num-1，适应计算
        page_num = page_num - 1
        session = AppUtils.get_session()
        from app.database_models import Threads
        threads = session.query(Threads).filter_by(user_id=g.user.id).offset(
            page_num * self.page_num_per_request).limit(
            self.page_num_per_request).all()
        threads = [tr.get_public_dict() for tr in threads]
        return ResponseClass.ok_with_data(threads)

# 删帖
class DeleteThread(Resource):

    @auth.login_required
    def post(self):
        from app_config import USER_ROLE_ADMIN
        from app.database_models import Threads
        if g.user.role == USER_ROLE_ADMIN:
            # 系统删帖
            t_id = request.json.get('thread_id', None)
            session = AppUtils.get_session()
            try:
                th = session.query(Threads).filter_by(id=t_id).first()
                if th is None:
                    return ResponseClass.warn(ResponseCode.THREAD_NOT_EXIST)
                session.delete(th)
                session.commit()
                return ResponseClass.ok()
            finally:
                session.close()
        else:
            t_id = request.json.get('thread_id', None)
            session = AppUtils.get_session()
            th = session.query(Threads).filter_by(user_id=g.user.id, id=t_id).first()
            if th is None:
                return ResponseClass.warn(ResponseCode.THREAD_NOT_EXIST)
            AppUtils.delete_to_sql(th).close()
            return ResponseClass.ok()


#!/usr/bin/python3
"""
2-warmup_flask: start's a Flask application
"""
from flask import Flask
from os import getenv

app = Flask(__name__)

@app.route('/')
def get_hbs_string():
    """ Returns 'Holberton School' when the route is called """
    app.url_map.strict_slashes = False
    return "Holberton School"

@app.route('/c', strict_slashes=False)
def get_c_string():
    """ Return's 'C is fun!' when the route is called """
    app.url_map.strict_slashes = False
    return "C is fun!"

if __name__ == "__main__":
    host = getenv('HBNB_API_HOST')
    port = int(getenv('HBNB_API_PORT'))
    app.run(host=host, port=port)


from typing import Dict, List, Optional
import xml.etree.ElementTree as ET

def elem_to_str(elem: ET.Element) -> str:
    return ET.tostring(elem).decode('utf-8')

def get_inside_text(element: ET.Element) -> Optional[str]:
    """
    Returns everything between <foo> and closing </foo>.

    Note that ET.tostring() works if you want the tags as well.

    Adapted from: https://stackoverflow.com/a/381614/543913
    """
    tokens = [element.text or '']
    tokens.extend(map(elem_to_str, element))
    tokens.append(element.tail or '')
    return ''.join(tokens).strip()

def get_node(
        tree: ET.Element,
        tag: Optional[str]=None,
        attribs: Optional[Dict[str, str]]=None,
        index: Optional[int]=None
        ) -> List[ET.Element]:
    """
    Finds the top-level nodes of <tree> which match <tag> and whose attrib
    mappings contains <attribs>.

    If index is None, asserts that only one such node matches, and returns it.
    Otherwise, returns the <index>'th node.
    """
    if attribs is None:
        attribs = {}

    nodes = [node for node in list(tree) if node.tag == tag and
            all([node.attrib.get(k, None)==v for k, v in attribs.items()])]
    if index is None:
        assert len(nodes)==1, [(node.tag, node.attrib) for node in list(tree)]
        return nodes[0]
    return nodes[index]


import argparse
from services.clouguard_service import CloudGuardService
from services.google_cloud_service import GoogleCloudService
from utils import validate_region, create_resource_lists_to_delete

def parse_arguments():
    parser = argparse.ArgumentParser(description="GCP Offboarding Script")
    parser.add_argument("--project-id", type=str, help="Your GCP centralized project id that you want to offboard")
    parser.add_argument("--region", type=validate_region,
                        help="The CloudGuard region you use (us/eu1/ap1/ap2/ap3/cace1)")
    parser.add_argument("--api-key", type=str, help="Your CloudGuard API key")
    parser.add_argument("--api-secret", type=str, help="Your CloudGuard API secret key")
    parser.add_argument("--google-credentials-path", type=str, help="The path to your key file")
    return parser.parse_args()

if __name__ == "__main__":

    args = parse_arguments()

    project_id = args.project_id
    region = args.region
    api_key = args.api_key
    api_secret = args.api_secret
    credentials_path = args.google_credentials_path

    try:

        cloudguard_service = CloudGuardService(api_key, api_secret, region)
        google_cloud_service = GoogleCloudService(credentials_path)
        topic_list, subscription_list, sink_list, service_account_list = create_resource_lists_to_delete(
            google_cloud_service, cloudguard_service, project_id)

        user_confirmation = input(
            "Do you want to delete CloudGuard related resources that created during the onboarding of this project? (yes/no): ")

        if user_confirmation.lower() == "yes":
            google_cloud_service.delete_cloudguard_resources(project_id, service_account_list, topic_list,
                                                             subscription_list, sink_list)
            print("CloudGuard resources have been deleted.")
        elif user_confirmation.lower() == "no":
            print("CloudGuard resources will not be deleted, you can delete them manually")
        else:
            print("Invalid input. Please enter 'yes' or 'no'.")

        # Cloud Guard offboarding API
        cloudguard_service.cloudguard_offboarding_request(project_id)
        print(f"Project {project_id} successfully offboarded from CloudGuard")
    except Exception as e:
        print(f"Error occurred in onboarding process, Error: {e}")


import math
import os
import re
import sys
from typing import Dict, List, Optional
import warnings

if sys.version_info >= (3, 9):
    from functools import cache
else:
    from functools import lru_cache as cache

import accelerate
import psutil
import torch
from transformers import (
    AutoConfig,
    AutoModel,
    AutoModelForCausalLM,
    AutoModelForSeq2SeqLM,
    AutoTokenizer,
    LlamaTokenizer,
    LlamaForCausalLM,
    T5Tokenizer,
)
import dataclasses
import gc
import glob
import os

from accelerate import init_empty_weights
from accelerate.utils import set_module_tensor_to_device
from huggingface_hub import snapshot_download
import torch
from torch import Tensor
from torch.nn import functional as F
import torch.nn as nn
from tqdm import tqdm
from transformers import (
    AutoConfig,
    AutoModelForCausalLM,
    AutoTokenizer,
    AutoModel,
    AutoModelForSeq2SeqLM,
)

from conversation import*

class BaseModelAdapter:
    """The base and the default model adapter."""

    use_fast_tokenizer = True

    def match(self, model_path: str):
        return True

    def load_model(self, model_path: str, from_pretrained_kwargs: dict):
        revision = from_pretrained_kwargs.get("revision", "main")
        try:
            tokenizer = AutoTokenizer.from_pretrained(
                model_path,
                use_fast=self.use_fast_tokenizer,
                revision=revision,
                trust_remote_code=True,
            )
        except TypeError:
            tokenizer = AutoTokenizer.from_pretrained(
                model_path, use_fast=False, revision=revision, trust_remote_code=True
            )
        try:
            model = AutoModelForCausalLM.from_pretrained(
                model_path, low_cpu_mem_usage=True, **from_pretrained_kwargs
            )
        except NameError:
            model = AutoModel.from_pretrained(
                model_path, low_cpu_mem_usage=True, **from_pretrained_kwargs
            )
        return model, tokenizer

    def load_compress_model(self, model_path, device, torch_dtype, revision="main"):
        return load_compress_model(
            model_path,
            device,
            torch_dtype,
            use_fast=self.use_fast_tokenizer,
            revision=revision,
        )

    def get_default_conv_template(self, model_path: str) -> Conversation:
        return get_conv_template("one_shot")

def get_compressed_list(module, prefix=""):
    compressed_list = []
    for attr_str in dir(module):
        target_attr = getattr(module, attr_str)
        if type(target_attr) == torch.nn.Linear:
            full_name = (
                f"{prefix}.{attr_str}.weight" if prefix else f"{attr_str}.weight"
            )
            compressed_list.append(full_name)
    for name, child in module.named_children():
        child_prefix = f"{prefix}.{name}" if prefix else name
        for each in get_compressed_list(child, child_prefix):
            compressed_list.append(each)
    return compressed_list

from dataclasses import dataclass
@dataclass
class CompressionConfig:
    """Group-wise quantization."""
    num_bits: int
    group_size: int
    group_dim: int
    symmetric: bool
    enabled: bool = True

default_compression_config = CompressionConfig(
    num_bits=8, group_size=256, group_dim=1, symmetric=True, enabled=True
)

def compress(tensor, config):
    """Simulate group-wise quantization."""
    if not config.enabled:
        return tensor

    group_size, num_bits, group_dim, symmetric = (
        config.group_size,
        config.num_bits,
        config.group_dim,
        config.symmetric,
    )
    assert num_bits <= 8

    original_shape = tensor.shape
    num_groups = (original_shape[group_dim] + group_size - 1) // group_size
    new_shape = (
        original_shape[:group_dim]
        + (num_groups, group_size)
        + original_shape[group_dim + 1 :]
    )

    # Pad
    pad_len = (group_size - original_shape[group_dim] % group_size) % group_size
    if pad_len != 0:
        pad_shape = (
            original_shape[:group_dim] + (pad_len,) + original_shape[group_dim + 1 :]
        )
        tensor = torch.cat(
            [tensor, torch.zeros(pad_shape, dtype=tensor.dtype, device=tensor.device)],
            dim=group_dim,
        )
    data = tensor.view(new_shape)

    # Quantize
    if symmetric:
        B = 2 ** (num_bits - 1) - 1
        scale = B / torch.max(data.abs(), dim=group_dim + 1, keepdim=True)[0]
        data = data * scale
        data = data.clamp_(-B, B).round_().to(torch.int8)
        return data, scale, original_shape
    else:
        B = 2**num_bits - 1
        mn = torch.min(data, dim=group_dim + 1, keepdim=True)[0]
        mx = torch.max(data, dim=group_dim + 1, keepdim=True)[0]

        scale = B / (mx - mn)
        data = data - mn
        data.mul_(scale)

        data = data.clamp_(0, B).round_().to(torch.uint8)
        return data, mn, scale, original_shape

def load_compress_model(model_path, device, torch_dtype, use_fast, revision="main"):
    # partially load model
    # `use_fast=True`` is not supported for some models.
    try:
        tokenizer = AutoTokenizer.from_pretrained(
            model_path, use_fast=use_fast, revision=revision, trust_remote_code=True
        )
    except TypeError:
        tokenizer = AutoTokenizer.from_pretrained(
            model_path, use_fast=~use_fast, revision=revision, trust_remote_code=True
        )
    with init_empty_weights():
        # `trust_remote_code` should be set as `True` for both AutoConfig and AutoModel
        config = AutoConfig.from_pretrained(
            model_path,
            low_cpu_mem_usage=True,
            torch_dtype=torch_dtype,
            trust_remote_code=True,
            revision=revision,
        )
        # some models are loaded by AutoModel but not AutoModelForCausalLM,
        # such as chatglm, chatglm2
        try:
            # google/flan-* models are based on an AutoModelForSeq2SeqLM.
            if "T5Config" in str(type(config)):
                model = AutoModelForSeq2SeqLM.from_config(
                    config, trust_remote_code=True
                )
            else:
                model = AutoModelForCausalLM.from_config(config, trust_remote_code=True)
        except NameError:
            model = AutoModel.from_config(config, trust_remote_code=True)
        linear_weights = get_compressed_list(model)
    if os.path.exists(model_path):
        # `model_path` is a local folder
        base_pattern = os.path.join(model_path, "pytorch_model*.bin")
    else:
        # `model_path` is a cached Hugging Face repo
        # We don't necessarily need to download the model' repo again if there is a cache.
        # So check the default huggingface cache first.
        model_path_temp = os.path.join(
            os.path.expanduser("~"),
            ".cache/huggingface/hub",
            "models--" + model_path.replace("/", "--"),
            "snapshots/",
        )
        downloaded = False
        if os.path.exists(model_path_temp):
            temp_last_dir = os.listdir(model_path_temp)[-1]
            model_path_temp = os.path.join(model_path_temp, temp_last_dir)
            base_pattern = os.path.join(model_path_temp, "pytorch_model*.bin")
            files = glob.glob(base_pattern)
            if len(files) > 0:
                downloaded = True

        if downloaded:
            model_path = model_path_temp
        else:
            model_path = snapshot_download(model_path, revision=revision)
        base_pattern = os.path.join(model_path, "pytorch_model*.bin")

    files = glob.glob(base_pattern)
    if len(files) == 0:
        raise ValueError(
            f"Cannot find any model weight files. "
            f"Please check your (cached) weight path: {model_path}"
        )

    compressed_state_dict = {}
    for filename in tqdm(files):
        tmp_state_dict = torch.load(filename, map_location=lambda storage, loc: storage)
        for name in tmp_state_dict:
            if name in linear_weights:
                tensor = tmp_state_dict[name].to(device, dtype=torch_dtype)
                compressed_state_dict[name] = compress(
                    tensor, default_compression_config
                )
            else:
                compressed_state_dict[name] = tmp_state_dict[name].to(
                    device, dtype=torch_dtype
                )
            tmp_state_dict[name] = None
            tensor = None
            gc.collect()
            torch.cuda.empty_cache()
            if device == "xpu":
                torch.xpu.empty_cache()
            if device == "npu":
                torch.npu.empty_cache()

    for name in model.state_dict():
        if name not in linear_weights:
            set_module_tensor_to_device(
                model, name, device, value=compressed_state_dict[name]
            )
    apply_compressed_weight(model, compressed_state_dict, device)

    if torch_dtype == torch.float16:
        model.half()
    model.to(device)
    model.eval()

    return model, tokenizer

def apply_compressed_weight(module, compressed_state_dict, target_device, prefix=""):
    for attr_str in dir(module):
        target_attr = getattr(module, attr_str)
        if type(target_attr) == torch.nn.Linear:
            full_name = (
                f"{prefix}.{attr_str}.weight" if prefix else f"{attr_str}.weight"
            )
            setattr(
                module,
                attr_str,
                CLinear(
                    compressed_state_dict[full_name], target_attr.bias, target_device
                ),
            )
    for name, child in module.named_children():
        child_prefix = f"{prefix}.{name}" if prefix else name
        apply_compressed_weight(
            child, compressed_state_dict, target_device, child_prefix
        )

class CLinear(nn.Module):
    """Compressed Linear Layer."""

    def __init__(self, weight=None, bias=None, device=None):
        super().__init__()
        if weight is None:
            self.weight = None
        elif isinstance(weight, Tensor):
            self.weight = compress(weight.data.to(device), default_compression_config)
        else:
            self.weight = weight
        self.bias = bias

    def forward(self, input: Tensor) -> Tensor:
        weight = decompress(self.weight, default_compression_config)
        if self.bias is None:
            return F.linear(input.to(weight.dtype), weight)
        return F.linear(input.to(weight.dtype), weight, self.bias.to(weight.dtype))

def decompress(packed_data, config):
    """Simulate group-wise dequantization."""
    if not config.enabled:
        return packed_data

    group_size, num_bits, group_dim, symmetric = (
        config.group_size,
        config.num_bits,
        config.group_dim,
        config.symmetric,
    )

    # Dequantize
    if symmetric:
        data, scale, original_shape = packed_data
        data = data / scale
    else:
        data, mn, scale, original_shape = packed_data
        data = data / scale
        data.add_(mn)

    # Unpad
    pad_len = (group_size - original_shape[group_dim] % group_size) % group_size
    if pad_len:
        padded_original_shape = (
            original_shape[:group_dim]
            + (original_shape[group_dim] + pad_len,)
            + original_shape[group_dim + 1 :]
        )
        data = data.reshape(padded_original_shape)
        indices = [slice(0, x) for x in original_shape]
        return data[indices].contiguous()
    else:
        return data.view(original_shape)

def remove_parent_directory_name(model_path):
    """Remove parent directory name."""
    if model_path[-1] == "/":
        model_path = model_path[:-1]
    return model_path.split("/")[-1]

class VicunaAdapter(BaseModelAdapter):
    "Model adapater for Vicuna models (e.g., lmsys/vicuna-7b-v1.3)" ""

    use_fast_tokenizer = False

    def match(self, model_path: str):
        return "vicuna" in model_path.lower()

    def load_model(self, model_path: str, from_pretrained_kwargs: dict):
        revision = from_pretrained_kwargs.get("revision", "main")
        tokenizer = AutoTokenizer.from_pretrained(
            model_path, use_fast=self.use_fast_tokenizer, revision=revision
        )
        model = AutoModelForCausalLM.from_pretrained(
            model_path,
            low_cpu_mem_usage=True,
            **from_pretrained_kwargs,
        )
        self.raise_warning_for_old_weights(model)
        return model, tokenizer

    def get_default_conv_template(self, model_path: str) -> Conversation:
        if "v0" in remove_parent_directory_name(model_path):
            return get_conv_template("one_shot")
        return get_conv_template("vicuna_v1.1")

    def raise_warning_for_old_weights(self, model):
        if isinstance(model, LlamaForCausalLM) and model.model.vocab_size > 32000:
            warnings.warn(
                "\nYou are probably using the old Vicuna-v0 model, "
                "which will generate unexpected results with the "
                "current fastchat.\nYou can try one of the following methods:\n"
                "1. Upgrade your weights to the new Vicuna-v1.3: https://github.com/lm-sys/FastChat#vicuna-weights.\n"
                "2. Use the old conversation template by `python3 -m fastchat.serve.cli --model-path /path/to/vicuna-v0 --conv-template one_shot`\n"
                "3. Downgrade fschat to fschat==0.1.10 (Not recommonded).\n"
            )

# A global registry for all model adapters
# TODO (lmzheng): make it a priority queue.
model_adapters: List[BaseModelAdapter] = []

def register_model_adapter(cls):
    """Register a model adapter."""
    model_adapters.append(cls())
register_model_adapter(VicunaAdapter)

@cache
def get_model_adapter(model_path: str) -> BaseModelAdapter:
    """Get a model adapter for a model_path."""
    model_path_basename = os.path.basename(os.path.normpath(model_path))

    # print(f'model_path_basename: {model_path_basename}')
    # print(model_adapters)
    # Try the basename of model_path at first
    for adapter in model_adapters:
        if adapter.match(model_path_basename) and type(adapter) != BaseModelAdapter:

            return adapter

    # Then try the full path
    for adapter in model_adapters:
        if adapter.match(model_path):
            # print(f'adapter: {adapter}')
            return adapter

    raise ValueError(f"No valid model adapter for {model_path}")

def get_conversation_template(model_path: str) -> Conversation:
    """Get the default conversation template."""
    adapter = get_model_adapter(model_path)
    return adapter.get_default_conv_template(model_path)

def get_conv_template(name: str) -> Conversation:
    """Get a conversation template."""
    return conv_templates[name].copy()

register_conv_template(
    Conversation(
        name="vicuna_v1.1",
        system_message="A chat between a curious user and an artificial intelligence assistant. "
        "The assistant gives helpful, detailed, and polite answers to the user's questions.",
        roles=("USER", "ASSISTANT"),
        sep_style=SeparatorStyle.ADD_COLON_TWO,
        sep=" ",
        sep2="</s>",
    )
)


__author__ = "Christian Kongsgaard"
__license__ = 'MIT'

# -------------------------------------------------------------------------------------------------------------------- #
# IMPORTS

# Modules
import matplotlib.pyplot as plt
import numpy as np

# RiBuild Modules
from delphin_6_automation.database_interactions import mongo_setup
from delphin_6_automation.database_interactions.auth import auth_dict
from delphin_6_automation.database_interactions.db_templates import delphin_entry

# -------------------------------------------------------------------------------------------------------------------- #
# RIBuild

server = mongo_setup.global_init(auth_dict)

filtered_entries = delphin_entry.Delphin.objects(simulated__exists=True).only('simulation_time')
gt_250 = filtered_entries.filter(simulation_time__gt=15000)
gt_300 = filtered_entries.filter(simulation_time__gt=300*60)

def get_time(projects):
    time = []
    for p in projects:
        time.append(p.simulation_time)

    return np.array(time)/60

sim_time = get_time(filtered_entries)

print()
print('STATS')
print(f'\tCount: {len(sim_time)}')
print(f'\tMin: {np.min(sim_time):.02f}')
print(f'\tQ25: {np.quantile(sim_time, 0.25):.02f}')
print(f'\tMean: {np.mean(sim_time):.02f}')
print(f'\tMedian: {np.quantile(sim_time, 0.50):.02f}')
print(f'\tQ75: {np.quantile(sim_time, 0.75):.02f}')
print(f'\tQ95: {np.quantile(sim_time, 0.95):.02f}')
print(f'\tMax: {np.max(sim_time):.02f}')
print('')
print(f'\tSimulations that takes longer than 250min: {gt_250.count()} = '
      f'{gt_250.count()/filtered_entries.count()*100:.02f}%')
print(f'\tSimulations that takes longer than 300min: {gt_300.count()} = '
      f'{gt_300.count()}')
print('')

months = 4
jobs_par = 300

"""
print('PREDICTIONS')
print('\tAverage:')
print(f'\t- (24h x 60min) / Simulation Time x {jobs_par} parallel x ({months} months x 30days): '
      f'{24*60/np.mean(sim_time)*jobs_par*months*30:.01f} simulations')
print('')
"""

hist, edges = np.histogram(sim_time, density=True, bins=100)
dx = edges[1] - edges[0]
cdf = np.cumsum(hist) * dx

plt.figure(figsize=(10, 10))
#plt.hist(sim_time, bins=50, )
plt.plot(edges[1:], cdf)
plt.axvline(x=np.mean(sim_time), linestyle=':', color='k', label='Mean')
plt.axvline(x=np.median(sim_time), linestyle='--', color='k', label='Median')
plt.title('Simulation Time')
plt.xlabel('Simulation Time in Minutes')
plt.ylabel('Ratio of Simulations')
plt.legend()
plt.xlim(-5, 260)
plt.show()

mongo_setup.global_end_ssh(server)


#!/home/yangz6/Software/miniconda3/envs/base2/bin/python
# Programmer : Yang Zhang
# Contact: yangz6@andrew.cmu.edu
# Last-modified: 09 Mar 2023 10:03:08 PM

import os,sys,argparse
from bx.bbi.bigwig_file import BigWigFile
from tqdm import tqdm
import numpy as np
from sklearn.preprocessing import PowerTransformer

def parse_arg():
    ''' This Function Parse the Argument '''
    p=argparse.ArgumentParser( description = 'Example: %(prog)s -h', epilog='Library dependency :')
    p.add_argument('-v','--version',action='version',version='%(prog)s 0.1')
    p.add_argument('--bw',type=str,dest="bw",nargs="+",help="bigwig file list")
    p.add_argument('--label',type=str,dest="label",nargs="+",help="label for the bigwig files")
    p.add_argument('--bin',type=str,dest="bin",help="bin annotation file")
    p.add_argument('--cell_name',type=str,dest="cell_name",help="cell name to extract in the bin annotation file, only rows in the fifth column of the bin annotation matching the cell_name will be extracted")
    p.add_argument('--original',type=str,dest="original",help="original signal without normalization")
    p.add_argument('--output',type=str,dest="output",help="output file")
    if len(sys.argv) < 2:
        print(p.print_help())
        exit(1)
    return p.parse_args()

class Bin(object):
    def __init__(self, chrom, start, end, idx):
        self.chrom = chrom
        self.start = start
        self.end = end
        self.bin_idx = idx
        #
        self.anno = {}
        self.normalized_anno = {}
    def __repr__(self):
        return "%s\t%d\t%d\t%s" % (self.chrom, self.start, self.end, self.bin_idx)
    def cal_mean_signal(self, bw, label):
        '''get the mean signal value within region'''
        array = np.array([])
        signal = bw.get_as_array(bytes(self.chrom, 'utf-8'), self.start, self.end)
        if signal is not None:
            array = np.append(array, signal)
        if len(array) < 1: # resolve the warning issue with numpy when array with zero element
            value = np.NAN
        else:
            value = np.nanmean(array)
        #
        self.anno[label] = value

def parse_bin_anno(filename, cell_name):
    region_list = []
    with open(filename, 'r') as fin:
        for line in fin:
            if line.strip().startswith('#') or line.strip() == '':
                continue
            row = line.strip().split('\t')
            chrom = row[0]
            start = int(row[1])
            end = int(row[2])
            bin_idx = row[3]
            cell_label = row[4]
            if cell_label == cell_name:
                region_list.append(Bin(chrom, start, end, bin_idx))
    return region_list

def main():
    global args
    args = parse_arg()
    # check parameters
    try:
        assert len(args.bw) == len(args.label)
    except AssertionError:
        print("length of bigwig files and label does not match", file = sys.stderr)
        exit(1)
    bw_list = []
    label_list = []
    for nn in range(len(args.bw)):
        bw_list.append(BigWigFile(open(args.bw[nn], 'rb')))
        label_list.append(args.label[nn])
    # parse bin annotation
    region_list = parse_bin_anno(args.bin, args.cell_name)
    print("Parse %d region" % (len(region_list)), file = sys.stdout)
    # annotate bin with bigwig files
    for nn in tqdm(range(len(region_list))):
        region = region_list[nn]
        for bw,label in zip(bw_list, label_list):
            region.cal_mean_signal(bw, label)
    print("calculate mean signal per bin done", file = sys.stdout)
    # power transformation
    for label in label_list:
        value_list = []
        idx_list = []
        for idx in tqdm(range(len(region_list))):
            idx_list.append(idx)
            region = region_list[idx]
            value = region.anno.get(label, np.NAN)
            value_list.append(value)
        value_list = np.array(value_list).reshape(-1, 1)
        pt = PowerTransformer(method='yeo-johnson', standardize=True)
        value_list_transformed = pt.fit_transform(value_list)
        assert value_list.shape[0] == value_list_transformed.shape[0]
        for idx,transformed_value in zip(idx_list, value_list_transformed.flatten()):
            region_list[idx].normalized_anno[label] = transformed_value
    print("transformation done", file = sys.stdout)
    # report
    if args.original is not None:
        with open(args.original, 'w') as fout:
            print('\t'.join(label_list), file = fout)
            for region in region_list:
                array = []
                for label  in label_list:
                    value = region.anno[label]
                    if np.isnan(value):
                        value = 'NA'
                    else:
                        value = '{:.6f}'.format(value)
                    array.append(value)
                print('\t'.join(array), file = fout)
    with open(args.output, 'w') as fout:
        print('\t'.join(label_list), file = fout)
        for region in region_list:
            array = []
            for label in label_list:
                value = region.normalized_anno[label]
                if np.isnan(value):
                    value = 'NA'
                else:
                    value = '{:.6f}'.format(value)
                array.append(value)
            print('\t'.join(array), file = fout)

if __name__=="__main__":
    main()


import sys
from typing import List, NamedTuple

from Queries import RQSS_QUERIES
from SPARQLWrapper import JSON, SPARQLWrapper

class MultilingualMetadataResult(NamedTuple):
    property: str
    num_non_en_label: int
    num_non_en_comment: int

    def __repr__(self):
        return "Property {0} has {1} non-English labels and {2} non-English comments".format(
            self.property,
            self.num_non_en_label,
            self.num_non_en_comment)

class MultilingualMetadataChecker:
    results: List[MultilingualMetadataResult] = None
    _ref_properties: List[str]

    def __init__(self, ref_properties: List[str]):
        self._ref_properties = ref_properties

    def check_multilingual_existance_from_Wikdiata(self) -> List[MultilingualMetadataResult]:
        self.results = []
        user_agent = "RQSSFramework Python/%s.%s" % (
            sys.version_info[0], sys.version_info[1])
        sparql = SPARQLWrapper(
            "https://query.wikidata.org/sparql", agent=user_agent)
        for prop in self._ref_properties:
            print('\t Getting number of non-English labels of reference property: ', prop)
            sparql.setQuery(
                RQSS_QUERIES['get_property_non_en_labels_wikidata'].format(prop))
            sparql.setReturnFormat(JSON)
            try:
                results = sparql.query().convert()
                for result in results["results"]["bindings"]:
                    value = result["to_ret"]["value"]
                    if value.isdigit():
                        num_non_en_labels = int(value)
                    else:
                        num_non_en_labels = 0
            except Exception as e:
                print('\t\t ERROR: ', e)
                continue
            print('\t Getting number of non-English comments of reference property: ', prop)
            sparql.setQuery(
                RQSS_QUERIES['get_property_non_en_comments_wikidata'].format(prop))
            sparql.setReturnFormat(JSON)
            try:
                results = sparql.query().convert()
                for result in results["results"]["bindings"]:
                    value = result["to_ret"]["value"]
                    if value.isdigit():
                        num_non_en_comments = int(value)
                    else:
                        num_non_en_comments = 0
            except Exception as e:
                print('\t\t ERROR: ', e)
                continue
            self.results.append(MultilingualMetadataResult(
                prop, num_non_en_labels, num_non_en_comments))
        return self.results

    @property
    def multilingual_labeling_score(self):
        if self.results is not None:
            return len([i for i in self.results if i.num_non_en_label > 0])/len(self.results) if len(self.results) > 0 else 1
        return None

    @property
    def multilingual_commenting_score(self):
        if self.results is not None:
            return len([i for i in self.results if i.num_non_en_comment > 0])/len(self.results) if len(self.results) > 0 else 1
        return None

    def __repr__(self):
        if self.results is None:
            return 'Results are not computed'
        return """num of properties,multilingual labeling score,multilingual commenting score
{0},{1},{2}""".format(
            len(self.results),
            self.multilingual_labeling_score,
            self.multilingual_commenting_score)

    def print_results(self):
        """
        print self.result if it is already computed
        """
        if self.results is None:
            print('Results are not computed')
            return
        for r in self.results:
            print(r)


from django.shortcuts import render
from django.http import HttpResponse

# Create your views here.
def hello(request):
    text = f'
"Изучаем django"
\nАвтор: Бараксина Яна'
    return HttpResponse(text)

first_name = 'Иван'
father_name = 'Петрович'
last_name = 'Иванов'
phone = '8-923-600-01-02'
email = 'vasya@mail.ru'

def about(request):
    text1 = f'
Имя: {first_name}
'
    text2 = f'
Отчество: {father_name}
'
    text3 = f'
Фамилия: {last_name}
'
    text4 = f'
Телефон: {phone}
'
    text5 = f'
email: {email}
'
    text = text1 + text2 + text3 + text4 + text5
    return HttpResponse(text)

items = [
   {"id": 1, "name": "Кроссовки abibas", "quantity": 5},
   {"id": 2, "name": "Куртка кожаная", "quantity": 2},
   {"id": 5, "name": "Coca-cola 1 литр", "quantity": 12},
   {"id": 7, "name": "Картофель фри", "quantity": 0},
   {"id": 8, "name": "Кепка", "quantity": 124},
]

def item_info(request, item_id):
    item = None
    for each in items:
        if item_id == each['id']:
            item = each
    if item is None:
        text = f'
Товар с id={item_id} не найден
'
    else:
        text = f'
{item["name"]}: {item["quantity"]} шт.
'
    text += 'Назад к списку товаров'
    return HttpResponse(text)

def items_list(request):
    text = '
'
    for each in items:
        text += f'
{each["name"]}
'
    text += '
'
    return HttpResponse(text)


import requests
import json
import logging

from jadi import component
from aj.plugins.dns_api.api import ApiDnsManager
from aj.plugins.dns_api.record import Record
import aj

@component(ApiDnsManager)
class GandiApiDnsProvider(ApiDnsManager):
    """
    LiveDNS API for domains hosted by Gandi.
    Full documentation available here: https://api.gandi.net/docs/livedns/
    """

    id = 'gandi'
    name = 'Gandi DNS API'

    def __init__(self, context):
        self.baseUrl = 'https://api.gandi.net/v5/livedns/domains'

    def _req(self, method, apiurl="", data=None):
        """
        Do the request to the api url.

        :param method: get, put, post or delete
        :type method: basestring
        :param apiurl: called url
        :type apiurl: basestring
        :param data: optional data to send (e.g. post)
        :type data: dict
        :return: response from the api
        :rtype: json
        """

        apikey = aj.config.data.get('dns_api', {}).get('apikey', None)
        sharing_id = aj.config.data.get('dns_api', {}).get('sharing_id', None)
        params = {'sharing_id': sharing_id}

        if method not in ["get", "put", "post", "delete"] or apikey is None:
            return

        func = getattr(requests, method)
        if data is None:
            resp = func(
                f"{self.baseUrl}{apiurl}",
                params=params,
                headers={"Authorization": f"Apikey {apikey}"}
            )
        else:
            resp = func(
                f"{self.baseUrl}{apiurl}",
                data=data,
                params=params,
                headers={"Authorization": f"Apikey {apikey}"}
            )

        return resp

    def get_domains(self):
        """
        List all domains managed by livedns under the provided apikey.
        :return: List of domains
        :rtype: list
        """

        domains = json.loads(self._req("get").content)
        return [domain['fqdn'] for domain in domains]

    def get_records(self, domain):
        """
        List all records from a given domain.

        :param domain: the domain, like example.com
        :type domain: basestring
        :return: List of records with details (TTL, name, type, etc...)
        :rtype: list
        """

        resp = self._req('get', apiurl=f"/{domain.fqdn}/records")
        records = json.loads(resp.content)
        domain.records = []

        for record in sorted(records, key=lambda d: d['rrset_name']):
            domain.records.append(Record(
                record['rrset_name'],
                record['rrset_ttl'],
                record['rrset_type'],
                record['rrset_values'])
            )

    def add_record(self, fqdn, record):
        """
        Add a new record to a given domain.

        :param fqdn: the domain, like example.com
        :type fqdn: basestring
        :param record: the record to add, with all details (TTL, name, type, etc...)
        :type record: Record object
        :return: status of the request and message
        :rtype: tuple
        """

        try:
            data = json.dumps({
                'rrset_name': record.name,
                'rrset_type': record.type,
                'rrset_values': record.values,
                'rrset_ttl': record.ttl
            })
            resp = self._req('post', apiurl=f"/{fqdn}/records", data=data)
            messages = json.loads(resp.content)
            if messages.get('status', '') == 'error':
                return resp.status_code, messages['errors']
            else:
                return resp.status_code, messages['message']
        except Exception as e:
            logging.error(e)

    def update_record(self, fqdn, record):
        """
        Update a record from a given domain with new values.

        :param fqdn: the domain, like example.com
        :type fqdn: basestring
        :param record: the record to add, with all details (TTL, name, type, etc...)
        :type record: Record object
        :return: status of the request and message
        :rtype: tuple
        """

        try:
            data = json.dumps({'items': [{
                'rrset_name': record.name,
                'rrset_type': record.type,
                'rrset_values': record.values,
                'rrset_ttl': record.ttl
            }]})
            resp = self._req('put', apiurl=f"/{fqdn}/records/{record.name}", data=data)
            messages = json.loads(resp.content)
            if messages.get('status', '') == 'error':
                return resp.status_code, messages['errors']
            else:
                return resp.status_code, messages['message']
        except Exception as e:
            logging.error(e)

    def delete_record(self, fqdn, rtype, name):
        """
        Delete a record from a given domain.

        :param fqdn: the domain, like example.com
        :type fqdn: basestring
        :param rtype: type of the DNS entry, like CNAME or AAAA
        :type rtype: basestring
        :param name: the record name, like test (to delete the entry test.example.com)
        :type name: basestring
        :return: status of the request and message
        :rtype: tuple
        """

        try:
            resp = self._req('delete', apiurl=f"/{fqdn}/records/{name}/{rtype}")
            if resp.content:
                messages = json.loads(resp.content)
            else:
                messages = {'message': 'Entry deleted'}
            if messages.get('status', '') == 'error':
                return resp.status_code, messages['errors'][0]['description']
            else:
                return resp.status_code, messages['message']
        except Exception as e:
            logging.error(e)


import os

import openai
openai.api_key = os.getenv("OPENAI_API_KEY")

def chat(prompt):

  completion = openai.ChatCompletion.create(
      model="gpt-3.5-turbo",
      messages=[
        {"role": "user", "content": prompt}
      ],
    )

  return completion.choices[0].message


import torch
from torch.utils.data.sampler import Sampler
import linklink as link
import math
import numpy as np

class DistributedSampler(Sampler):
    def __init__(self, dataset, world_size=None, rank=None, round_up=True):
        if world_size is None:
            world_size = link.get_world_size()
        if rank is None:
            rank = link.get_rank()
        self.dataset = dataset
        self.world_size = world_size
        self.rank = rank
        self.round_up = round_up
        self.epoch = 0

        self.num_samples = int(
            math.ceil(len(self.dataset) * 1.0 / self.world_size))
        if self.round_up:
            self.total_size = self.num_samples * self.world_size
            self.length = self.num_samples
        else:
            self.total_size = len(self.dataset)

        if self.rank < self.world_size-1:
            self.length = self.num_samples
        else:
            self.length = self.total_size - \
                (self.world_size-1)*self.num_samples

    def __iter__(self):
        g = torch.Generator()
        g.manual_seed(self.epoch)
        indices = list(torch.randperm(len(self.dataset), generator=g))

        if self.round_up:
            indices += indices[:(self.total_size - len(indices))]
        assert len(indices) == self.total_size

        offset = self.num_samples * self.rank
        indices = indices[offset:offset + self.num_samples]
        if self.round_up or (not self.round_up and self.rank < self.world_size-1):
            assert len(indices) == self.num_samples

        return iter(indices)

    def __len__(self):
        return self.length

    def set_epoch(self, epoch):
        self.epoch = epoch

class DistributedGivenIterationSampler(Sampler):
    def __init__(self, dataset, total_iter, batch_size, world_size=None, rank=None, last_iter=0):
        if world_size is None:
            world_size = link.get_world_size()
        if rank is None:
            rank = link.get_rank()
        assert rank < world_size
        self.dataset = dataset
        self.total_iter = total_iter
        self.batch_size = batch_size
        self.world_size = world_size
        self.rank = rank
        self.last_iter = last_iter

        self.total_size = self.total_iter*self.batch_size

        self.indices = self.gen_new_list()
        self.call = 0

    def __iter__(self):
        if self.call == 0:
            self.call = 1
            return iter(self.indices[self.last_iter*self.batch_size:])
        else:
            raise RuntimeError(
                "this sampler is not designed to be called more than once!!")

    def gen_new_list(self):
        np.random.seed(0)
        all_size = self.total_size * self.world_size
        indices = np.arange(len(self.dataset))
        indices = indices[:all_size]
        num_repeat = (all_size-1) // indices.shape[0] + 1

        indices = np.tile(indices, num_repeat)
        indices = indices[:all_size]

        np.random.shuffle(indices)
        beg = self.total_size * self.rank
        indices = indices[beg:beg+self.total_size]

        assert len(indices) == self.total_size

        return indices

    def __len__(self):
        # note here we do not take last iter into consideration, since __len__
        # should only be used for displaying, the correct remaining size is
        # handled by dataloader
        return self.total_size

class DistributedEpochSampler(Sampler):
    def __init__(self, dataset, total_iter, batch_size, world_size=None, rank=None, last_iter=0):
        if world_size is None:
            world_size = link.get_world_size()
        if rank is None:
            rank = link.get_rank()
        assert rank < world_size
        self.dataset = dataset
        self.total_iter = total_iter
        self.batch_size = batch_size
        self.world_size = world_size
        self.rank = rank
        self.last_iter = last_iter

        self.all_size_single = self.total_iter * self.batch_size

        self.indices = self.gen_new_list()
        self.call = 0

    def __iter__(self):
        if self.call == 0:
            self.call = 1
            return iter(self.indices[self.last_iter*self.batch_size:])
        else:
            raise RuntimeError(
                "this sampler is not designed to be called more than once!!")

    def get_one_epoch_self_part(self):
        num = len(self.dataset)
        indices = np.arange(num)
        extra_indices = np.random.choice(
            num, self.extra_per_epoch, replace=False)
        indices = np.concatenate((indices, extra_indices))
        np.random.shuffle(indices)
        assert len(indices) % (self.world_size * self.batch_size) == 0
        num_single = len(indices) // self.world_size
        return indices[self.rank*num_single:(self.rank+1)*num_single]

    def gen_new_list(self):
        np.random.seed(0)

        self.all_num = self.total_iter * self.batch_size * self.world_size
        iter_per_epoch = (len(self.dataset) -
                          1) // (self.batch_size * self.world_size) + 1
        self.num_per_epoch = iter_per_epoch * self.batch_size * self.world_size
        self.extra_per_epoch = self.num_per_epoch - len(self.dataset)
        repeat = (self.all_num - 1) // self.num_per_epoch + 1
        indices = []
        for i in range(repeat):
            indice = self.get_one_epoch_self_part()
            indices.append(indice)

        indices = np.concatenate(indices)
        indices = indices[:self.all_size_single]

        assert len(indices) == self.all_size_single

        return indices

    def __len__(self):
        return self.all_size_single

class RankedGivenIterationSampler(Sampler):
    def __init__(self, dataset, total_iter, batch_size, last_iter=0, shuffle=True):

        self.shuffle = shuffle
        self.dataset = dataset
        self.total_iter = total_iter
        self.batch_size = batch_size
        self.last_iter = last_iter

        self.total_size = self.total_iter * self.batch_size
        self.cur_size = self.last_iter * self.batch_size
        # self.indices = self.gen_new_list()
        self.indices = np.arange(len(self.dataset))
        self.call = 0

    def indice_generator(self):
        if self.shuffle:
            np.random.shuffle(self.indices)

        last_size = self.cur_size
        self.cur_size = 0
        pointer = 0
        while self.cur_size < last_size:
            remaining_size = last_size - self.cur_size
            indices = self.indices[pointer:pointer+remaining_size]
            self.cur_size += len(indices)
            if self.cur_size < last_size:
                pointer = 0
            else:
                pointer = pointer + len(indices)

        print('Training', self.total_size / len(self.indices), 'epoch; Shuffle =', self.shuffle, 'last_iter =', self.last_iter, 'pointer =', pointer, flush=True)

        while self.cur_size < self.total_size:
            #np.random.shuffle(self.indices)
            remaining_size = self.total_size - self.cur_size
            indices = self.indices[pointer:pointer+remaining_size]
            self.cur_size += len(indices)
            for item in indices:
                yield item
            if self.cur_size < self.total_size:
                pointer = 0
            else:
                pointer = pointer + len(indices)

    def __iter__(self):
        if self.call == 0:
            self.call = 1
            return self.indice_generator()
        else:
            raise RuntimeError("this sampler is not designed to be called more than once!!")

    def __len__(self):
        # note here we do not take last iter into consideration, since __len__
        # should only be used for displaying, the correct remaining size is
        # handled by dataloader
        return self.total_size

sampler_dict = {
    'distributed': DistributedSampler,
    'distributed_iteration': DistributedGivenIterationSampler,
    'distributed_epoch': DistributedEpochSampler,
    'ranked_iteration': RankedGivenIterationSampler
}

def build_sampler(cfg_sampler, cfg_dataset):
    batch_size = cfg_dataset['batch_size']
    dataset = cfg_dataset['dataset']
    # check step type: iteration or epoch ?
    if not getattr(cfg_dataset, 'max_iter', False):
        world_size = link.get_world_size()
        iter_per_epoch = (len(dataset) - 1) // (batch_size * world_size) + 1
        if cfg_sampler['type'] == "naive":
            total_iter = cfg_dataset['max_epoch'] * ((len(dataset) - 1) // batch_size + 1)  #125200
        else:
            total_iter = cfg_dataset['max_epoch'] * iter_per_epoch

    else:
        total_iter = cfg_dataset['max_iter']
    # initialize sampler kwargs
    if cfg_sampler['type'] in ['distributed', "naive", "random"]:
        sampler_kwargs = {'dataset': dataset}
    else:
        sampler_kwargs = {
            'dataset': dataset,
            'batch_size': batch_size,
            'total_iter': total_iter,
            'last_iter': cfg_dataset['last_iter']
        }
    cfg_sampler['kwargs'].update(sampler_kwargs)
    cfg_dataset['max_iter'] = total_iter
    cfg_dataset.pop('dataset')
    # print('cfg_dataset', cfg_dataset, flush=True)

    return sampler_dict[cfg_sampler['type']](**cfg_sampler['kwargs'])


import usb.core
import time

device = usb.core.find(idVendor = 0x0810, idProduct = 0x0001)

endpoint = device[0].interfaces()[0].endpoints()[0]
interface = device[0].interfaces()[0].bInterfaceNumber

device.reset()

if device.is_kernel_driver_active(interface):
    device.detach_kernel_driver(interface)

device.set_configuration()
endpaddr = endpoint.bEndpointAddress

list_len = 8 # after testing, all buttons and axes of one joystick were put in the first 8 places of the list
while True:
    ########################  I had two joysticks connected through 1 usb ###########################
    joy_data_1_from_usb = []
    joy_data_2_from_usb = []

    #joy1_axes[]=[R-axis up/down, R-axis left/right, L-axis up/down, L-axis left/right]
    #joy1_buttons[up/down,right/left, triangle, circle, x, rectangle, R1, R2, R3 , L1, L2, L3,select, start]
    joy1_axes = [0,0,0,0]
    joy1_buttons = [0,0,0,0,0,0,0,0,0,0,0,0]
    joy2_axes = [0,0,0,0]
    joy2_buttons = [0,0,0,0,0,0,0,0,0,0,0,0]

    read = device.read(endpaddr, 16) # after testing, all buttons and axes were put into the first 16 places in the list

    for i in range (list_len):
        joy_data_1_from_usb.append(read[i])
        joy_data_2_from_usb.append(read[i+8])
    joy_data_1_from_usb=joy_data_1_from_usb[1:7]
    joy_data_2_from_usb=joy_data_2_from_usb[1:7]

################################################# JOY 1 ####################################################

######################################### AXES ############################################

######################### LEFT AXES ################################
    if joy_data_1_from_usb[3] < 128:           #UP
        joy1_axes[2]= (joy_data_1_from_usb[1] * (-1) +128) / 128
    elif joy_data_1_from_usb[3] > 128:         #Down
        joy1_axes[2]= (joy_data_1_from_usb[1] * (-1) +127) / 128
    elif joy_data_1_from_usb[2] < 128:         #Left
        joy1_axes[3]= (joy_data_1_from_usb[2]  +128) / 128
    elif joy_data_1_from_usb[2] > 128:         #Right
        joy1_axes[3]= (joy_data_1_from_usb[2]  *(-1) +126) / 126

######################## RIGHT AXES ################################
    if joy_data_1_from_usb[1] < 128:           #UP
        joy1_axes[0]= (joy_data_1_from_usb[1] * (-1) +128) / 128
    elif joy_data_1_from_usb[1] > 128:         #Down
        joy1_axes[0]= (joy_data_1_from_usb[1] * (-1) +126) / 126
    elif joy_data_1_from_usb[0] < 128:         #Left
        joy1_axes[1]= (joy_data_1_from_usb[0]  +128) / 128
    elif joy_data_1_from_usb[0] > 128:         #Right
        joy1_axes[1]= (joy_data_1_from_usb[0]  *(-1) +126) / 126

############################ BUTTONS ###############################
    if joy_data_1_from_usb[4] == 0:         #UP
        joy1_buttons[0]= 1
    elif joy_data_1_from_usb[4] == 4:       #DOWN
        joy1_buttons[0]= -1.
    elif joy_data_1_from_usb[4] == 2:       #RIGHT
        joy1_buttons[1]= 1
    elif joy_data_1_from_usb[4] == 6:       #LEFT
        joy1_buttons[1]= -1
    elif joy_data_1_from_usb[4] == 31:      #Triangle
        joy1_buttons[2]= 1
    elif joy_data_1_from_usb[4] == 47:      #Circle
        joy1_buttons[3]= 1
    elif joy_data_1_from_usb[4] == 79:      #X
        joy1_buttons[4]= 1
    elif joy_data_1_from_usb[4] == 143:     #Rectangle
        joy1_buttons[5]= 1
    if joy_data_1_from_usb[5] == 1:         #L1
        joy1_buttons[9]= 1
    elif joy_data_1_from_usb[5] == 4:       #L2
        joy1_buttons[10]= 1
    elif joy_data_1_from_usb[5] == 2:       #R1
        joy1_buttons[6]= 1
    elif joy_data_1_from_usb[5] == 8:       #R2
        joy1_buttons[7]= 1
    elif joy_data_1_from_usb[5] == 64:      #L3
        joy1_buttons[8]= 1
    elif joy_data_1_from_usb[5] == 128:     #R3
        joy1_buttons[11]= 1
    elif joy_data_1_from_usb[5] == 16:      #Select
        joy1_buttons[12]= 1
    elif joy_data_1_from_usb[5] == 32:      #Start
        joy1_buttons[13]= 1

################################################# JOY 2 ####################################################

######################################### AXES ############################################

######################### LEFT AXES ################################
    if joy_data_2_from_usb[3] < 128:           #UP
        joy2_axes[2]= (joy_data_2_from_usb[3] * (-1) +128) / 128
    elif joy_data_2_from_usb[3] > 128:         #Down
        joy2_axes[2]= (joy_data_2_from_usb[3] * (-1) +127) / 128
    elif joy_data_2_from_usb[2] < 128:         #Left
        joy2_axes[3]= (joy_data_2_from_usb[2]  +128) / 128
    elif joy_data_2_from_usb[2] > 128:         #Right
        joy2_axes[3]= (joy_data_2_from_usb[2] * (-1) +127) / 128

######################## RIGHT AXES ################################
    if joy_data_2_from_usb[1] < 128:           #UP
        joy2_axes[0]= (joy_data_2_from_usb[1] * (-1) +128) / 128
    elif joy_data_2_from_usb[1] > 128:         #Down
        joy2_axes[0]= (joy_data_2_from_usb[1] * (-1) +127) / 128
    elif joy_data_2_from_usb[0] < 128:         #Left
        joy2_axes[1]= (joy_data_2_from_usb[0]  +128) / 128
    elif joy_data_2_from_usb[0] > 128:         #Right
        joy2_axes[1]= (joy_data_2_from_usb[0] * (-1) +127) / 128

############################ BUTTONS ###############################
    if joy_data_2_from_usb[4] == 0:         #UP
        joy2_buttons[0]= 1
    elif joy_data_2_from_usb[4] == 4:       #DOWN
        joy2_buttons[0]= -1.
    elif joy_data_2_from_usb[4] == 2:       #RIGHT
        joy2_buttons[1]= 1
    elif joy_data_2_from_usb[4] == 6:       #LEFT
        joy2_buttons[1]= -1
    elif joy_data_2_from_usb[4] == 31:      #Triangle
        joy2_buttons[2]= 1
    elif joy_data_2_from_usb[4] == 47:      #Circle
        joy2_buttons[3]= 1
    elif joy_data_2_from_usb[4] == 79:      #X
        joy2_buttons[4]= 1
    elif joy_data_2_from_usb[4] == 143:     #Rectangle
        joy2_buttons[5]= 1
    if joy_data_2_from_usb[5] == 1:         #L1
        joy2_buttons[9]= 1
    elif joy_data_2_from_usb[5] == 4:       #L2
        joy2_buttons[10]= 1
    elif joy_data_2_from_usb[5] == 2:       #R1
        joy2_buttons[6]= 1
    elif joy_data_2_from_usb[5] == 8:       #R2
        joy2_buttons[7]= 1
    elif joy_data_2_from_usb[5] == 64:      #L3
        joy2_buttons[8]= 1
    elif joy_data_2_from_usb[5] == 128:     #R3
        joy2_buttons[11]= 1
    elif joy_data_2_from_usb[5] == 16:      #Select
        joy2_buttons[12]= 1
    elif joy_data_2_from_usb[5] == 32:      #Start
        joy2_buttons[13]= 1

    print("Joy 1: ", joy1_axes, "                    ", joy1_buttons)
    print("Joy 2: ", joy2_axes, "                    ", joy2_buttons)


# Create your views here.
from rest_framework.response import Response
from rest_framework import generics, status
from rest_framework.permissions import AllowAny
from rest_framework_simplejwt.views import TokenObtainPairView

from djangogamers.apps.authentication.models import User
from djangogamers.apps.authentication.serializers import RegistrationSerializer, CustomTokenObtainPairSerializer

class RegistrationAPIView(generics.CreateAPIView):
    permission_classes = (AllowAny,)
    serializer_class = RegistrationSerializer

    def post(self, request, **kwargs):
        serializer = self.serializer_class(data=request.data)
        serializer.is_valid(raise_exception=True)
        serializer_data = serializer.validated_data
        serializer.save()
        res = {}

        try:
            user = User.objects.get(
                email=serializer_data.get('email'))
        except User.DoesNotExist:
            return Response({'error': 'user does not exist'}, status=status.HTTP_200_OK)

        if user.is_active:
            res.update(
                {
                    'success_message': 'Account creation was successful',
                    'status': status.HTTP_201_CREATED,
                    'refresh': user.tokens()['refresh'],
                    'access': user.tokens()['access']
                }
            )
        else:
            res.update({
                'activate account': 'please check your email to activate account'
            })

        return Response(res, status=res.get('status'))

class LoginAPIView(TokenObtainPairView):
    permission_classes = [AllowAny]
    serializer_class = CustomTokenObtainPairSerializer


# -*- coding: utf-8 -*-
import json

import scrapy

from ..items import SoItem

class SoSpider(scrapy.Spider):
    name = 'so'
    allowed_domains = ['image.so.com']

    def start_requests(self):
        # for i in range(0,150,30):
        for i in range(5):
            sn = i * 30
            url = 'https://image.so.com/zjl?ch=beauty&sn={}&listtype=new&temp=1'.format(str(sn))
            yield scrapy.Request(
                url=url,
                callback=self.parse_image
            )

    # response是json合适的字符串
    def parse_image(self, response):
        html = json.loads(response.text)
        for img in html['list']:
            item = SoItem()
            item['img_link'] = img['qhimg_url']
            yield item