''' Project Euler 79
A common security method used for online banking is to ask the user for three
random characters from a passcode. For example, if the passcode was 531278,
they may ask for the 2nd, 3rd, and 5th characters;
the expected reply would be: 317.

The text file, keylog.txt, contains fifty successful login attempts.

Given that the three characters are always asked for in order,
analyse the file so as to determine the shortest possible secret passcode
of unknown length.
'''

import os
from functools import reduce

__location__ = os.path.realpath(
    os.path.join(os.getcwd(), os.path.dirname(__file__)))

with open(os.path.join(__location__, 'p079_keylog.txt')) as keylog_file:
    keylog_text = keylog_file.read().splitlines()

keylog_text = list(set(keylog_text))

graph = {}
for n in keylog_text:
    for i in range(1, len(n)):
        if not n[i] in graph:
            graph[n[i]] = set()
        graph[n[i]].update(n[i-1])

def topological_sort(graph):
    if len(graph) == 0:
        return
    graph = graph.copy()
    for i, j in graph.items():
        j.discard(i)
    root_nodes = reduce(set.union, graph.values()) - set(graph.keys())
    for r in root_nodes:
        graph[r] = set()
    while True:
        sorting = set(key for key, value in graph.items() if len(value) == 0)
        if len(sorting) == 0:
            break
        yield sorting

        graph = {key: value - sorting for key, value in graph.items()
                 if key not in sorting}

print(list(topological_sort(graph)))

''' Show rate of occurance
first, middle, last = {}, {}, {}

for each in keylog_text:
    if each[0] not in first.keys():
        first.update({each[0]: 1})
    else:
        count_first = first.pop(each[0]) + 1
        first.update({each[0]: count_first})
    if each[1] not in middle.keys():
        middle.update({each[1]: 1})
    else:
        count_middle = middle.pop(each[1]) + 1
        middle.update({each[1]: count_middle})
    if each[2] not in last.keys():
        last.update({each[2]: 1})
    else:
        count_last = last.pop(each[2]) + 1
        last.update({each[2]: count_last})
'''


from panda3d.core import *
from toontown.toonbase import TTLocalizer
from . import ZoneUtil
from toontown.toonbase import ToontownGlobals
from toontown.toontowngui import TeaserPanel

class TrialerForceAcknowledge:

    def __init__(self, doneEvent):
        self.doneEvent = doneEvent
        self.dialog = None
        return

    def enter(self, destHood):
        doneStatus = {}

        def letThrough(self = self, doneStatus = doneStatus):
            doneStatus['mode'] = 'pass'
            messenger.send(self.doneEvent, [doneStatus])

        if not base.restrictTrialers:
            letThrough()
            return
        if base.roamingTrialers:
            letThrough()
            return
        if base.cr.isPaid():
            letThrough()
            return
        if ZoneUtil.getCanonicalHoodId(destHood) in (ToontownGlobals.ToontownCentral, ToontownGlobals.MyEstate, ToontownGlobals.GoofySpeedway):
            letThrough()
            return
        else:
            try:
                base.localAvatar.b_setAnimState('neutral', 1)
            except:
                pass

        doneStatus['mode'] = 'fail'
        self.doneStatus = doneStatus
        self.dialog = TeaserPanel.TeaserPanel(pageName='otherHoods', doneFunc=self.handleOk)

    def exit(self):
        if self.dialog:
            self.dialog.cleanup()
            self.dialog.unload()
            self.dialog = None
        return

    def handleOk(self):
        messenger.send(self.doneEvent, [self.doneStatus])


from pyllicalabs import *
import datetime
from datetime import date
from dateutil.relativedelta import relativedelta

relativePath = "/.../"

allPath   = relativePath + "/all_texts.txt"
getPath   = relativePath + "/get_text.txt"
outputDir = relativePath + "/DATABASE/"

def scrapping():
    # Récupération de l'état
    getFile = open(getPath, "r")
    getInfos = [int(getFile.readline().replace('\n', '')) for _ in range(8)]
    getFile.close()

    # Récupération de la base de données
    allFile = open(allPath, "r")
    paths = [allFile.readline().replace('\n', '') for _ in range(1500)]
    allFile.close()

    # Récupération du champ d'action
    startIndex = getInfos[6] - 1
    endIndex   = getInfos[7] - 1

    if startIndex > endIndex :
        print("Travail terminé.")
        return

    if getInfos[0] == 0 :
        print("Préparation pour le premier document")
        startDate  = datetime.datetime(int(paths[2::11][startIndex]),
                                       int(paths[3::11][startIndex]),
                                       int(paths[4::11][startIndex]))
        endDate    = datetime.datetime(int(paths[5::11][startIndex]),
                                       int(paths[6::11][startIndex]),
                                       int(paths[7::11][startIndex]))
    else:
        startDate  = datetime.datetime(getInfos[0], getInfos[1], getInfos[2])
        endDate    = datetime.datetime(getInfos[3], getInfos[4], getInfos[5])

    if startDate > endDate :
        print("Préparation pour le prochain document")
        startIndex += 1

        # Incrément du texte et réinitialisation de la date de début
        getFile = open(getPath, "w")
        getFile.writelines([paths[2::11][startIndex] + "\n",
                            paths[3::11][startIndex] + "\n",
                            paths[4::11][startIndex] + "\n",
                            paths[5::11][startIndex] + "\n",
                            paths[6::11][startIndex] + "\n",
                            paths[7::11][startIndex] + "\n",
                            str(startIndex + 1)      + "\n",
                            str(endIndex   + 1)])
        getFile.close()
        return

    # --- Traitement du texte actuel à la date actuelle ---
    # 1) Mémorisation des paramètres à utiliser
    text_url = paths[1::11][startIndex]
    text_year = startDate.year
    text_month = startDate.month
    text_day = startDate.day
    text_title = outputDir + str(text_year) + "/" + str(text_month) + "/" + paths[::11][startIndex]

    # 2) Incrémentation
    if paths[9::11][startIndex] == 'j':
        startDate += datetime.timedelta(days = int(paths[8::11][startIndex]))
    elif paths[9::11][startIndex] == 'm':
        startDate += relativedelta(months =+ int(paths[8::11][startIndex]))

    # 3) Préparation de la valeur suivante
    getFile = open(getPath, "w")
    getFile.writelines([str(startDate.year ) + "\n",
                        str(startDate.month) + "\n",
                        str(startDate.day  ) + "\n",
                        str(endDate.year   ) + "\n",
                        str(endDate.month  ) + "\n",
                        str(endDate.day    ) + "\n",
                        str(startIndex + 1 ) + "\n",
                        str(endIndex   + 1 ) + "\n"])

    # 4) Récupération de la donnée
    print("Appel de :")
    print("pdfpress(url=\""  + text_url        + "\",")
    print("    title=\""     + text_title      + "\",")
    print("    year="        + str(text_year)  + ",")
    print("    month="       + str(text_month) + ",")
    print("    day="         + str(text_day)   + ",")
    print("    item=1,\nrate=1)\n")

    pdfpress(url=      text_url,
             title=    text_title,
             year=     text_year,
             month=    text_month,
             day=      text_day,
             item=     1,
             rate=     1)

scrapping()


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

from tkinter import *
from math import *
from JCVD import *
from variables import *

color=Color()

######################################################## INTERFACE ########################################################################################################################
class Interface(Frame):

	def __init__(self, window):
		Frame.__init__(self, window, width=width, height=height)
		self.window = window

		self.initialize()
		self.pack(fill=BOTH)

	#Fonction comprenant tout ce que l'interface doit contenir lors de son initialisation
	def initialize(self):

		#Simulateur et zone de simulation (caneva ou sont affichées route et voitures)
		self.simulator = LabelFrame(self, text='Simulateur')
		self.zone = Canvas(self.simulator, width=width, height=height, bg=color.areaColor)
		self.zone.pack()
		self.simulator.pack(side=LEFT,expand=Y, fill=BOTH, pady=2, padx=2)
		self.var_road = RouteVirage(nbOfLanes=2, zone = self.zone)
		self.var_road.draw(self.zone)

		#Variables modifiables par l utilisateur
		self.var_time = IntVar()
		self.var_time.set(20)  # valeur par défaut

		self.var_traffic = IntVar()
		self.var_traffic.set(30)

		self.var_nbOfLanes = IntVar()
		self.var_nbOfLanes.set(2)

		self.var_speed = DoubleVar()
		self.var_speed.set(1)

		self.var_roadName = StringVar()
		self.var_roadName.set('RouteVirage')
		self.var_road = RouteVirage(zone=self.zone, nbOfLanes=self.var_nbOfLanes.get())

		self.var_sound = BooleanVar()
		self.var_sound.set(True)

		self.var_modeMalozieux = BooleanVar()
		self.var_modeMalozieux.set(False)

		#Interface utilisateur : controles
		self.controles = LabelFrame(self, text='Controles')
		self.controles.pack(side=RIGHT, expand=Y, fill=BOTH, pady=2, padx=2)
		self.displayControles()

		#Menu haut
		self.menubar = Menu(self)

		self.optionmenu = Menu(self.menubar, tearoff=0)
		self.menubar.add_cascade(label="Options", menu=self.optionmenu)
		self.optionmenu.insert_checkbutton(1,label="Mode malozieux", variable=self.var_modeMalozieux, command=self.selectColorMod)
		self.optionmenu.insert_checkbutton(1,label="Activer/Désactiver les sons", variable=self.var_sound)

		self.helpmenu = Menu(self.menubar, tearoff=0)
		self.menubar.add_cascade(label="Aide", menu=self.helpmenu)
		self.helpmenu.add_command(label="À propos", command=self.popJCVD )

		self.menubar.add_command(label="Quitter", command=quit)
		self.window.config(menu=self.menubar)

	#Afficher l'UI
	def displayControles(self) :

		controles = self.controles

		#"Temps"
		scale_time=Scale(controles, from_=2, to=40, resolution=2, length=300, orient=HORIZONTAL, label='Fréquence de rafraîchissement (ms)', variable=self.var_time)
		scale_time.pack()

		#Vitesse
		scale_speed=Scale(controles, from_=0.5, to=2, resolution=0.1, length=300, orient=HORIZONTAL, label="Multiplicateur de vitesse à l'apparition", variable=self.var_speed)
		scale_speed.pack()

		#Traffic
		traffic = LabelFrame(controles, text='Traffic')
		values = [1000000, 50, 30, 10]
		texts = ['presque surement rien', 'peu dense', 'dense', 'très dense']

		for i in range(len(values)):
			b = Radiobutton(traffic, variable=self.var_traffic, text=texts[i], value=values[i])
			b.pack(side=LEFT, expand=1)

		traffic.pack()

		#Menu selection (pour les routes)
		roads = ['RouteVirage', 'RouteOvale', 'RouteDroite']
		roadFrame = LabelFrame(controles, text='Type de route')
		routeMenu = OptionMenu(roadFrame, self.var_roadName, * roads, command = self.resetZone)
		routeMenu.pack()
		roadFrame.pack()

		#Nombre de voies
		nbOfLanes = LabelFrame(controles, text='Nombre de voies')
		lanes = [1, 2, 3]
		lanesMenu = OptionMenu(nbOfLanes, self.var_nbOfLanes, * lanes, command = self.resetZone)
		nbOfLanes.pack()
		lanesMenu.pack(side=LEFT)

	# Affiche un popup sur lequel est inscrit une citation de Jean-Claude Van Damme
	def popJCVD(self):
		top = Toplevel()
		top.title("À propos de Jean Claude Van Damme ...")
		msg = Message(top, text=randomPhrase(JCVD) + "  - JCVD")
		msg.pack()
		button = Button(top, text="Ok Jean-Claude", command=top.destroy)
		button.pack()

	def selectColorMod(self):
		if self.var_modeMalozieux.get()==False:
			color.roadColor = 'grey'
			color.markingColor = 'white'
			color.edgeColor = 'black'
			color.areaColor = 'green'
			self.resetZone(0)
		else:
			color.roadColor = "yellow"
			color.markingColor = "deeppink"
			color.edgeColor = "orange"
			color.areaColor = "purple"
			self.resetZone(0)

	def resetZone(self,var):
		roads = {'RouteVirage':RouteVirage, 'RouteOvale':RouteOvale, 'RouteDroite':RouteDroite}
		self.var_road = roads.get(self.var_roadName.get())(zone=self.zone, nbOfLanes=self.var_nbOfLanes.get())
		self.zone.delete(ALL)
		self.zone.configure(bg=color.areaColor)
		self.var_road.draw(self.zone)
		self.zone.pack()

##########################################################################################################################################################################################

############################################# ROUTES ######################################################################################################################################

class Route():

	def __init__(self, speedMax = 130, nbOfLanes = 2, zone = None):
		self.zone = zone
		self.speedMax = speedMax
		self.nbOfLanes = nbOfLanes           #nombre de voies sur la route

		#Création d'une liste de listes : cette liste contient les listes des véhicules sur une voie
		#Exemple : listVehiclesLane[1] renverra la liste de tous les véhicules situées sur la voie 2
		self.listVehiclesLane = []
		for i in range(nbOfLanes):
			self.listVehiclesLane.append([])

class RouteDroite(Route):

	def draw(self, zone) :
		self.listVehiclesLane.append([]) #lane -1 est la voie d'insertion

		Canvas.create_rectangle(zone, 400,0, 490,1002, fill=color.roadColor, outline=color.edgeColor)
		Canvas.create_line(zone, 430, 0, 430,1002, fill = color.markingColor, dash=(5,3))
		Canvas.create_line(zone, 460, 0, 460,1002, fill = color.markingColor, dash=(5,3))

		Canvas.create_rectangle(zone, 400 + self.nbOfLanes*30,-1, 1002, 1002, fill=color.areaColor, outline=color.edgeColor)

		#sortie
		Canvas.create_rectangle(zone, 0,950, 350,920, fill=color.roadColor, outline=color.edgeColor)
		Canvas.create_rectangle(zone, 370,670, 400,900, fill=color.roadColor, outline=color.roadColor)
		Canvas.create_line(zone, 370,670, 370,900, fill=color.edgeColor)

		Canvas.create_arc(zone, 300,850, 400, 950, start=0, extent=-90, fill=color.roadColor, outline=color.roadColor, style='pieslice')
		Canvas.create_arc(zone, 300,850, 400, 950, start=0, extent=-90, fill=color.roadColor, outline=color.edgeColor, style='arc')

		Canvas.create_arc(zone, 330,880, 370, 920, start=0, extent=-90, fill=color.areaColor, outline=color.areaColor, style='pieslice')
		Canvas.create_arc(zone, 330,880, 370, 920, start=0, extent=-90, fill=color.areaColor, outline=color.edgeColor, style='arc')

		ptsTriangle2 = [(370,670), (400,670),    (400,650)]
		Canvas.create_polygon(zone, ptsTriangle2, fill=color.roadColor, outline=color.roadColor)
		Canvas.create_line(zone, 370,670, 401,649, fill=color.edgeColor)

		Canvas.create_line(zone, 400,652, 400,899, fill=color.markingColor, dash=(3,3))

	def convert(self, t, lane, segment) :
		if lane < 0 :

			if t>=100 and t<=400 :
				X = 415 + 30*lane
				Y = t
				segment = 3

			if t<100 :
				X = 100 + 35*cos((t-50)/(40*pi)-pi/2)
				Y = 100 + 35*sin((t-50)/(40*pi)-pi/2)
				segment = 2

			if t<50 :
				X = t*350/50
				Y = 65
				segment = 2

			if t>=650 and t<=900 :
				X = 415 + 30*lane
				Y = t
				segment = 4

			if t>900 :
				X = 350 + 35*cos((t-900)/(10*pi))
				Y = 900 + 35*sin((t-900)/(10*pi))
				segment = 4

			if t>950 :
				X = 350-(t-950)*350/50
				Y = 935
				segment = 4

		elif lane >= 0 :
			X = 415 + lane*30
			Y = t
			segment = 1

		if t > 1001 :
			segment = 0

		return(X,Y,segment)

class RouteVirage(Route):

	######## fonction de dessin de la route ################################
	def draw(self, zone) :
		#3 routes droites
		Canvas.create_rectangle(zone, 0,10+(3-self.nbOfLanes)*30, 800,100, fill=color.roadColor, outline=color.edgeColor)
		Canvas.create_rectangle(zone, 820,120, 910-(3-self.nbOfLanes)*30,820, fill=color.roadColor, outline=color.edgeColor)
		Canvas.create_rectangle(zone, 0,840, 800,930-(3-self.nbOfLanes)*30, fill=color.roadColor, outline=color.edgeColor)

		#virage haut droite
		Canvas.create_arc(zone, 780-self.nbOfLanes*30,100-self.nbOfLanes*30, 820+self.nbOfLanes*30,140+self.nbOfLanes*30 , start=0, extent=90, fill=color.roadColor, outline=color.roadColor, style='pieslice') #route
		Canvas.create_arc(zone, 780,100, 820,140 , start=0, extent=90, fill=color.areaColor, outline=color.areaColor, style='pieslice') #cache virage
		Canvas.create_arc(zone, 780-self.nbOfLanes*30,100-self.nbOfLanes*30, 820+self.nbOfLanes*30,140+self.nbOfLanes*30 , start=0, extent=90, fill=color.roadColor, outline=color.edgeColor, style='arc') #bord ext
		Canvas.create_arc(zone, 780,100, 820,140 , start=0, extent=90, fill=color.areaColor, outline=color.edgeColor, style='arc') #bord int
		#virage bas droite
		Canvas.create_arc(zone, 780-self.nbOfLanes*30,800-self.nbOfLanes*30, 820+self.nbOfLanes*30,840+self.nbOfLanes*30 , start=270, extent=90, fill=color.roadColor, outline=color.roadColor, style='pieslice')
		Canvas.create_arc(zone, 780,800, 820,840 , start=270, extent=90, fill=color.areaColor, outline=color.areaColor, style='pieslice')
		Canvas.create_arc(zone, 780-self.nbOfLanes*30,800-self.nbOfLanes*30, 820+self.nbOfLanes*30,840+self.nbOfLanes*30 , start=270, extent=90, fill=color.roadColor, outline=color.edgeColor, style='arc')
		Canvas.create_arc(zone, 780,800, 820,840 , start=270, extent=90, fill=color.areaColor, outline=color.edgeColor, style='arc')

		#marquages
		#for i in range(self.nbOfLanes)
		if self.nbOfLanes>=2 :
			Canvas.create_line(zone, 0,70, 800,70, fill=color.markingColor, dash=(5,3), width=1)
			Canvas.create_line(zone, 850,120, 850,820, fill=color.markingColor, dash=(5,3), width=1)
			Canvas.create_line(zone, 0,870, 800,870, fill=color.markingColor, dash=(5,3), width=1)

			Canvas.create_arc(zone, 750,70, 850,170 , start=0, extent=90, fill=color.roadColor, outline=color.markingColor, style='arc', dash=(5,3))
			Canvas.create_arc(zone, 850,870, 750,770 , start=270, extent=90, fill=color.roadColor, outline=color.markingColor, style='arc', dash=(5,3))

		if self.nbOfLanes==3 :
			Canvas.create_line(zone, 0,40, 800,40, fill=color.markingColor, dash=(5,3), width=1)
			Canvas.create_line(zone, 880,120, 880,820, fill=color.markingColor, dash=(5,3), width=1)
			Canvas.create_line(zone, 0,900, 800,900, fill=color.markingColor, dash=(5,3), width=1)

			Canvas.create_arc(zone, 720,40, 880,200 , start=0, extent=90, fill=color.roadColor, outline=color.markingColor, style='arc', dash=(5,3))
			Canvas.create_arc(zone, 880,900, 720,740 , start=270, extent=90, fill=color.roadColor, outline=color.markingColor, style='arc', dash=(5,3))

	####### Converti t en couple X,Y ######
	def convert(self, t, lane, segment) :

		if segment==1 :
		# morceau 1 (droite horizontale)
			X = t
			Y = 55 + (1-lane)*30

			if X>=800 :
				segment = 2

		if segment==2 :
		#morceau 2 (arc1)
			X = 800 + (35+(lane)*30)* cos((t-800)/(20*pi)-pi/2)
			Y = 120 + (35+(lane)*30)* sin((t-800)/(20*pi)-pi/2)

			if Y>=125 :
				segment = 3

		if segment==3 :
		#morceau 3 (droite verticale)
			X = 835 + lane*30
			Y = (t-903) + 120

			if Y>=825 :
				segment = 4

		if segment==4 :
		#morceau 4 (arc2)
			X = 800 + (35+lane*30)* cos((t-1605)/(20*pi)+0.1)
			Y = 820 + (35+lane*30)* sin((t-1605)/(20*pi)+0.1)

			if X<=800 :
				segment = 5

		if segment==5 :
		#morceau 5 (droite horizontale)
			X = (-t+1697) + 800
			Y = 855 + lane*30

			if X<=0 :
				segment = 0

		return (X,Y,segment)

class RouteOvale(Route) :

	def draw(self,zone) :
		nbVoies=self.nbOfLanes
		Canvas.create_oval(zone, 40,40, 960,960, width=1, fill=color.roadColor)
		for i in range (nbVoies):
			Canvas.create_oval(zone, 70 + 30 * i,70 + 30 * i, 930 - 30 * i,930 - 30 * i, width=1, outline=color.markingColor, dash=(3,5))
		Canvas.create_oval(zone, 40+30*nbVoies,40+30*nbVoies, 960-30*nbVoies,960-30*nbVoies, width=1, fill=color.areaColor)

	def convert(self, t, posLine, segment) :
		#on met ça parce que le dessin en fonction des voies est plus long à faire sinon, et donc voilàààà
		if self.nbOfLanes == 1 :
			posLine += 2
		elif self.nbOfLanes == 2 :
			posLine += 1

		#un cercle classique, avec le - au sinus pour tourner dans le bon sens (on est pas des anglais hein)
		X = 500 + (385+30*(posLine))* cos(t/(100*pi))
		Y = 500	+ (385+30*(posLine))* sin(-t/(100*pi))

		#Segment = 10 une fois un tour effectué, pour le reset un peu buggé
		if t >= 1975 :
			segment = 10
		else :
			segment = 1

		return (X,Y,segment)

##########################################################################################################################################################################################


import tkinter as tk
from tkinter import messagebox
import math

# Pencere oluşturmak için nesne oluşturulur
# Bu nesnenin özelliklerini değiştirerek ve metodlarını kullanarak
# pencereyi şekillendiririz
window = tk.Tk()

# title metodu Pencerenin başlığını, programın ismini belirtir
window.title("Logaritma ve Üs Hesaplama Programı")

# geometri metodu pencere boyutlarını ayarlamaya yarar
# buradaki 500 x eskesnindeki piksel sayısını
# 150 sayısı ise y eksenindeki piksel sayısını temsil eder
window.geometry("500x150")

# hgLabel ile penceremizde görünecek bir yazı nesnesini temsil ediyoruz
# Label ın hangi pencerede olacağını, üzerinde ne yazacağını ve fontunu belirttik
# place metodu ile de konumunu ayarlıyoruz
hgLabel = tk.Label(window, text="Hoşgeldiniz", font="Ariel 13")
hgLabel.place(relx=0.5, rely=0.2, anchor="center")

'''
    Bu kısımda kullanıcıdan veri almak için text alanları oluşturdum
    Öncesinde de bu text alanlarının içine ne yazılması gerektiğini
    belirten label lar yerleştirdim, konumlardaki anchor değerleri
    east(doğu), west(batı) şeklinde ve relx değerleri de bu anchor değerine
    göre uzaklıkları belirtiyor
'''
questionLabel = tk.Label(window, text="Birinci sayı : ", font="Ariel 13")
questionLabel.place(relx=0.3, rely=0.4, anchor="w")
userInput = tk.Entry(window, width=20)
userInput.place(relx=0.5, rely=0.4, anchor="w")

questionLabel2 = tk.Label(window, text="İkinci sayı : ", font="Ariel 13")
questionLabel2.place(relx=0.3, rely=0.6, anchor="w")
userInput2 = tk.Entry(window, width=20)
userInput2.place(relx=0.5, rely=0.6, anchor="w")

# Hesaplama işleminin başlaması için bir buton oluşturup
# bu butonun tıklandığında aktif olacak fonksiyonu tanımlıyorum
def Hesapla():
    try:
        # kullanıcıdan alınan verileri sayıya dönüştürürüz
        # hata olması durumunda ekrana hata mesajı fırlatan
        # message box kullanacağız bunun için try, except
        # modülünü kullanıyoruz
        x = int(userInput.get())
        y = int(userInput2.get())
        sqarti = x**y
        logg = math.log2(x)
        strn = f"x**y : {str(sqarti)} --- log(x) : {str(logg)}"
        hgLabel.configure(text=strn)
    except:
        messagebox.showwarning(title="Hata", message="Girdiler hatalıdır. Kontrol ediniz")
        raise

hesaplaButton = tk.Button(window, text="Hesapla", font="Ariel 10", fg="red", command=Hesapla)
hesaplaButton.place(relx=0.5, rely=0.8, anchor="center")

# mainloop metodu pencere açık kaldığı sürece programın çalışmasını
#ve sürekli açık kalmasını sağlar
window.mainloop()


"""
Output Format

For each test case, print the number of square integers in the range on a new line.

Sample Input

2
3 9
17 24
Sample Output

2
0
"""

#!/bin/python3

import sys

def squares(arr):
    count = 0
    for i in range(arr[0], (arr[1]+1)):
        if sqrt(i) % 1 == 0:
            count += 1
    print(count)

def sqrt(x):
    return x**(1/2)

if __name__ == "__main__":
    q = int(input().strip())
    arr = []
    for a0 in range(q):
        a, b = input().strip().split(' ')
        a, b = [int(a), int(b)]
        arr.append(a)
        arr.append(b)
        squares(arr)
        arr = []


from django.contrib import admin

from .models import Message

class MessageAdmin(admin.ModelAdmin):
    fields = ('method', 'body', 'parsed')
    readonly_fields = ('date',)
    list_display = ('method', 'body', 'parsed', 'date')

admin.site.register(Message, MessageAdmin)


# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations

class Migration(migrations.Migration):

    dependencies = [
        ('mafia_app', '0007_death_game'),
    ]

    operations = [
        migrations.RemoveField(
            model_name='player',
            name='redditID',
        ),
        migrations.AddField(
            model_name='player',
            name='alignment',
            field=models.CharField(default=b'U', max_length=1, choices=[(b'U', b'Unknown'), (b'M', b'Mafia'), (b'T', b'Town'), (b'O', b'Other')]),
        ),
        migrations.AddField(
            model_name='player',
            name='notes',
            field=models.TextField(blank=True),
        ),
        migrations.AddField(
            model_name='player',
            name='role',
            field=models.CharField(max_length=50, blank=True),
        ),
    ]


"""Transition and sequence analysis of neighborhood change."""

from time import time
from warnings import warn

import geopandas as gpd
import numpy as np
import pandas as pd
from giddy.markov import Markov, Spatial_Markov
from giddy.sequence import Sequence
from libpysal.weights import Voronoi, lag_categorical
from libpysal.weights.contiguity import Queen, Rook
from libpysal.weights.distance import KNN, DistanceBand, Kernel
from numpy.random import PCG64, SeedSequence, default_rng
from sklearn.cluster import AgglomerativeClustering
from tqdm.auto import tqdm

Ws = {
    "queen": Queen,
    "rook": Rook,
    "voronoi": Voronoi,
    "knn": KNN,
    "kernel": Kernel,
    "distanceband": DistanceBand,
}

def transition(
    gdf,
    cluster_col,
    temporal_index="year",
    unit_index="geoid",
    w_type="rook",
    w_options=None,
    permutations=0,
):
    """
    Model neighborhood change as a discrete spatial Markov process.

    Parameters
    ----------
    gdf : geopandas.GeoDataFrame or pandas.DataFrame
        Long-form geopandas.GeoDataFrame or pandas.DataFrame containing neighborhood
        attributes with a column defining neighborhood clusters.
    cluster_col : string or int
        Column name for the neighborhood segmentation, such as
        "ward", "kmeans", etc.
    temporal_index : string, optional
        Column defining time and or sequencing of the long-form data.
        Default is "year".
    unit_index : string, optional
        Column identifying the unique id of spatial units.
        Default is "geoid".
    w_type : string, optional
        Type of spatial weights type ("rook", "queen", "knn" or
        "kernel") to be used for spatial structure. Default is
        None, if non-spatial Markov transition rates are desired.
    w_options : dict
        additional options passed to a libpysal weights constructor
        (e.g. `k` for a KNN weights matrix)
    permutations : int, optional
        number of permutations for use in randomization based
        inference (the default is 0).

    Returns
    --------
    mar : giddy.markov.Markov instance or giddy.markov.Spatial_Markov
        if w_type=None, a classic Markov instance is returned.
        if w_type is given, a Spatial_Markov instance is returned.

    Examples
    --------
    >>> from geosnap import Community
    >>> columbus = Community.from_ltdb(msa_fips="18140")
    >>> columbus1 = columbus.cluster(columns=['median_household_income',
    ... 'p_poverty_rate', 'p_edu_college_greater', 'p_unemployment_rate'],
    ... method='ward', n_clusters=6)
    >>> gdf = columbus1.gdf
    >>> a = transition(gdf, "ward", w_type="rook")
    >>> a.p
    array([[0.79189189, 0.00540541, 0.0027027 , 0.13243243, 0.06216216,
        0.00540541],
       [0.0203252 , 0.75609756, 0.10569106, 0.11382114, 0.        ,
        0.00406504],
       [0.00917431, 0.20183486, 0.75229358, 0.01834862, 0.        ,
        0.01834862],
       [0.1959799 , 0.18341709, 0.00251256, 0.61809045, 0.        ,
        0.        ],
       [0.32307692, 0.        , 0.        , 0.        , 0.66153846,
        0.01538462],
       [0.09375   , 0.0625    , 0.        , 0.        , 0.        ,
        0.84375   ]])
    >>> a.P[0]
    array([[0.82119205, 0.        , 0.        , 0.10927152, 0.06622517,
        0.00331126],
       [0.14285714, 0.57142857, 0.14285714, 0.14285714, 0.        ,
        0.        ],
       [0.5       , 0.        , 0.5       , 0.        , 0.        ,
        0.        ],
       [0.21428571, 0.14285714, 0.        , 0.64285714, 0.        ,
        0.        ],
       [0.18918919, 0.        , 0.        , 0.        , 0.78378378,
        0.02702703],
       [0.28571429, 0.        , 0.        , 0.        , 0.        ,
        0.71428571]])
    """
    if not w_options:
        w_options = {}
    assert (
        unit_index in gdf.columns
    ), f"The unit_index ({unit_index}) column is not in the geodataframe"
    gdf_temp = gdf.copy().reset_index()
    df = gdf_temp[[unit_index, temporal_index, cluster_col]]
    df_wide = df.pivot(
        index=unit_index, columns=temporal_index, values=cluster_col
    ).dropna()
    y = df_wide.values
    if w_type is None:
        mar = Markov(y)  # class markov modeling
    else:
        geoms = gdf_temp.groupby(unit_index).first()[gdf_temp.geometry.name]
        gdf_wide = df_wide.merge(geoms, left_index=True, right_index=True)
        w = Ws[w_type].from_dataframe(gpd.GeoDataFrame(gdf_wide), **w_options)
        w.transform = "r"
        mar = Spatial_Markov(
            y, w, permutations=permutations, discrete=True, variable_name=cluster_col
        )
    return mar

def sequence(
    gdf,
    cluster_col,
    seq_clusters=5,
    subs_mat=None,
    dist_type=None,
    indel=None,
    temporal_index="year",
    unit_index="geoid",
):
    """
    Pairwise sequence analysis and sequence clustering.

    Dynamic programming if optimal matching.

    Parameters
    ----------
    gdf             : geopandas.GeoDataFrame or pandas.DataFrame
                      Long-form geopandas.GeoDataFrame or pandas.DataFrame containing neighborhood
                      attributes with a column defining neighborhood clusters.
    cluster_col     : string or int
                      Column name for the neighborhood segmentation, such as
                      "ward", "kmeans", etc.
    seq_clusters    : int, optional
                      Number of neighborhood sequence clusters. Agglomerative
                      Clustering with Ward linkage is now used for clustering
                      the sequences. Default is 5.
    dist_type       : string
                      "hamming": hamming distance (substitution only
                      and its cost is constant 1) from sklearn.metrics;
                      "markov": utilize empirical transition
                      probabilities to define substitution costs;
                      "interval": differences between states are used
                      to define substitution costs, and indel=k-1;
                      "arbitrary": arbitrary distance if there is not a
                      strong theory guidance: substitution=0.5, indel=1.
                      "tran": transition-oriented optimal matching. Sequence of
                      transitions. Based on :cite:`Biemann:2011`.
    subs_mat        : array
                      (k,k), substitution cost matrix. Should be hollow (
                      0 cost between the same type), symmetric and non-negative.
    indel           : float, optional
                      insertion/deletion cost.
    temporal_index        : string, optional
                      Column defining time and or sequencing of the long-form data.
                      Default is "year".
    unit_index          : string, optional
                      Column identifying the unique id of spatial units.
                      Default is "geoid".

    Returns
    --------
    gdf_temp        : geopandas.GeoDataFrame or pandas.DataFrame
                      geopandas.GeoDataFrame or pandas.DataFrame with a new column for sequence
                      labels.
    df_wide         : pandas.DataFrame
                      Wide-form DataFrame with k (k is the number of periods)
                      columns of neighborhood types and 1 column of sequence
                      labels.
    seq_dis_mat     : array
                      (n,n), distance/dissimilarity matrix for each pair of
                      sequences

    Examples
    --------
    >>> from geosnap.data import Community
    >>> columbus = Community.from_ltdb(msa_fips="18140")
    >>> columbus1 = columbus.cluster(columns=['median_household_income',
    ... 'p_poverty_rate', 'p_edu_college_greater', 'p_unemployment_rate'],
    ... method='ward', n_clusters=6)
    >>> gdf = columbus1.gdf
    >>> gdf_new, df_wide, seq_hamming = Sequence(gdf, dist_type="hamming")
    >>> seq_hamming.seq_dis_mat[:5, :5]
    array([[0., 3., 4., 5., 5.],
           [3., 0., 3., 3., 3.],
           [4., 3., 0., 2., 2.],
           [5., 3., 2., 0., 0.],
           [5., 3., 2., 0., 0.]])

    """
    assert (
        unit_index in gdf.columns
    ), f"The unit_index ({unit_index}) column is not in the geodataframe"
    gdf_temp = gdf.copy().reset_index()
    df = gdf_temp[[unit_index, temporal_index, cluster_col]]
    df_wide = (
        df.pivot(index=unit_index, columns=temporal_index, values=cluster_col)
        .dropna()
        .astype("int")
    )
    y = df_wide.values
    seq_dis_mat = Sequence(
        y, subs_mat=subs_mat, dist_type=dist_type, indel=indel, cluster_type=cluster_col
    ).seq_dis_mat
    model = AgglomerativeClustering(n_clusters=seq_clusters).fit(seq_dis_mat)
    name_seq = dist_type + "_%d" % (seq_clusters)
    df_wide[name_seq] = model.labels_
    gdf_temp = gdf_temp.merge(df_wide[[name_seq]], left_on=unit_index, right_index=True)
    gdf_temp = gdf_temp.reset_index(drop=True)

    return gdf_temp, df_wide, seq_dis_mat

def predict_markov_labels(
    gdf,
    unit_index="geoid",
    temporal_index="year",
    cluster_col=None,
    w_type="rook",
    w_options=None,
    base_year=None,
    new_colname=None,
    time_steps=1,
    increment=None,
    seed=None,
    verbose=True,
):
    """Predict neighborhood labels based on spatial Markov transition model

    Parameters
    ----------
    gdf : geopandas.GeoDataFrame
        a long-form geodataframe with a column of labels to be simulated with a spatial Markov model
    unit_index : str,
        column on dataframe that identifies unique geographic units, by default "geoid"
    temporal_index : str
        column on dataframe that identifies unique time periods, by default "year"
    cluster_col : str
        column on the dataframe that stores cluster or other labels to be simulated
    w_type : str, optional
        type of spatial weights matrix to include in the transition model, by default "queen"
    w_options : dict, optional
        additional keyword arguments passed to the libpysal weights constructor
    base_year : int or str, optional
        the year from which to begin simulation (i.e. the set of labels to define the first
        period of the Markov sequence)
    new_colname : str, optional
        new column name to store predicted labels under. Defaults to "predicted"
    time_steps : int, optional
        the number of time-steps to simulate, by default 1
    increment : str or int, optional
        styled increment each time-step referrs to. For example, for a model fitted to decadal
        Census data, each time-step refers to a period of ten years, so an increment of 10 ensures
        that the temporal index aligns appropriately with the time steps being simulated
    verbose: bool
        if true, print warnings from the label sampling process

    Returns
    -------
    geopandas.GeoDataFrame
        long-form geodataframe with predicted cluster labels stored in the `new_colname` column
    """
    crs = gdf.crs
    np.random.seed(seed)
    if not new_colname:
        new_colname = "predicted"
    if not w_options:
        w_options = {}

    assert (
        cluster_col and cluster_col in gdf.columns
    ), f"The input dataframe has no column named {cluster_col}"

    assert (
        base_year
    ), "Missing `base_year`. You must provide an initial time point with labels to begin simulation"
    assert (
        base_year in gdf[temporal_index].unique().tolist()
    ), "A set of observations with `temporal_index`==`base_year` must be included in the gdf"

    gdf = gdf.copy()
    gdf = gdf.dropna(subset=[cluster_col]).reset_index(drop=True)
    t = transition(
        gdf,
        cluster_col,
        w_type=w_type,
        unit_index=unit_index,
        temporal_index=temporal_index,
        w_options=w_options,
    )

    if time_steps == 1:

        gdf = gdf[gdf[temporal_index] == base_year].reset_index(drop=True)
        w = Ws[w_type].from_dataframe(gdf, **w_options)
        predicted = _draw_labels(w, gdf, cluster_col, t, unit_index, verbose)
        if new_colname:
            predicted = predicted.rename(columns={cluster_col: new_colname})
        return predicted

    else:
        assert (
            increment
        ), "You must set the `increment` argument to simulate multiple time steps"
        predictions = []
        gdf = gdf[gdf[temporal_index] == base_year]
        gdf = gdf[[unit_index, cluster_col, temporal_index, gdf.geometry.name]]
        current_time = base_year + increment
        gdf = gdf.dropna(subset=[cluster_col]).reset_index(drop=True)
        w = Ws[w_type].from_dataframe(gdf, **w_options)
        predictions.append(gdf)

        for step in range(1, time_steps + 1):
            # use the last known set of labels  to get the spatial context for each geog unit
            gdf = predictions[step - 1].copy()

            predicted = _draw_labels(w, gdf, cluster_col, t, unit_index, verbose)
            predicted[temporal_index] = current_time
            predictions.append(predicted)
            current_time += increment
        gdf = gpd.GeoDataFrame(pd.concat(predictions), crs=crs)
        if new_colname:
            gdf = gdf.rename(columns={cluster_col: new_colname})
        return gdf

def _draw_labels(w, gdf, cluster_col, markov, unit_index, verbose):
    """Draw a random class label from the spatially-conditioned transition rates.

    Parameters
    ----------
    w : libpysal.weights.W
        spatial weights object
    gdf : geopandas.GeoDataFrame
        geodataframe of observations with class/cluster labels as a column
    cluster_col : string
        the column on the dataframe that holds class labels
    markov : giddy.Spatial_Markov
        an instance of a Spatial_Markov class
    unit_index : string
        the column on the dataframe that identifies unique spatial units

    Returns
    -------
    geopandas.GeoDataFrame
        long-form geodataframe with predicted cluster labels stored in the `new_colname` column
    """
    gdf = gdf.copy()
    gdf = gdf.dropna(subset=[cluster_col])
    lags = lag_categorical(w, gdf[cluster_col].values)
    clusters = gdf.reset_index()[cluster_col].astype(str).values
    classes = markov.classes.astype(str)
    cluster_idx = dict(zip(classes, list(range(len(classes)))))

    labels = {}
    for i, lag in enumerate(lags):
        #  select the transition matrix using the label of unit's spatial lag
        spatial_context = np.nan_to_num(markov.P, posinf=0.0, neginf=0.0)[
            cluster_idx[lag]
        ]
        #  select the class row from the transition matrix using the unit's label
        probs = spatial_context[cluster_idx[clusters[i]]]
        probs /= (
            probs.sum()
        )  # correct for tolerance, see https://stackoverflow.com/questions/25985120/numpy-1-9-0-valueerror-probabilities-do-not-sum-to-1
        probs = np.nan_to_num(probs.flatten())
        if sum(probs) == 0:
            # in case obs have a modal neighbor never before seen in the model
            # (so all transition probs are 0)
            # fall back to the aspatial transition matrix
            if verbose:
                warn(
                    f"Falling back to aspatial transition rule for unit "
                    f"{gdf[unit_index][i]}"
                )
            probs = markov.p[cluster_idx[clusters[i]]].flatten()

        labels[i] = np.random.choice(classes, p=probs)

    labels = pd.Series(labels, name=cluster_col, index=gdf.index)
    out = gdf[[unit_index, gdf.geometry.name]]
    predicted = gpd.GeoDataFrame(pd.concat([labels, out], axis=1))
    return predicted

def draw_sequence_from_gdf(
    gdf,
    w,
    label_column,
    smk,
    time_column,
    start_time=None,
    time_steps=1,
    increment=None,
    seed=None,
):
    """Draw a set of class labels for each unit in a geodataframe using transition
    probabilities defined by a giddy.Spatial_Markov model and the spatial lag of each
    unit.

    Parameters
    ----------
    gdf : geopandas.GeoDataFrame
        geodataframe of observations with class/cluster labels as a column
    w : libpysal.weights.W
        spatial weights object that defines the neigbhbor graph for each unit.
    label_column : str
        the column on the dataframe that holds class labels
    smk : giddy.Spatial_Markov
        an instance of a Spatial_Markov class created from the giddy package
        or `geosnap.analyze.transition`
    time_column : str
        column on dataframe that identifies unique time periods, by default "year"
    start_time : str, int, or float, optional
        Time period to begin drawing a sequence of labels (must be present in
        `gdf[label_col]`). If None, use the most recent time period given by
        max(gdf[label_column].unique()). By default None
    time_steps : int, optional
        the number of time-steps to simulate (i.e. the number of labels to draw in a
        sequence for each unit), by default 1
    increment : itn, required
        styled increment each time-step referrs to. For example, for a model fitted to
        decadal Census data, each time-step refers to a period of ten years, so an
        increment of 10 ensures that the temporal index aligns appropriately with the
        time steps being simulated
    seed: int
        seed for  reproducible pseudo-random results. Used to create a SeedSequence and
        spawn a set of Generators using PCG64. If None, uses the current time

    Returns
    -------
    geopandas.GeoDataFrame
        long-form geodataframe with the same index as the geodataframe in the
        time period equal the start time (i.e. `gdf[gdf[time_column]==start_time]`).

    """
    assert increment

    steps = [start_time + (increment * step) for step in range(time_steps + 1)]
    steps = steps[1:]
    gdf = gdf.copy()
    gdf = gdf[[label_column, time_column, gdf.geometry.name]].copy()

    dfs = list()

    current_df = gdf[gdf[time_column] == start_time]

    if seed is None:
        seed = int(time())

    base_seq = SeedSequence(seed)
    child_seqs = base_seq.spawn(time_steps)
    generators = [PCG64(seq) for seq in child_seqs]

    dfs.append(current_df)
    # must run in sequence because we need the prior time's spatial lag
    for i, step in enumerate(tqdm(steps)):
        # `steps` and `dfs` are off by one so the ith in dfs is the previous time period
        current_df = dfs[i].copy()
        predicted_labels = _draw_labels_from_gdf(
            current_df, w, label_column, smk, generators[i]
        )
        predicted_df = gdf[gdf[time_column] == start_time]
        # overwrite labels with predictions for the new time period
        predicted_df[label_column] = predicted_labels
        predicted_df[time_column] = step

        dfs.append(predicted_df)
    simulated = pd.concat(dfs)

    return simulated

def _draw_labels_from_gdf(gdf, w, label_column, smk, seed):
    """Draw set of new labels given a geodataframe and a spatial Markov transition model

    Parameters
    ----------
    gdf : geopandas.GeoDataFrame
        a geodataframe defining the study region, including a column holding class labels
    w : libpysal.Weights
        a spatial weights matrix relating units to one another. This should be the same
        W object that was used to fit the Spatial_Markov instance
    label_column : str
        the column in gdf holding class labels
    smk : giddy.Spatial_Markov
        a spatial Markov transition model created by the pysal giddy package
        or geosnap.analyze.transition
    seed: int or nmnumpy.random.Generator instance
        seed passed to np.random.default_rng for reproducible pseudo-random results

    Returns
    -------
    numpy.array
        an array of simulated class labels drawn from the conditional probabilities
        provided in the Spatial_Markov object
    """

    labels = gdf[label_column].astype(str).values
    lags = lag_categorical(w, labels)
    probs = _conditional_probs_from_smk(labels, lags, smk)
    assert len(lags) == len(
        probs
    ), "Lag values and probability vectors are different lengths"
    simulated_labels = _draw_labels_from_probs(
        smk.classes.astype(str), probs=probs, seed=seed
    )

    return simulated_labels

def _draw_labels_from_probs(classes, probs, seed):
    """Draw from a fized set of classes using a vector of probabilities

    Parameters
    ----------
    classes : list-like
        set of class labels
    probs : list-like
        list of probabilities
    seed: int or numpy.random.Generator instance
        seed passed to np.random.default_rng for reproducible pseudo-random results
    verbose : bool, optional
        if true, print a warning when a label cannot be drawn from the
        probability vector, by default True

    Returns
    -------
    list
        list of labels drawn from `classes` with size n_probs
    """
    labels = list()
    rng = default_rng(seed=seed)
    # for each set of probabilities in the array, draw a label
    # this could also be done in parallel. We could also take multiple draws per
    # unit by passing a `size` argument to rng.choice
    for p in probs:
        try:
            label = rng.choice(classes, p=p)
        except ValueError as e:
            raise ValueError from e
        labels.append(label)
    return np.array(labels)

def _conditional_probs_from_smk(labels, lags, smk, fill_null_probs=True):
    """Given a set of existing labels and associated lags, return a vector of
    transition probabilities from a giddy.Spatial_Markov model

    Parameters
    ----------
    labels : list
        array of categorical labels that define a class for each unit
    lags : list
        array of categorical labels that define the context for each unit
    smk : giddy.Spatial_Markov
        a spatial Markov transition model from giddy or geosnap.analyze.transition

    Returns
    -------
    list
        list of lists, where each element of the outer list is
        a set of transition probabilities, and each element of the innerr
        list(s) is the probability of transitioning into class with index i
    """
    classes = smk.classes.astype(str)

    # mapping back to the order each class is given in the smk object
    class_idx = dict(zip(classes, list(range(len(classes)))))

    probs = list()
    # this piece could be parallelized as long as it gets concatenated back in order
    for i in range(len(labels)):
        current_label = labels[i]
        current_class_idx = class_idx[current_label]
        aspatial_p = np.nan_to_num(smk.p[current_class_idx]).flatten()
        aspatial_p /= aspatial_p.sum()

        lag_idx = class_idx[lags[i]]
        conditional_matrix = smk.P[lag_idx]
        p = conditional_matrix[current_class_idx].flatten()
        # correct for tolerance, see https://stackoverflow.com/questions/25985120/numpy-1-9-0-valueerror-probabilities-do-not-sum-to-1
        p = np.nan_to_num(p)
        if p.sum() == 0:
            if fill_null_probs:
                warn(
                    f"No spatial transition rules for {current_label} with conrtext {lags[i]}"
                    "falling back to aspatial transition rules"
                )
                probs.append(aspatial_p)
            else:
                raise ValueError(
                    f"No spatial transition rules for {current_label} with conrtext {lags[i]}"
                )
        else:
            p /= p.sum()

            probs.append(np.nan_to_num(p))

    return probs


#!/usr/bin/env python3

# *****************************************
# irrigator - Initialize Crontab
# *****************************************
#
# Description: Add cron entries for items
#
# 1. Add reboot script to initialize relays
#  @reboot cd /usr/local/bin/irrigator && sudo python3 control.py -i &
#
# 2. Add monthly log cleanup
#  0 0 1 * * cd /usr/local/bin/irrigator/logs && sh backup.sh
#
# 3. Add periodic weather check
#  */15 * * * * cd /usr/local/bin/irrigator && sudo python3 openwx.py
#
# *****************************************
from crontab import CronTab
from common import *

def checkexists(comment_string, system_cron):
    count = 0 # Init count variable
    for count in system_cron.find_comment(comment_string):
        print(count) # Look for finding the CRON Job
    return(count)

# Main Start
system_cron = CronTab(user='root')

# Initialize Relays on Boot
command_string = "cd /usr/local/bin/irrigator && sudo python3 control.py -i &"
comment_string = "Irrigator-Init"

if (checkexists(comment_string, system_cron)==0):
    # If not found, create it.
    entry = system_cron.new(command=command_string,comment=comment_string)
    entry.every_reboot()
    entry.enable()
    system_cron.write()

# Monthly Log Cleanup
command_string = "cd /usr/local/bin/irrigator/logs && sh backup.sh"
comment_string = "Irrigator-Log"

if (checkexists(comment_string, system_cron)==0):
    # If not found, create it.
    entry = system_cron.new(command=command_string,comment=comment_string)
    entry.setall("0 0 1 * *")
    entry.enable()
    system_cron.write()

# Cache weather information every 15 minutes
command_string = "cd /usr/local/bin/irrigator && sudo python3 openwx.py"
comment_string = "Irrigator-WxCache"

if (checkexists(comment_string, system_cron)==0):
    # If not found, create it.
    entry = system_cron.new(command=command_string,comment=comment_string)
    entry.minute.every(15)
    entry.enable()
    system_cron.write()

# Add schedules to the crontab
json_data_dict = ReadJSON() # This will create default schedules if none exist

for item in json_data_dict['schedules']:
    command_string = "cd /usr/local/bin/irrigator && sudo python3 control.py -s " + item + " &"
    if (checkexists(item, system_cron)==0):
        # If not found, create it.
        entry = system_cron.new(command=command_string,comment=item)
        entry.setall(json_data_dict['schedules'][item]['start_time']['cron_string'])
        if(json_data_dict['schedules'][item]['start_time']['enabled']):
            entry.enable()
        else:
            entry.enable(False)
        system_cron.write()


import pandas as pd
import numpy as np
import seaborn as sns
from sklearn import ensemble
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
from math import sqrt

trainingData = pd.read_csv('C:/Users/.../train.csv')
testingData = pd.read_csv('C:/Users/.../test.csv')

##missing data
#total = trainingData.isnull().sum().sort_values(ascending=False)
#percent = (trainingData.isnull().sum()/trainingData.shape[0]).sort_values(ascending=False)
#missing_data = pd.concat([total, percent], axis=1, keys=['Total', 'Percent'])
#print(missing_data.head(20))

columnsToDrop=['PoolQC', 'MiscFeature', 'Alley', 'Fence', 'FireplaceQu', 'LotFrontage']
trainingData.drop(columnsToDrop, axis=1, inplace=True)
testingData.drop(columnsToDrop, axis=1, inplace=True)

##missing data
#total = trainingData.isnull().sum().sort_values(ascending=False)
#percent = (trainingData.isnull().sum()/trainingData.shape[0]).sort_values(ascending=False)
#missing_data = pd.concat([total, percent], axis=1, keys=['Total', 'Percent'])
#print(missing_data.head(15))

##missing data
#total = testingData.isnull().sum().sort_values(ascending=False)
#percent = (testingData.isnull().sum()/testingData.shape[0]).sort_values(ascending=False)
#missing_data = pd.concat([total, percent], axis=1, keys=['Total', 'Percent'])
#print(missing_data.head(30))

# fillna cause by no garage
trainingData['GarageType'].fillna('NA', inplace=True)
trainingData['GarageYrBlt'].fillna(trainingData['YearBuilt'], inplace=True)
trainingData['GarageFinish'].fillna('NA', inplace=True)
trainingData['GarageCond'].fillna('NA', inplace=True)
trainingData['GarageQual'].fillna('NA', inplace=True)

testingData['GarageType'].fillna('NA', inplace=True)
testingData['GarageYrBlt'].fillna(testingData['YearBuilt'], inplace=True)
testingData['GarageFinish'].fillna('NA', inplace=True)
testingData['GarageCond'].fillna('NA', inplace=True)
testingData['GarageQual'].fillna('NA', inplace=True)
testingData['GarageArea'].fillna(0.0, inplace=True)
testingData['GarageCars'].fillna(0.0, inplace=True)

# fillna cause by no basement
trainingData['BsmtFinType2'].fillna('NA', inplace=True)
trainingData['BsmtExposure'].fillna('NA', inplace=True)
trainingData['BsmtQual'].fillna('NA', inplace=True)
trainingData['BsmtFinType1'].fillna('NA', inplace=True)
trainingData['BsmtCond'].fillna('NA', inplace=True)

testingData['BsmtFinType2'].fillna('NA', inplace=True)
testingData['BsmtExposure'].fillna('NA', inplace=True)
testingData['BsmtQual'].fillna('NA', inplace=True)
testingData['BsmtFinType1'].fillna('NA', inplace=True)
testingData['BsmtCond'].fillna('NA', inplace=True)
testingData['BsmtFullBath'].fillna(0.0, inplace=True)
testingData['BsmtHalfBath'].fillna(0.0, inplace=True)
testingData['TotalBsmtSF'].fillna(0.0, inplace=True)
testingData['BsmtFinSF2'].fillna(0.0, inplace=True)
testingData['BsmtFinSF1'].fillna(0.0, inplace=True)
testingData['BsmtUnfSF'].fillna(0.0, inplace=True)

# fillna cause by no Masonry veneer
trainingData['MasVnrType'].fillna('None', inplace=True)
trainingData['MasVnrArea'].fillna(0.0, inplace=True)

testingData['MasVnrType'].fillna('None', inplace=True)
testingData['MasVnrArea'].fillna(0.0, inplace=True)

##missing data
#total = trainingData.isnull().sum().sort_values(ascending=False)
#percent = (trainingData.isnull().sum()/trainingData.shape[0]).sort_values(ascending=False)
#missing_data = pd.concat([total, percent], axis=1, keys=['Total', 'Percent'])
#print(missing_data.head(5))
#
##missing data
#total = testingData.isnull().sum().sort_values(ascending=False)
#percent = (testingData.isnull().sum()/testingData.shape[0]).sort_values(ascending=False)
#missing_data = pd.concat([total, percent], axis=1, keys=['Total', 'Percent'])
#print(missing_data.head(10))

#fill other missing data
trainingData['Electrical'].fillna(trainingData['Electrical'].mode()[0], inplace=True)

testingData['MSZoning'].fillna(trainingData['MSZoning'].mode()[0], inplace=True)
testingData['Utilities'].fillna(trainingData['Utilities'].mode()[0], inplace=True)
testingData['MSZoning'].fillna(trainingData['MSZoning'].mode()[0], inplace=True)
testingData['Exterior1st'].fillna(trainingData['Exterior1st'].mode()[0], inplace=True)
testingData['Exterior2nd'].fillna(trainingData['Exterior2nd'].mode()[0], inplace=True)
testingData['Functional'].fillna(trainingData['Functional'].mode()[0], inplace=True)
testingData['SaleType'].fillna(trainingData['SaleType'].mode()[0], inplace=True)
testingData['KitchenQual'].fillna(trainingData['KitchenQual'].mode()[0], inplace=True)

##missing data
#total = trainingData.isnull().sum().sort_values(ascending=False)
#percent = (trainingData.isnull().sum()/trainingData.shape[0]).sort_values(ascending=False)
#missing_data = pd.concat([total, percent], axis=1, keys=['Total', 'Percent'])
#print(missing_data.head(5))
#
##missing data
#total = testingData.isnull().sum().sort_values(ascending=False)
#percent = (testingData.isnull().sum()/testingData.shape[0]).sort_values(ascending=False)
#missing_data = pd.concat([total, percent], axis=1, keys=['Total', 'Percent'])
#print(missing_data.head(6))

#Add some combine attributes
trainingData['TotalSF'] = trainingData['TotalBsmtSF'] + trainingData['1stFlrSF'] + trainingData['2ndFlrSF']
trainingData['TotalBath'] = trainingData['BsmtFullBath'] + trainingData['BsmtHalfBath'] + trainingData['FullBath'] + trainingData['HalfBath']

testingData['TotalSF'] = testingData['TotalBsmtSF'] + testingData['1stFlrSF'] + testingData['2ndFlrSF']
testingData['TotalBath'] = testingData['BsmtFullBath'] + testingData['BsmtHalfBath'] + testingData['FullBath'] + testingData['HalfBath']
##drop some attributes
#trainingData.drop(['TotalBsmtSF', '1stFlrSF', '2ndFlrSF', 'BsmtFullBath', 'BsmtHalfBath', 'FullBath', 'HalfBath'], axis=1, inplace=True)
#testingData.drop(['TotalBsmtSF', '1stFlrSF', '2ndFlrSF', 'BsmtFullBath', 'BsmtHalfBath', 'FullBath', 'HalfBath'], axis=1, inplace=True)

#change some attributes to numerical
trainingData["ExterQual"] = trainingData["ExterQual"].map({"Ex":5, "Gd":4, "TA":3, "Fa":2, "Po":1})
trainingData["ExterCond"] = trainingData["ExterCond"].map({"Ex":5, "Gd":4, "TA":3, "Fa":2, "Po":1})
trainingData["HeatingQC"] = trainingData["HeatingQC"].map({"Ex":5, "Gd":4, "TA":3, "Fa":2, "Po":1})
trainingData["KitchenQual"] = trainingData["KitchenQual"].map({"Ex":5, "Gd":4, "TA":3, "Fa":2, "Po":1})

testingData["ExterQual"] = testingData["ExterQual"].map({"Ex":5, "Gd":4, "TA":3, "Fa":2, "Po":1})
testingData["ExterCond"] = testingData["ExterCond"].map({"Ex":5, "Gd":4, "TA":3, "Fa":2, "Po":1})
testingData["HeatingQC"] = testingData["HeatingQC"].map({"Ex":5, "Gd":4, "TA":3, "Fa":2, "Po":1})
testingData["KitchenQual"] = testingData["KitchenQual"].map({"Ex":5, "Gd":4, "TA":3, "Fa":2, "Po":1})

#change dtypes
trainingData['MSSubClass'] = trainingData['MSSubClass'].astype(str)
testingData['MSSubClass'] = testingData['MSSubClass'].astype(str)

##check for outliers
#col=['GrLivArea', 'TotalSF']
#for c in col:
#    sns.relplot(x=c, y='SalePrice', data=trainingData)
#
#print(trainingData.shape)
trainingData.drop(trainingData[(trainingData['GrLivArea']>4000) & (trainingData['SalePrice']<300000)].index, inplace = True)
#
#for c in col:
#    sns.relplot(x=c, y='SalePrice', data=trainingData)
#
#print(trainingData.shape)

train_Y=trainingData['SalePrice']
train_X=trainingData.drop(['Id', 'SalePrice'], axis=1)

test_X=testingData.drop(['Id'], axis=1)

#print(train_X.dtypes)
#print(train_Y.shape)

#prosess categorical features
len_train_x=train_X.shape[0]
tmp_all=pd.concat(objs=[train_X, test_X], axis=0, sort=False).reset_index(drop=True)
tmp_all=pd.get_dummies(tmp_all)
tmp_all= tmp_all.astype(float)

new_train_X=tmp_all[:len_train_x]
new_test_X=tmp_all[len_train_x:]

#Set model
GBR = ensemble.GradientBoostingRegressor(n_estimators=3000, learning_rate=0.05, max_depth=3, max_features='sqrt',
                                         min_samples_leaf=10, loss='huber')
#training error
GBR.fit(new_train_X, train_Y)
y_pred = GBR.predict(new_train_X)
y_pred=np.log(y_pred)
log_Y=np.log(train_Y)
rms = sqrt(mean_squared_error(y_pred, log_Y))
print('TE: ', rms)

# Splitting
x_train, x_test, y_train, y_test = train_test_split(new_train_X, train_Y, test_size=0.5)

GBR.fit(x_train, y_train)
y_pred = GBR.predict(x_test)
y_pred=np.log(y_pred)
y_test=np.log(y_test)

rms = sqrt(mean_squared_error(y_test, y_pred))
print('CV: ', rms)

#retraining with whole training data
numberOfModel=30
box=[]
result=np.zeros(new_test_X.shape[0])
for i in range(numberOfModel):
    GBR = ensemble.GradientBoostingRegressor(n_estimators=3000, learning_rate=0.05, max_depth=3, max_features='sqrt',
                                             min_samples_leaf=10, loss='huber').fit(new_train_X, train_Y)
    box.append(GBR)
    # Getting our SalePrice estimation
    tmp = GBR.predict(new_test_X)
    result=result+tmp
    print('Model number: ', i, ' completes.')

result=result/numberOfModel

## Saving to CSV
pd.DataFrame({'Id': testingData.Id, 'SalePrice': result}).to_csv('C:/Users/.../output.csv', index =False)


'''
Convergents of e
https://projecteuler.net/problem=65
'''
from fractions import Fraction
from numpy import e

def returnPeriods(num, limit):
    if num == e:
        return returnEuler(limit)
    periods = []
    r = num
    i = int(num)
    fractional = r - i
    for _ in range(0, limit):
        periods.append(i)
        r = 1 / fractional
        print(r)
        i = int(r)
        fractional = r - i
    return periods

def returnEuler(limit):
    periods = [2 * (i+1) // 3 if i % 3 == 2 else 1 for i in range(limit)]
    periods[0] += 1
    return periods

def returnConvergent(num, convergent):
    periods = returnPeriods(num, convergent)
    twoago_convergent = Fraction(periods[0], 1)
    if convergent == 1:
        return twoago_convergent
    previous_convergent = Fraction(periods[1] * periods[0] + 1, periods[1])
    if convergent == 2:
        return previous_convergent
    else:
        for n in range(2, convergent):
            current_convergent = Fraction(periods[n]
                                          * previous_convergent.numerator
                                          + twoago_convergent.numerator,
                                          periods[n]
                                          * previous_convergent.denominator
                                          + twoago_convergent.denominator)
            twoago_convergent = previous_convergent
            previous_convergent = current_convergent
    return current_convergent

print(sum([int(n) for n in str(returnConvergent(e, 100).numerator)]))


# Given a set of n segments {[a_0,b_0],[a_1,b_1],...,[a_{n−1},b_{n−1}]} with integer coordinates on a line, find the minimum number m of points such that each segment contains at least one point. That is, find a set of integers X of the minimum size such that for any segment [a_i,b_i] there is a point x∈X such that a_i≤x≤b_i.

import sys
from collections import namedtuple

Segment=namedtuple('Segment','start end')

def optimal_points(segments):
    points=[]
    while segments!=[]:
          y=[s.end for s in segments]
          i=y.index(min(y))
          b=y[i]
          points.append(b)
          segments.pop(i)
          nseg=[s for s in segments]
          for s in nseg:
              if s.start<=b: segments.remove(s)
    return points

if __name__ == '__main__':
   input = sys.stdin.read()
   n,*data=map(int,input.split())
   segments=list(map(lambda x: Segment(x[0],x[1]),zip(data[::2],data[1::2])))
   points=optimal_points(segments)
   print(len(points))
   for p in points: print(p, end=' ')


'''
You are given a character string A having length N, consisting of only lowercase and uppercase latin letters.

You have to toggle case of each character of string A. For e.g 'A' is changed to 'a', 'e' is changed to 'E', etc.

Input 1:
A = "tHiSiSaStRiNg"

Output 1:
ThIsIsAsTrInG
'''

string = input("Enter String : ")
result = ""
for i in range(len(string)):
    result += chr(ord(string[i]) ^ (32))
print(result)


from random import shuffle

def shuffle_list(mylist):
    shuffle(mylist)
    return mylist

def mans_minejums():
    minejums = ""
    while minejums not in ["1","2","3"]:
        minejums = input("Izvēlies skaitli - 1, 2, 3: ")
    return int(minejums)

def parbaudi_minejumu(lists,minejums):
    if lists[minejums-1] == "o":
        print("Pareizi🎉")
    else:
        print ("Nepareizi😒")
        print(lists)

#pa soļiem izsauc visas funkcijas
#norāda sarakstu
mylist = [" ", "o", " "]

#sajauc sarakstu
sajaukts_saraksts = shuffle_list(mylist)

#spēlētāja minējums
speletaja_minejums = mans_minejums()

#pārbauda spēlētāja minējumu
parbaudi_minejumu(sajaukts_saraksts, speletaja_minejums)


#0
'''
a = {3,10,11,13,31,21,1,10,3,5,6,6}
a.remove(3)
print(a)
'''
#1
'''
a = {"dog", "cat", "mouse", "sheep"}
b = {"cow", "horse", "donkey", "cat", "dog"}
c = a.intersection(b)
print(c)
'''
#2
'''
a = {"dog", "cat", "mouse", "sheep"}
b = {"cow", "horse", "donkey", "cat", "dog"}
j = a.difference(b)
print(j)
'''
#3
'''
a={1, 1.2, 'jack', 'hi',5}
a.add('python')
print(a)
print(a.pop())
print(a)
'''
#000
'''
menu = {'lagman': 120, 'plov': '120', 'borsh': 100}
menu.update({'besh_barmak':130})
print(menu)
menu.update({'borsh':135})
print(menu)
print(menu.pop('borsh'))
print(menu)
'''

#10
'''
menu = {'lagman': 120, 'plov': '120', 'borsh': 100}
menu.update({'drinks':['Coca-Cola', 'Sprite', 'Fanta']})
print(menu)
'''

#011
'''
a = ['Argentina', 'Bolivia', 'Brazil', 'Chile', 'Colombia', 'Ecuador', 'Guyana', 'Paraguay', 'Peru', 'Suriname', 'Suriname', 'Uruguay', 'Venezuela']
a.remove('Suriname')
print(a)
'''
#020

a={'add', 'remove', 'clear','update', 'difference', 'discard','intersection', 'intersection_update','pop'}
b={'clear','keys','items','get','values','update'}
c=a.intersection(b)
print(c)


# 显示控件的提示信息

# 需要用到 QToolTip

import sys
from PyQt5.QtWidgets import  QHBoxLayout,QMainWindow,QApplication,QToolTip,QPushButton,QWidget
# 提示信息需要设置字体
from PyQt5.QtGui import QFont

class TooltipForm(QMainWindow):
    def __init__(self):
        super().__init__()
        # 调用初始化ui的一个方法
        self.initUI()

    # 编写初始化UI的方法
    def initUI(self):
        # 设置字体和字号
        QToolTip.setFont(QFont('SansSerif',12))
        # 给窗口设置提示，这个方法支持富文本
        self.setToolTip('今天是个<b>好日子</b>')
        # 设置窗口的位置和尺寸
        self.setGeometry(300,300,200,200)
        # 设置窗口的标题
        self.setWindowTitle('设置控件提示消息')

    # 添加butoon按钮并设置提示信息

        # 添加Button
        # 创建全局对象self.button1
        self.button1 = QPushButton('我的按钮')
        # 设置按钮提示
        self.button1.setToolTip('这是按钮的提示信息')
        # 发送单击信号，执行对应的方法  (将信息与槽关联)
        self.button1.clicked.connect(self.onClick_Button)

        # 创建水平布局
        layout = QHBoxLayout()
        # 将组件加到水平局部里面
        layout.addWidget(self.button1)

        # 放置一个主框架
        mainFrame = QWidget()
        # 在主框架内添加水平布局
        mainFrame.setLayout(layout)
        # 把主框架放在窗口上
        self.setCentralWidget(mainFrame)

    # 按钮的单击事件的方法(自定义的槽)
    def onClick_Button(self):
        sender = self.sender()
        print(sender.text() + '按钮被按下')
        # 得到实例
        app = QApplication.instance()
        # 退出应用程序
        app.quit()

# 防止别的脚本调用，只有自己单独运行时，才会调用下面代码
if __name__ == '__main__':
    # 创建app实例，并传入参数
    app= QApplication(sys.argv)
    # 创建对象
    main = TooltipForm()
    # 创建窗口
    main.show()
    # 进入程序的主循环，并通过exit函数，确保主循环安全结束(该释放资源的释放资源)
    sys.exit(app.exec_())


import sqlite3
import os
from sqlite3.dbapi2 import Cursor, Error

def criarBanco():
    global conexao, Cursor
    if not os.path.exists('estacionamento.db'):
        conexao = sqlite3.connect('estacionamento.db')
        Cursor = conexao.cursor()

        sql_cliente =   'create table cliente('\
                        'id integer primary key autoincrement,'\
                        'nome varchar(50),'\
                        'cpf varchar(20),'\
                        'endereco varchar(40),'\
                        'contato varchar(15))'

        sql_veiculo =   'create table veiculo('\
                        'id_veiculo integer primary key autoincrement,'\
                        'modelo varchar(20),'\
                        'placa varchar(10),'\
                        'cor varchar(20),'\
                        'proprietario varchar(40),'\
                        'id_cliente integer not null,'\
                        'FOREING KEY (id_cliente) REFERENCES cliente(id))'

        Cursor.execute(sql_cliente)
        Cursor.execute(sql_veiculo)
        conexao.commit()

def adicionar_cliente(nome): # parametro
    global conexao, Cursor
    sql_cliente = 'insert into contato(nome, cpf, endereco, contato) values(?,?,?,?)'
    Cursor.execute(sql_cliente, [nome ]) #passamos o comando sql e logo seguindo do parametro em forma de lista

def adicionar_veiculo(id_cliente, veiculos): #id_contato chave estrageira na tabela telefones fones?
    global conexao, Cursor
    sql_veiculo = 'insert into veiculos(modelo, placa, cor, proprietario id_cliente) values(?,?,?)' #id_contato foreid key
    for i in veiculos:
        Cursor.execute(sql_veiculo, [i[0], i[1], id_cliente])

def adicionar_veiculos():
    veiculos = []
    while True:
        modelo = input(f'modelo do carro: ')
        placa = input(f'numero da placa : ')
        cor = input(f'cor do veiculo : ')
        if modelo  == "":
            modelo = None
        if placa == "":
            placa = None
        if cor == "":
            cor = None

        veiculos.append((modelo, placa, cor))
        print(veiculos)
        conf = input('deseja cadastrar outro veiculo para esse cliente? (S/N)')
        if conf in 'Ss':
            pass
        if conf in 'Nn':
            break
    return veiculos

def cadastro():
    global conexao, Cursor
    if conexao == None:
        conexao = sqlite3.connect('estacionamento.db')
        Cursor = conexao.cursor()
    nome = input('entre com o nome do cliente : ')
    if nome == '':
        nome = None
    else:
        res = consultar('cliente', 'id,nome','nome', nome)
        print(res)
        if len(res)>0:
            id = res[0][0]
            res = consultar('veiculos', 'modelo, placa', 'id_cliente', id)
            if len(res)>0:
                print('veiculos cadastrados')
                for i in res:
                    print(i)
            else:
                print('não ha veiculos cadastrados para esse cliente!')
        else:
            fones = adicionar_veiculos()
                ## sequencia sql parar adicionar registros
            try:
                adicionar_cliente(nome)
                id_cliente = Cursor.lastrowid
                adicionar_veiculos(id_cliente)
                conexao.commit()
            except:
                    print('erro de integridade do banco de dados!')

def atualizar_cliente():
    global conexao, Cursor
    if conexao == None:
        conexao = sqlite3.connect('estacionamento.db')
        Cursor = conexao.cursor()
    print('---------------------------------------------------------------')
    print('consultar/atualizar cliente')
    print('---------------------------------------------------------------')
    nome = input('digite o nome do cliente : ')
    sql = f"select * from cliente where nome like '%{nome}%'"## like busca aproximada
    Cursor.execute(sql)
    res = Cursor.fetchall()
    if len(res)>0:
        for i in res:
            print(i)
        resp = int(input('digite o nome do cliente a ser atualizado ou 0 para sair : '))
        if resp != 0:
            id_cliente = resp
            res = consultar('cliente', 'id,cliente', 'id', id_cliente)
            if len(res)>0:
                id_cliente = res[0][0]
                print(f'nomes : {res[0][1]}')
                res2 = consultar('veiculos', 'id_veiculo, modelo,placa', 'id_cliente', id_cliente)
                if len(res2)>0:
                    print('---------------------------------------------')
                    print('                  telefones                  ')
                    print('---------------------------------------------')
                    for i in res2:
                        print(i)
                    menu ('menu',['1-alterar cliente', '2-excluir cliente', '3-incluir veiculo', '4-alterar veiculo', '5-excluir veiculo', '6-sair']) ## tratar opção 2
                    opc = int(input('entre com uma opção : '))
                    if opc == 1:
                        novo_cliente = input('digite o novo cliente : ')
                        sql = "UPTADE cliente SET nome = ? where id = ?"
                        Cursor.execute(sql, [novo_cliente, id_cliente])
                    elif opc == 2:
                        sql = "DELETE FROM cliente WHERE id = ? "
                        Cursor.execute(sql, [id_cliente])
                    elif opc == 3:
                        veiculos = adicionar_cliente()
                        adicionar_veiculos(id_cliente, veiculos )
                    elif opc == 4:
                        id_veiculo = int(input('digite o id do veiculo a ser alterado : '))
                        novo_modelo = input('digite o novo numero : ')
                        nova_placa = input('digite a nova descrição : ')
                        sql = "UPDATE telefones SET numero = ?, descricao = ? WHERE id_fone = ?"
                        Cursor.execute(sql, [novo_modelo, nova_placa, id_veiculo])
                    elif opc == 5:
                        id_veiculo = int(input('digite o id do telefone a ser excluido : '))
                        sql = "DELETE from telefones WHERE id_fone = ?"
                        Cursor.execute(sql, [id_veiculo])
                    elif opc == 6:
                        exit
                else:
                    print('sem veiculos cadastrados!')
                    resp = input('deseja incluir um novo veiculo? (S/N)')
                    if resp in 'Ss':
                        veiculos = adicionar_veiculos()
                        adicionar_cliente(id_cliente, veiculos)
                conexao.commit()
            else:
                print('cliente não cadastrado!')
    else:
        print('cliente não cadastrado!')

def consultar(tabela, campos, campo_cond, valor):
    sql = f'select {campos} from {tabela} where {campo_cond} = ?'
    Cursor = conexao.cursor()
    Cursor.execute(sql, [valor])
    res = Cursor.fetchall()
    return res

def menu(cliente, veiculos):
    print(cliente)
    for i in veiculos:
        print(i)

def main():
    global conexao, Cursor
    conexao = None
    Cursor = None
    criarBanco()
    while True:
        menu ('menu_principal', ['1 - novo cliente', '2 - atualizar_cliente', '3 - sair'])
        opc = int(input('escolha uma opção : '))
        if opc == 1:
            cadastro()
        elif opc == 2:
            atualizar_cliente()
        elif opc == 3:
            break
    if Cursor != None:
        Cursor.close()
    if conexao != None:
        conexao.close()
main()


from http import client as http_client

from ironic_lib import metrics_utils
from oslo_utils import uuidutils
from pecan import rest

from ironic import api
from ironic.api.controllers import link
from ironic.api.controllers.v1 import collection
from ironic.api.controllers.v1 import notification_utils as notify
from ironic.api.controllers.v1 import utils as api_utils
from ironic.api import method
from ironic.common import args
from ironic.common import exception
from ironic.common.i18n import _
from ironic.common import policy
from ironic import objects

METRICS = metrics_utils.get_metrics_logger(__name__)

_DEFAULT_RETURN_FIELDS = ['uuid', 'node_uuid', 'volume_type',
                          'boot_index', 'volume_id']

TARGET_SCHEMA = {
    'type': 'object',
    'properties': {
        'boot_index': {'type': 'integer'},
        'extra': {'type': ['object', 'null']},
        'node_uuid': {'type': 'string'},
        'properties': {'type': ['object', 'null']},
        'volume_id': {'type': 'string'},
        'volume_type': {'type': 'string'},
        'uuid': {'type': ['string', 'null']},
    },
    'required': ['boot_index', 'node_uuid', 'volume_id', 'volume_type'],
    'additionalProperties': False,
}

TARGET_VALIDATOR_EXTRA = args.dict_valid(
    node_uuid=args.uuid,
    uuid=args.uuid,
)

TARGET_VALIDATOR = args.and_valid(
    args.schema(TARGET_SCHEMA),
    TARGET_VALIDATOR_EXTRA
)

PATCH_ALLOWED_FIELDS = [
    'boot_index',
    'extra',
    'node_uuid',
    'properties',
    'volume_id',
    'volume_type'
]

def convert_with_links(rpc_target, fields=None, sanitize=True):
    target = api_utils.object_to_dict(
        rpc_target,
        link_resource='volume/targets',
        fields=(
            'boot_index',
            'extra',
            'properties',
            'volume_id',
            'volume_type'
        )
    )
    api_utils.populate_node_uuid(rpc_target, target)

    if fields is not None:
        api_utils.check_for_invalid_fields(fields, target)

    if not sanitize:
        return target

    api_utils.sanitize_dict(target, fields)

    return target

def list_convert_with_links(rpc_targets, limit, url, fields=None,
                            detail=None, **kwargs):
    if detail:
        kwargs['detail'] = detail
    return collection.list_convert_with_links(
        items=[convert_with_links(p, fields=fields, sanitize=False)
               for p in rpc_targets],
        item_name='targets',
        limit=limit,
        url=url,
        fields=fields,
        sanitize_func=api_utils.sanitize_dict,
        **kwargs
    )

class VolumeTargetsController(rest.RestController):
    """REST controller for VolumeTargets."""

    invalid_sort_key_list = ['extra', 'properties']

    def __init__(self, node_ident=None):
        super(VolumeTargetsController, self).__init__()
        self.parent_node_ident = node_ident

    def _redact_target_properties(self, target):
        # Filters what could contain sensitive information. For iSCSI
        # volumes this can include iscsi connection details which may
        # be sensitive.
        redacted = ('** Value redacted: Requires permission '
                    'baremetal:volume:view_target_properties '
                    'access. Permission denied. **')
        redacted_message = {
            'redacted_contents': redacted
        }
        target.properties = redacted_message

    def _get_volume_targets_collection(self, node_ident, marker, limit,
                                       sort_key, sort_dir, resource_url=None,
                                       fields=None, detail=None,
                                       project=None):
        limit = api_utils.validate_limit(limit)
        sort_dir = api_utils.validate_sort_dir(sort_dir)

        marker_obj = None
        if marker:
            marker_obj = objects.VolumeTarget.get_by_uuid(
                api.request.context, marker)

        if sort_key in self.invalid_sort_key_list:
            raise exception.InvalidParameterValue(
                _("The sort_key value %(key)s is an invalid field for "
                  "sorting") % {'key': sort_key})
        node_ident = self.parent_node_ident or node_ident

        if node_ident:
            # FIXME(comstud): Since all we need is the node ID, we can
            #                 make this more efficient by only querying
            #                 for that column. This will get cleaned up
            #                 as we move to the object interface.
            node = api_utils.get_rpc_node(node_ident)
            targets = objects.VolumeTarget.list_by_node_id(
                api.request.context, node.id, limit, marker_obj,
                sort_key=sort_key, sort_dir=sort_dir, project=project)
        else:
            targets = objects.VolumeTarget.list(api.request.context,
                                                limit, marker_obj,
                                                sort_key=sort_key,
                                                sort_dir=sort_dir,
                                                project=project)
        cdict = api.request.context.to_policy_values()
        if not policy.check_policy('baremetal:volume:view_target_properties',
                                   cdict, cdict):
            for target in targets:
                self._redact_target_properties(target)

        return list_convert_with_links(targets, limit,
                                       url=resource_url,
                                       fields=fields,
                                       sort_key=sort_key,
                                       sort_dir=sort_dir,
                                       detail=detail)

    @METRICS.timer('VolumeTargetsController.get_all')
    @method.expose()
    @args.validate(node=args.uuid_or_name, marker=args.uuid,
                   limit=args.integer, sort_key=args.string,
                   sort_dir=args.string, fields=args.string_list,
                   detail=args.boolean)
    def get_all(self, node=None, marker=None, limit=None, sort_key='id',
                sort_dir='asc', fields=None, detail=None, project=None):
        """Retrieve a list of volume targets.

        :param node: UUID or name of a node, to get only volume targets
                     for that node.
        :param marker: pagination marker for large data sets.
        :param limit: maximum number of resources to return in a single result.
                      This value cannot be larger than the value of max_limit
                      in the [api] section of the ironic configuration, or only
                      max_limit resources will be returned.
        :param sort_key: column to sort results by. Default: id.
        :param sort_dir: direction to sort. "asc" or "desc". Default: "asc".
        :param fields: Optional, a list with a specified set of fields
                       of the resource to be returned.
        :param detail: Optional, whether to retrieve with detail.
        :param project: Optional, an associated node project (owner,
                        or lessee) to filter the query upon.

        :returns: a list of volume targets, or an empty list if no volume
                  target is found.

        :raises: InvalidParameterValue if sort_key does not exist
        :raises: InvalidParameterValue if sort key is invalid for sorting.
        :raises: InvalidParameterValue if both fields and detail are specified.
        """
        project = api_utils.check_volume_list_policy(
            parent_node=self.parent_node_ident)
        if fields is None and not detail:
            fields = _DEFAULT_RETURN_FIELDS

        if fields and detail:
            raise exception.InvalidParameterValue(
                _("Can't fetch a subset of fields with 'detail' set"))

        resource_url = 'volume/targets'
        return self._get_volume_targets_collection(node, marker, limit,
                                                   sort_key, sort_dir,
                                                   resource_url=resource_url,
                                                   fields=fields,
                                                   detail=detail,
                                                   project=project)

    @METRICS.timer('VolumeTargetsController.get_one')
    @method.expose()
    @args.validate(target_uuid=args.uuid, fields=args.string_list)
    def get_one(self, target_uuid, fields=None):
        """Retrieve information about the given volume target.

        :param target_uuid: UUID of a volume target.
        :param fields: Optional, a list with a specified set of fields
               of the resource to be returned.

        :returns: API-serializable volume target object.

        :raises: OperationNotPermitted if accessed with specifying a parent
                 node.
        :raises: VolumeTargetNotFound if no volume target with this UUID exists
        """

        rpc_target, _ = api_utils.check_volume_policy_and_retrieve(
            'baremetal:volume:get',
            target_uuid,
            target=True)

        if self.parent_node_ident:
            raise exception.OperationNotPermitted()

        cdict = api.request.context.to_policy_values()
        if not policy.check_policy('baremetal:volume:view_target_properties',
                                   cdict, cdict):
            self._redact_target_properties(rpc_target)

        return convert_with_links(rpc_target, fields=fields)

    @METRICS.timer('VolumeTargetsController.post')
    @method.expose(status_code=http_client.CREATED)
    @method.body('target')
    @args.validate(target=TARGET_VALIDATOR)
    def post(self, target):
        """Create a new volume target.

        :param target: a volume target within the request body.

        :returns: API-serializable volume target object.

        :raises: OperationNotPermitted if accessed with specifying a parent
                 node.
        :raises: VolumeTargetBootIndexAlreadyExists if a volume target already
                 exists with the same node ID and boot index
        :raises: VolumeTargetAlreadyExists if a volume target with the same
                 UUID exists
        """
        context = api.request.context
        raise_node_not_found = False
        node = None
        owner = None
        lessee = None
        node_uuid = target.get('node_uuid')
        try:
            node = api_utils.replace_node_uuid_with_id(target)
            owner = node.owner
            lessee = node.lessee
        except exception.NotFound:
            raise_node_not_found = True
        api_utils.check_owner_policy('node', 'baremetal:volume:create',
                                     owner, lessee=lessee,
                                     conceal_node=False)
        if raise_node_not_found:
            raise exception.InvalidInput(fieldname='node_uuid',
                                         value=node_uuid)

        if self.parent_node_ident:
            raise exception.OperationNotPermitted()

        # NOTE(hshiina): UUID is mandatory for notification payload
        if not target.get('uuid'):
            target['uuid'] = uuidutils.generate_uuid()
        new_target = objects.VolumeTarget(context, **target)

        notify.emit_start_notification(context, new_target, 'create',
                                       node_uuid=node.uuid)
        with notify.handle_error_notification(context, new_target, 'create',
                                              node_uuid=node.uuid):
            new_target.create()
        notify.emit_end_notification(context, new_target, 'create',
                                     node_uuid=node.uuid)
        # Set the HTTP Location Header
        api.response.location = link.build_url('volume/targets',
                                               new_target.uuid)
        return convert_with_links(new_target)

    @METRICS.timer('VolumeTargetsController.patch')
    @method.expose()
    @method.body('patch')
    @args.validate(target_uuid=args.uuid, patch=args.patch)
    def patch(self, target_uuid, patch):
        """Update an existing volume target.

        :param target_uuid: UUID of a volume target.
        :param patch: a json PATCH document to apply to this volume target.

        :returns: API-serializable volume target object.

        :raises: OperationNotPermitted if accessed with specifying a
                 parent node.
        :raises: PatchError if a given patch can not be applied.
        :raises: InvalidParameterValue if the volume target's UUID is being
                 changed
        :raises: NodeLocked if the node is already locked
        :raises: NodeNotFound if the node associated with the volume target
                 does not exist
        :raises: VolumeTargetNotFound if the volume target cannot be found
        :raises: VolumeTargetBootIndexAlreadyExists if a volume target already
                 exists with the same node ID and boot index values
        :raises: InvalidUUID if invalid node UUID is passed in the patch.
        :raises: InvalidStateRequested If a node associated with the
                 volume target is not powered off.
        """
        context = api.request.context

        api_utils.check_volume_policy_and_retrieve('baremetal:volume:update',
                                                   target_uuid,
                                                   target=True)

        if self.parent_node_ident:
            raise exception.OperationNotPermitted()

        api_utils.patch_validate_allowed_fields(patch, PATCH_ALLOWED_FIELDS)

        values = api_utils.get_patch_values(patch, '/node_uuid')
        for value in values:
            if not uuidutils.is_uuid_like(value):
                message = _("Expected a UUID for node_uuid, but received "
                            "%(uuid)s.") % {'uuid': str(value)}
                raise exception.InvalidUUID(message=message)

        rpc_target = objects.VolumeTarget.get_by_uuid(context, target_uuid)
        target_dict = rpc_target.as_dict()
        # NOTE(smoriya):
        # 1) Remove node_id because it's an internal value and
        #    not present in the API object
        # 2) Add node_uuid
        rpc_node = api_utils.replace_node_id_with_uuid(target_dict)

        target_dict = api_utils.apply_jsonpatch(target_dict, patch)

        try:
            if target_dict['node_uuid'] != rpc_node.uuid:

                # TODO(TheJulia): I guess the intention is to
                # permit the mapping to be changed
                # should we even allow this at all?
                rpc_node = objects.Node.get(
                    api.request.context, target_dict['node_uuid'])
        except exception.NodeNotFound as e:
            # Change error code because 404 (NotFound) is inappropriate
            # response for a PATCH request to change a volume target
            e.code = http_client.BAD_REQUEST  # BadRequest
            raise

        api_utils.patched_validate_with_schema(
            target_dict, TARGET_SCHEMA, TARGET_VALIDATOR)

        api_utils.patch_update_changed_fields(
            target_dict, rpc_target, fields=objects.VolumeTarget.fields,
            schema=TARGET_SCHEMA, id_map={'node_id': rpc_node.id}
        )

        notify.emit_start_notification(context, rpc_target, 'update',
                                       node_uuid=rpc_node.uuid)
        with notify.handle_error_notification(context, rpc_target, 'update',
                                              node_uuid=rpc_node.uuid):
            topic = api.request.rpcapi.get_topic_for(rpc_node)
            new_target = api.request.rpcapi.update_volume_target(
                context, rpc_target, topic)

        api_target = convert_with_links(new_target)
        notify.emit_end_notification(context, new_target, 'update',
                                     node_uuid=rpc_node.uuid)
        return api_target

    @METRICS.timer('VolumeTargetsController.delete')
    @method.expose(status_code=http_client.NO_CONTENT)
    @args.validate(target_uuid=args.uuid)
    def delete(self, target_uuid):
        """Delete a volume target.

        :param target_uuid: UUID of a volume target.

        :raises: OperationNotPermitted if accessed with specifying a
                 parent node.
        :raises: NodeLocked if node is locked by another conductor
        :raises: NodeNotFound if the node associated with the target does
                 not exist
        :raises: VolumeTargetNotFound if the volume target cannot be found
        :raises: InvalidStateRequested If a node associated with the
                 volume target is not powered off.
        """
        context = api.request.context

        api_utils.check_volume_policy_and_retrieve('baremetal:volume:delete',
                                                   target_uuid,
                                                   target=True)

        if self.parent_node_ident:
            raise exception.OperationNotPermitted()

        rpc_target = objects.VolumeTarget.get_by_uuid(context, target_uuid)
        rpc_node = objects.Node.get_by_id(context, rpc_target.node_id)
        notify.emit_start_notification(context, rpc_target, 'delete',
                                       node_uuid=rpc_node.uuid)
        with notify.handle_error_notification(context, rpc_target, 'delete',
                                              node_uuid=rpc_node.uuid):
            topic = api.request.rpcapi.get_topic_for(rpc_node)
            api.request.rpcapi.destroy_volume_target(context,
                                                     rpc_target, topic)
        notify.emit_end_notification(context, rpc_target, 'delete',
                                     node_uuid=rpc_node.uuid)