import tkinter as tk
from LessonInstance import *
from datetime import timedelta
from InputInstance import *
from processInput import *

startPoint=(10,100)
width=80
height=30

timeList=['TIME\DAY','0830-0930','0930-1030','1030-1130','1130-1230',
                  '1230-1330','1330-1430','1430-1530','1530-1630',
                  '1630-1730','1730-1830','1830-1930','1930-2030',
                  '2030-2130','2130-2230','2230-2330']
timeNum=[x for x in range(0,16)]
dayList=['TIME\DAY','MON','TUE','WED','THU','FRI','SAT']
dayNum=[x for x in range(0,7)]
timeDic=dict(zip(timeList,timeNum))
dayDic=dict(zip(dayList,dayNum))

class Application(tk.Frame):
    def __init__(self, master=None):
        tk.Frame.__init__(self,master)
        self.grid(sticky=tk.N+tk.S+tk.E+tk.W)
        self.createInitalWidgets()

    def createInitalWidgets(self):
        self.lFrame=tk.Frame(self)
        self.mFrame=tk.Frame(self)
        self.rFrame=tk.Frame(self)

        #initalise widgets in lFrame
        #lSub1
        self.lSub1=tk.LabelFrame(self.lFrame)
        self.totalLabel=tk.Label(self.lSub1,text="Total # courses:")
        self.totalEntryVar=tk.IntVar()
        self.totalEntry=tk.Entry(self.lSub1,textvariable=self.totalEntryVar)

        self.totalLabel.grid()
        self.totalEntry.grid(column=1,row=0)
        self.lSub1.grid()

        #lSub2
        self.lSub2=tk.LabelFrame(self.lFrame)
        self.courseCodeLbl=tk.Label(self.lSub2,text="Couse Code")
        self.mustLbl=tk.Label(self.lSub2,text="must")
        self.indexLbl=tk.Label(self.lSub2,text="index")

        self.course=[]
        self.course.append(CourseFrame(self.lSub2))

        self.addCourseBtn=tk.Button(self.lSub2,text="Add Course",command=self.addCourse)

        self.courseCodeLbl.grid(row=0,column=0)
        self.mustLbl.grid(row=0,column=1)
        self.indexLbl.grid(row=0,column=2)

        self.course[0].grid(row=1,column=0,rowspan=2,columnspan=4)
        self.addCourseBtn.grid(row=3,column=0,sticky=tk.E)
        self.lSub2.grid()

        #lSub3
        self.lSub3=tk.LabelFrame(self.lFrame)
        self.con1Lbl=tk.Label(self.lSub3,text="Condition 1")
        self.con1CheckVar=tk.IntVar()
        self.con1Check=tk.Checkbutton(self.lSub3,command=self.toggleCon1,variable=self.con1CheckVar)
        self.txt1=tk.Label(self.lSub3,text="For each week:")

        self.con1=[]
        self.con1.append(Condition(self.lSub3,typ=1))
        self.con1[-1].setDisabled()

        self.addCondition1Btn=tk.Button(self.lSub3,text="Add Conditon 1",state=tk.DISABLED,command=self.addCondition1)

        self.con1Lbl.grid(row=0,column=0)
        self.con1Check.grid(row=0,column=1)
        self.txt1.grid(row=1,column=0)
        self.con1[-1].grid(row=2,column=0)
        self.addCondition1Btn.grid(row=3,column=0)
        self.lSub3.grid()

        #lSub4
        self.lSub4=tk.LabelFrame(self.lFrame)

        self.con2Lbl=tk.Label(self.lSub4,text="Conditon 2")
        self.con2CheckVar=tk.IntVar()
        self.con2Check=tk.Checkbutton(self.lSub4,command=self.toggleCon2,variable=self.con2CheckVar)

        self.con2=[]
        self.con2.append(Condition(self.lSub4,typ=2))
        self.con2[-1].setDisabled()

        self.addCondition2Btn=tk.Button(self.lSub4,text="Add Conditon 2",state=tk.DISABLED,command=self.addCondition2)

        self.con2Lbl.grid(row=0,column=0)
        self.con2Check.grid(row=0,column=1)
        self.con2[-1].grid(row=1,column=0)
        self.addCondition2Btn.grid(row=2,column=0)
        self.lSub4.grid()

        #lSub5
        self.lSub5=tk.LabelFrame(self.lFrame)
        self.startBtn=tk.Button(self.lSub5,text="start",command=self.start)
        self.resetBtn=tk.Button(self.lSub5,text="reset",command=self.reset)

        self.startBtn.grid(row=0,column=0)
        self.resetBtn.grid(row=0,column=1)
        self.lSub5.grid()

        self.lFrame.grid(row=0,column=0)
        self.mFrame.grid(row=0,column=1)
        self.rFrame.grid(row=0,column=2)

        #initialising mFrame
        self.can=tk.Canvas(self.mFrame,bg="#FFFFFF",height=600,width=600)
        self.can.grid(sticky=tk.N+tk.S+tk.E+tk.W)
        self.createEmptyTable()

        self.nextBtn=tk.Button(self.mFrame,text="next",command=self.nextScreen,state=tk.DISABLED)
        self.nextBtn.grid(row=1)

    def createEmptyTable(self):
        self.slot=[[self.can.create_rectangle(
            startPoint[0]+dayDic[day]*width,
            startPoint[1]+timeDic[time]*height,
            startPoint[0]+dayDic[day]*width+width,
            startPoint[1]+timeDic[time]*height+height,
            tags=(day,time))
                    for time in timeList]
                   for day in dayList]
        self.time_dayLbl=self.can.create_text(startPoint[0]+width/2,startPoint[1]+height/2,text="TIME\DAY")

        self.timeLbl=[]
        self.dayLbl=[]
        for (rect,t) in tuple(zip([self.slot[0][x] for x in range(1,16)],[timeList[y] for y in range(1,16)])):
            self.timeLbl.append(self.can.create_text((self.can.bbox(rect)[0]+self.can.bbox(rect)[2])/2,(self.can.bbox(rect)[1]+self.can.bbox(rect)[3])/2,text=t))

        for (rect,d) in tuple(zip([self.slot[x][0] for x in range(1,7)],[dayList[y] for y in range(1,7)])):
            self.dayLbl.append(self.can.create_text((self.can.bbox(rect)[0]+self.can.bbox(rect)[2])/2,(self.can.bbox(rect)[1]+self.can.bbox(rect)[3])/2,text=d))

    def addCourse(self):
        self.course.append(CourseFrame(self.lSub2))
        self.course[-1].grid(row=self.addCourseBtn.grid_info()["row"],column=0,columnspan=4)
        self.addCourseBtn.grid(row=int(self.addCourseBtn.grid_info()["row"])+1)

    def addCondition1(self):
        self.con1.append(Condition(self.lSub3,typ=1))
        self.con1[-1].grid(row=self.addCondition1Btn.grid_info()["row"])
        self.addCondition1Btn.grid(row=int(self.addCondition1Btn.grid_info()["row"])+1)
    def addCondition2(self):
        self.con2.append(Condition(self.lSub4,typ=2))
        self.con2[-1].grid(row=self.addCondition2Btn.grid_info()["row"])
        self.addCondition2Btn.grid(row=int(self.addCondition2Btn.grid_info()["row"])+1)

    def start(self):
##        lsub=[]
##        lsub.append(SubLessonInstance("LEC","groupNum","FRI","0830-0930","LT2A",""))
##        lsub.append(SubLessonInstance("LEC","groupNum","THU","1230-1430","LT2A",""))
##        l=[]
##        l.append(LessonInstance("CSC","CZ2001","title",3.0,"",32429,lsub))
##
##        msub=[]
##        msub.append(SubLessonInstance("LEC","groupNum","MON","1300-1500","LT2A",""))
##        msub.append(SubLessonInstance("LEC","groupNum","WED","1330-1500","LT2A",""))
##        l.append(LessonInstance("CSC","CZ2001","title",3.0,"",32429,msub))
##
##
##        self.displayLessonInstanceList(l)
        crList=[]
        con1List=[]
        con2List=[]
        for cr in self.course:
            crList.append(courseInput(cr.getCourseEntry(),cr.getCheck1(),cr.getCheck2(),cr.getIndexEntry()))

        for con in self.con1:
            con1List.append(con1Input(con.getDayNum(),con.getLessonType(),con.getCompareType(),con.getTime()))
        for con in self.con2:
            con2List.append(con2Input(con.getWeekday(),con.getLessonType(),con.getCompareType(),con.getTime()))

        a=InputInstance(self.totalEntryVar.get(),crList,con1List,con2List)
        errMsg=validateInput(a)
        if errMsg=="":
            self.output=processInput(a)
            firstDisplay=next(self.output)
            print("R")
            self.displayLessonInstanceList(firstDisplay)
            self.nextBtn.configure(state=tk.NORMAL)
        else:
            #display error message in a popup window
            pass

##        print("The user intend to take {0} course(s)".format(self.totalEntryVar.get()))
##        print("The course options are ",end="")
##        for x in self.course:
##            print(x.getCourseEntry()+",",end="")
##        print("Among which,",end="")
##        for x in self.course:
##            if x.getCheck1()==1:
##                print(x.getCourseEntry()+",",end="")
##        print("are mandatory and",end="")
##        for x in self.course:
##            if x.getCheck1()==0:
##                print(x.getCourseEntry()+",",end="")
##        print("are optional.")
##
##        for x in self.course:
##            if x.getCheck2()==1:
##                print("For course {0}, only index number of ".format(x.getCourseEntry()),end="")
##                for y in x.getIndexEntry():
##                    print(y+",",end="")
##                print("should be considered")
##
##        if(self.con1CheckVar.get()==1):
##            print("Following Condition1s should be met:")
##            print("For each week:")
##            for x in self.con1:
##                print("No more than {0} day has {1} {2} than {3}".format(x.getDayNum(),x.getLessonType(),x.getCompareType(),x.getTime()))
##        else:
##            print("No Condition1 need to be considered.")
##
##        if(self.con2CheckVar.get()==1):
##            print("Following Condition2s should be met:")
##            for x in self.con2:
##                print("On {0}, no {1} {2} than {3}".format(x.getWeekday(),x.getLessonType(),x.getCompareType(),x.getTime()))
##        else:
##            print("No Condition2 need to be considered.")
##
    def reset(self):
        self.__init__()

    def toggleCon1(self):
        if self.con1CheckVar.get()==1:
            for x in self.con1:
                x.setNormal()
            self.addCondition1Btn.configure(state=tk.NORMAL)
        else:
            for x in self.con1:
                x.setDisabled()
            self.addCondition1Btn.configure(state=tk.DISABLED)
    def toggleCon2(self):
        if self.con2CheckVar.get()==1:
            for x in self.con2:
                x.setNormal()
            self.addCondition2Btn.configure(state=tk.NORMAL)
        else:
            for x in self.con2:
                x.setDisabled()
            self.addCondition2Btn.configure(state=tk.DISABLED)

    def displayLessonInstance(self,lesson):
        for subLesson in lesson.subList:
            h=timedelta(hours=subLesson.endTime.hour-subLesson.startTime.hour,minutes=subLesson.endTime.minute-subLesson.startTime.minute).seconds/3600*height
            print(h)
            sPointY=((subLesson.startTime.hour*60+subLesson.startTime.minute-510)/60+1)*height+startPoint[1]
            self.can.create_rectangle(
                self.can.bbox(subLesson.day)[0],
                sPointY,
                self.can.bbox(subLesson.day)[2],
                sPointY+h,
                tags=str(lesson),
                fill="#FFFFFF")
    def displayLessonInstanceList(self,lessonList):
        for lesson in lessonList:
            self.displayLessonInstance(lesson)

    def nextScreen(self):
        for rect in self.can.find_all():
            self.can.delete(rect)
        self.createEmptyTable()
        self.displayLessonInstanceList(next(self.output))
class CourseFrame(tk.Frame):

    def __init__(self,master=None):
        tk.Frame.__init__(self,master)
        self.grid(sticky=tk.N+tk.S+tk.E+tk.W)
        self.createInitalWidgets()

    def createInitalWidgets(self):
        self.indexEntry=[]
        self.indexEntryVar=[]
        self.indexDelBtn=[]

        self.courseEntryVar=tk.StringVar()

        self.courseEntry=tk.Entry(self,textvariable=self.courseEntryVar)

        self.courseCheck1Var=tk.IntVar()
        self.courseCheck1=tk.Checkbutton(self,variable=self.courseCheck1Var)

        self.courseCheck2Var=tk.IntVar()
        self.courseCheck2=tk.Checkbutton(self,command=self.createAddIndexBtn,variable=self.courseCheck2Var)
        self.delBtn=tk.Button(self,text="x",command=self.delCourse)

        self.courseEntry.grid(row=0,column=0)
        self.courseCheck1.grid(row=0,column=1)
        self.courseCheck2.grid(row=0,column=2)
        self.delBtn.grid(row=0,column=3)

    def createAddIndexBtn(self):
        if self.courseCheck2Var.get()==1:
            self.addIndexBtn=tk.Button(self,text="Add Index",command=self.addIndex)
            self.addIndexBtn.grid(row=1,column=0,sticky=tk.E)
        if self.courseCheck2Var.get()==0:
            for x in range(1,int(self.addIndexBtn.grid_info()["row"])+1):
                print(x)
                for w in self.grid_slaves(row=x):
                    w.grid_forget()

    def addIndex(self):
        self.indexEntryVar.append(tk.StringVar())
        self.indexEntry.append(tk.Entry(self,textvariable=self.indexEntryVar[-1]))
        self.indexEntry[-1].grid(row=self.addIndexBtn.grid_info()["row"],column=self.addIndexBtn.grid_info()["column"])
        delBtn=tk.Button(self,text="x")
        delBtn.bind('<Button-1>',self.delIndex)
        self.indexDelBtn.append(delBtn)
        self.indexDelBtn[-1].grid(row=self.addIndexBtn.grid_info()["row"],column=3)
        self.addIndexBtn.grid(row=int(self.addIndexBtn.grid_info()["row"])+1)

    def delIndex(self,event):
        for w in self.grid_slaves(row=event.widget.grid_info()["row"]):
            w.grid_forget()

    def delCourse(self):
        self.grid_forget()

    def getCourseEntry(self):
        return self.courseEntryVar.get()

    def getCheck1(self):
        return self.courseCheck1Var.get()

    def getCheck2(self):
        return self.courseCheck2Var.get()

    def getIndexEntry(self):
        indexEntry=[]
        for x in self.indexEntryVar:
            indexEntry.append(x.get())
        return indexEntry

class Condition(tk.Frame):
    def __init__(self,master=None,typ=1):
        self.typ=typ
        tk.Frame.__init__(self,master)
        self.grid(sticky=tk.N+tk.S+tk.E+tk.W)
        self.createInitalWidgets()
    def createInitalWidgets(self):

        if self.typ==1:
            self.textPart1=tk.Label(self,text="No more than ")
            dayNumList=(0,1,2,3,4,5)
            self.dayNumVar=tk.IntVar()
            self.dayNumVar.set(dayNumList[0])
            self.dayList=tk.OptionMenu(self,self.dayNumVar,*dayNumList)
            self.textPart2=tk.Label(self,text="day(s), has")

            self.textPart1.grid(row=0,column=0)
            self.dayList.grid(row=0,column=1)
            self.textPart2.grid(row=0,column=2)

        if self.typ==2:
            self.textPart1=tk.Label(self,text="On")
            weekdayTypeList=("Mon","Tue","Wed","Thu","Fri")
            self.weekdayVar=tk.StringVar()
            self.weekdayVar.set(weekdayTypeList[0])
            self.weekdayList=tk.OptionMenu(self,self.weekdayVar,*weekdayTypeList)
            self.textPart2=tk.Label(self,text=", no")

            self.textPart1.grid(row=0,column=0)
            self.weekdayList.grid(row=0,column=1)
            self.textPart2.grid(row=0,column=2)

        lessonTypeList=("lessons", "lectures", "tutorials", "labs")
        self.lessonTypeVar=tk.StringVar()
        self.lessonTypeVar.set(lessonTypeList[0])
        self.lessonList=tk.OptionMenu(self,self.lessonTypeVar,*lessonTypeList)

        compareTypeList=("earlier", "later")
        self.compareTypeVar=tk.StringVar()
        self.compareTypeVar.set(compareTypeList[0])
        self.compareList=tk.OptionMenu(self,self.compareTypeVar,*compareTypeList)

        self.textPart3=tk.Label(self,text="than")

        hrTypeList=tuple([x for x in range (7,22)])
        minTypeList=(00,30)
        self.hrVar=tk.IntVar()
        self.minVar=tk.IntVar()
        self.hrVar.set(hrTypeList[0])
        self.minVar.set(minTypeList[0])
        self.hrList=tk.OptionMenu(self,self.hrVar,*hrTypeList)
        self.minList=tk.OptionMenu(self,self.minVar,*minTypeList)

        self.colonLbl=tk.Label(self,text=":")

        self.delBtn=tk.Button(self,text="x",command=self.delCondition)

        self.lessonList.grid(row=0,column=3)
        self.compareList.grid(row=1,column=0)
        self.textPart3.grid(row=1,column=1)
        self.hrList.grid(row=1,column=2)
        self.colonLbl.grid(row=1,column=3)
        self.minList.grid(row=1,column=4)
        self.delBtn.grid(row=1,column=5)

    def delCondition(self):
        self.grid_forget()

    def getDayNum(self):
        return self.dayNumVar.get()

    def getWeekday(self):
        return self.weekdayVar.get()

    def getLessonType(self):
        return self.lessonTypeVar.get()

    def getCompareType(self):
        return self.compareTypeVar.get()

    def getTime(self):
        return str(self.hrVar.get())+":"+str(self.minVar.get())

    def setDisabled(self):

        for x in [self.lessonList,self.compareList,self.hrList,self.minList,self.delBtn]:
                x.configure(state=tk.DISABLED)
        if self.typ==1:
            self.dayList.configure(state=tk.DISABLED)
        else:
            self.weekdayList.configure(state=tk.DISABLED)

    def setNormal(self):
        for x in [self.lessonList,self.compareList,self.hrList,self.minList,self.delBtn]:
                x.configure(state=tk.NORMAL)
        if self.typ==1:
            self.dayList.configure(state=tk.NORMAL)
        else:
            self.weekdayList.configure(state=tk.NORMAL)


from datetime import date
from person import Person
from family import Family

def main():
    family = Family([
        Person('Trillian', date(1970, 3, 14)),
        Person('Arthur', date(1965, 7, 4)),
        Person('Ford', date(1995, 2, 2)),
        Person('Zaphod', date(1997, 5, 1)),
        Person('Douglas', date(1999, 4, 2))
    ])

    singles = [
        Person('Marvin', date(1991, 1, 1)),
        Person('Slarti', date(1993, 9, 9))
    ]

    oldest = None
    earliest_date = date.max
    for m in family:
        if m.birthdate < earliest_date:
            oldest = m
            earliest_date = m.birthdate

    for s in singles:
        if s.birthdate < earliest_date:
            oldest = s
            earliest_date = s.birthdate

    max_age = (date.today() - earliest_date).days / 365.2425
    print('Oldest person: {}; Age: {:6.2f}'.format(oldest.name, max_age))

if __name__ == '__main__':
    main()


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

def make_TDOA_from_microphone_position(mic_list,SOUNDSPEED,SimulationParams):
    for i in range(0,self.NODENUM-1):
        mic1 = self.mic_list[i]
        for j in range(i+1,self.NODENUM):
            mic2 = self.mic_list[j]
            distance = sqrt((mic1.pos_x - mic2.pos_x)**2 + (mic1.pos_y - mic2.pos_y)**2)
            error = 0
            mu,sigma = 0,0.1
            TDOA[i][j] = distance/self.SOUNDSPEED + error*np.random.normal(0,sigma)
    return TDOA


from keras.models import Model
from sklearn.preprocessing import LabelBinarizer
from keras.layers import Input, Dense, Conv2D, BatchNormalization, Flatten, MaxPooling2D, Lambda, ReLU
from keras.optimizers import Adam
import cv2
import imutils
import numpy as np
import math
from .helper import find_contour
import os

model_id_mapping = {
    "up": 1,
    "down": 2,
    "right": 3,
    "left": 4,
    "circle": 5,
    "six": 6,
    "seven": 7,
    "eight": 8,
    "nine": 9,
    "zero": 10,
    "v": 11,
    "w": 12,
    "x": 13,
    "y": 14,
    "z": 15
}

class CNN:
    def __init__(self, version):
        self.dim = 64
        self.lb = LabelBinarizer().fit(['circle', 'down', 'eight', 'left', 'nine', 'right', 'seven', 'six', 'up', 'v',
                                        'w', 'x', 'y', 'z', 'zero'])
        self.version = version
        self.font = cv2.FONT_HERSHEY_SIMPLEX
        self.local_image_count = 0

        if self.version == "gray":
            self.channels = 1
            self.model = self.getArchitecture()
            self.model.load_weights("./model/final.h5")  # load saved weights

        if self.version == "RGB":
            self.channels = 3
            self.model = self.getArchitecture()
            self.model.load_weights("./model/final_colour_final_1.h5")  # load saved weights

    # returns probability and class
    def predict(self, frame):
        img = np.reshape(frame, newshape=(1, self.dim, self.dim, self.channels))
        pred = self.model.predict(img)
        return self.lb.classes_[pred.argmax(axis=-1).item()], np.max(pred)

    # take in raw img and predict
    def raw_predict(self, img):
        if (self.channels == 1):
            gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        elif (self.channels == 3):
            gray = img
        bbs = find_contour(img)
        results = {
            "l": None,
            "c": None,
            "r": None
        }
        for rotated_bb, position in bbs:
            potential_image = gray[rotated_bb[1]:rotated_bb[3], rotated_bb[0]:rotated_bb[2]]
            if (self.channels == 1):
                height, width = potential_image.shape
            elif (self.channels == 3):
                height, width, _ = potential_image.shape
            if height != 0:
                potential_image = cv2.resize(potential_image, (64, 64), interpolation=cv2.INTER_CUBIC)
                potential_image = potential_image / 255
                reg_img = self.predict(potential_image)
                category, prob = reg_img
                if prob >= 0.90:

                    if results.get(position) is None:
                        results[position] = {
                            "category": model_id_mapping.get(category),
                            "prob": prob
                        }

                    else:
                        prev_prob = results.get(position).get("prob")
                        if prob > prev_prob:
                            results[position] = {
                                "category": model_id_mapping.get(category),
                                "prob": prob
                            }

                    cv2.rectangle(gray,
                                  (rotated_bb[0], rotated_bb[1]),
                                  (rotated_bb[2], rotated_bb[3]),
                                  (255, 255, 255),
                                  2)
                    cv2.putText(gray,
                                category + "\n" + str(position) + "\n" + str(((rotated_bb[0] - rotated_bb[2])*(rotated_bb[1]-rotated_bb[3]))),
                                (rotated_bb[0], rotated_bb[1] + 40),
                                self.font,
                                2,
                                (255, 255, 255),
                                2)

        self.save_to_local(gray)
        for category in results:
            result = results.get(category)
            if result is not None:
                result["prob"] = str(result.get("prob"))

        return results

    def save_to_local(self, img):
        cv2.imwrite(os.path.abspath(os.getcwd()) + "/model/" + '/reg_image/' + str(
            self.local_image_count) + '.jpg', img)
        self.local_image_count += 1

    # graph architecture of cnn
    def getArchitecture(self):
        input_layer = Input(shape=(self.dim, self.dim, self.channels))
        x = Conv2D(32, (3, 3), padding="same")(input_layer)
        x = BatchNormalization()(x)
        x = ReLU()(x)
        x = Conv2D(32, (3, 3), padding="same")(x)
        x = BatchNormalization()(x)
        x = ReLU()(x)
        x = MaxPooling2D()(x)

        x = Conv2D(64, (5, 5), padding="same")(x)
        x = BatchNormalization()(x)
        x = ReLU()(x)
        x = Conv2D(64, (5, 5), padding="same")(x)
        x = BatchNormalization()(x)
        x = ReLU()(x)
        x = MaxPooling2D()(x)

        x = Conv2D(128, (5, 5), padding="same")(x)
        x = BatchNormalization()(x)
        x = ReLU()(x)
        x = Conv2D(128, (5, 5), padding="same")(x)
        x = BatchNormalization()(x)
        x = ReLU()(x)
        x = MaxPooling2D()(x)

        x = Conv2D(256, (5, 5), padding="same")(x)
        x = BatchNormalization()(x)
        x = ReLU()(x)
        x = Conv2D(256, (5, 5), padding="same")(x)
        x = BatchNormalization()(x)
        x = ReLU()(x)
        x = MaxPooling2D()(x)

        x = Flatten()(x)
        x = Dense(512, activation="relu")(x)
        output = Dense(15, activation="softmax")(x)

        # Connect the inputs with the outputs
        cnn = Model(inputs=input_layer, outputs=output)
        cnn.compile(loss="categorical_crossentropy", optimizer=Adam(lr=0.00006, decay=1e-6))
        return cnn


import datetime
import re
import response_getter
import json
from helpers import  url_format, text_format
from CONSTANTS import *
import DataCollectors_Configuration
import uuid

def get_date_and_time():
    current_date = datetime.datetime.now()
    current_date.strftime("%y-%m-%d %H:%M:%S")
    current_date = str(current_date)
    return current_date.split(" ")

def get_hirerachy(hirerachy):
    items = hirerachy.split('|')
    length = len(items)
    category_names = ''
    for level in range(0, 10):
        if level < length:
            category_names = category_names + '{},'.format(items[level])
        else:
            category_names = category_names + 'not_available,'
    return category_names.split(',')

def get_product_specifications(raw_data):
    product_details_1 = raw_data.find('div', {'id': 'prodDetails'})
    product_details_2 = raw_data.find('table', {'id': 'productDetailsTable'})
    product_details_3 = raw_data.find('div', {'id': 'detailBullets_feature_div'})
    product_details_4 = raw_data.find('div', {'class': 'a-section a-spacing-large pzr-features-containers'})
    product_details_5 = raw_data.find('div', {'id': 'detail-bullets'})
    product_details_6 = raw_data.find('table', {'id': 'product-specification-table'})
    product_details_7 = raw_data.find('div', {'id': 'technicalSpecifications_feature_div'})
    product_details_8 = raw_data.find('div', {'id': 'detail_bullets_id'})
    specifications = {'default': 'not_available'}
    if product_details_2 and product_details_6:

        specification_container = product_details_2.find('td', {'class': 'bucket'})
        if specification_container:
            list1 = specification_container.findAll('li')
            for specs in list1:

                try:
                    spec = text_format(specs).split(':')
                    specifications.update(((spec[0], spec[1]),))
                except IndexError:
                    continue

        tr_tags = product_details_6.findAll('tr')
        if len(tr_tags) != 0:
            for tr_tag in tr_tags:
                if tr_tag.th:
                    key = text_format(tr_tag.th)
                    if key in 'Customer Reviews':
                        continue
                    else:
                        value = text_format(tr_tag.td)
                        specifications.update(((key, value),))
        return specifications

    elif product_details_4 and product_details_5:
        list1 = product_details_5.find_all('li')
        for specs in list1:
            try:
                spec = text_format(specs).split(':')

                specifications.update(((spec[0], spec[1]),))
            except IndexError:
                continue
        t_body = product_details_4.findAll('table')
        if len(t_body) != 0:
            for tag in t_body:
                tr_tags = tag.findAll('tr')
                for tr_tag in tr_tags:
                    if tr_tag.th:
                        key = text_format(tr_tag.th)
                        if key in 'Customer Reviews':
                            continue
                        else:
                            value = text_format(tr_tag.td)
                            specifications.update(((key, value),))
        return specifications

    elif product_details_8:
        list1 = product_details_8.find_all('li')
        for specs in list1:
            try:
                spec = text_format(specs).split(':')

                specifications.update(((spec[0], spec[1]),))
            except IndexError:
                continue
        return specifications

    elif product_details_7:
        table_container = product_details_7.find('table', {'id': 'technicalSpecifications_section_1'})
        if table_container:
            tr_tags = table_container.findAll('tr')
            if len(tr_tags) != 0:
                for tr in tr_tags:
                    if tr.th:
                        key = tr.th.text.strip()
                        if tr.td:
                            value = tr.td.text.strip()
                            specifications.update(((key, value),))
                        return specifications
    elif product_details_5:
        list1 = product_details_5.find_all('li')
        for specs in list1:
            try:
                spec = text_format(specs).split(':')

                specifications.update(((spec[0], spec[1]),))
            except IndexError:
                continue
        return specifications

    elif product_details_1:
        t_body = product_details_1.findAll('table')

        if len(t_body) != 0:
            for tag in t_body:

                tr_tags = tag.findAll('tr')
                for tr_tag in tr_tags:
                    if tr_tag.th:
                        key = text_format(tr_tag.th)
                        if key in 'Customer Reviews':
                            continue
                        else:
                            value = tr_tag.td.text.strip()
                            specifications.update(((key, value),))
                    else:
                        td_tags = tr_tag.findAll('td')
                        if len(td_tags) != 0 and len(td_tags) >= 2:
                            specifications.update(((text_format(td_tags[0]), text_format(td_tags[1])),))

            return specifications

    elif product_details_2:
        specification_container = product_details_2.find('td', {'class': 'bucket'})
        if specification_container:
            list1 = specification_container.findAll('li')
            for specs in list1:

                try:
                    spec = text_format(specs).split(':')
                    specifications.update(((spec[0], spec[1]),))
                except IndexError:
                    continue
        return specifications

    elif product_details_3:
        list2 = product_details_3.find_all('span', {'class': 'a-list-item'})
        for specs in list2:
            try:
                spec = text_format(specs).split(':')
                specifications.update(((spec[0], spec[1]),))
            except IndexError:
                continue
        return specifications
    else:
        return specifications

    return specifications

def get_brand(raw_data):
    brand_tag_1 = raw_data.find('a', {'id': 'bylineInfo'})
    brand_tag_2 = raw_data.find('a', {'id': 'brand'})
    if brand_tag_1:
        return text_format(brand_tag_1)
    elif brand_tag_2:
        brand_name = text_format(brand_tag_2)
        if len(brand_name) == 0:
            brand_image_tag = brand_tag_2.find('img')
            if brand_image_tag:
                brand_img = brand_image_tag['src']
                return brand_img
        return text_format(brand_tag_2)
    return 'not_availabe'

def get_title(raw_data):
    title_tag_1 = raw_data.find('span', {'id': 'productTitle'})
    title_tag_2 = raw_data.find('span', {'id': 'ebooksProductTitle'})
    if title_tag_1:
        title = text_format(title_tag_1)
        return title
    if title_tag_2:
        title = text_format(title_tag_2)
        return title
    else:
        return 'not_available'

def get_author_name(raw_data):
    author_tag_1 = raw_data.find('a', {'class': 'a-link-normal contributorNameID'})
    author_tag_2 = raw_data.find_all("span", {'class': 'author notFaded'})
    if author_tag_1:
        author_name = text_format(author_tag_1)
        return author_name
    elif author_tag_2:
        author_name = ''
        for auth in author_tag_2:
            auther_details = auth.text.replace("Author", "").replace("()", "").replace(",", "").replace("\n",
                                                                                "").strip() + "|"
            author_name = author_name + auther_details
        return author_name
    else:
        return 'not_available'

def get_product_rating(raw_data):
    rating_tag_1 = raw_data.find('a', {'id': 'cmrsSummary-popover'})
    rating_tag_2 = raw_data.find('div', {'class': 'a-spacing-none', 'id': 'averageCustomerReviews'})
    if rating_tag_2:

        rating_tag = rating_tag_2.find('span', {'class': 'a-icon-alt'})
        if rating_tag:
            rating = text_format(rating_tag)
            if rating:
                return rating.split('stars')[0]

    if rating_tag_1:
        rating_tag = rating_tag_1.find('span', {'class': 'a-icon-alt'})
        if rating_tag:
            rating = text_format(rating_tag)
            if rating:
                return rating.split('stars')[0]

    return 'not_available'

def get_selling_price(raw_data):
    price_tag_1 = raw_data.find('span', {'class': 'a-size-medium a-color-price offer-price a-text-normal'})
    price_tag_2 = raw_data.find('span', {'class': 'a-size-medium a-color-price header-price'})
    price_tag_3 = raw_data.find('span', {'id': 'priceblock_ourprice'})
    price_tag_4 = raw_data.find('span', {'class': 'a-size-medium a-color-price'})
    price_tag_5 = raw_data.find('tr', {'id': 'newPriceRow'})
    price_tag_6 = raw_data.find('tr', {'id': 'usedPriceRow'})
    price_tag_7 = raw_data.find('div', {'id': 'price-quantity-container'})
    price_tag_8 = raw_data.find('td', {'class': 'a-color-price a-size-medium a-align-bottom'})
    if price_tag_1:
        price_tag = price_tag_1.text
        if 'EUR' in price_tag:
            price = re.sub('[^0-9\-.,]', '', price_tag).replace(',', '.')
        else:
            price = re.sub('[^0-9\-.]', '', price_tag).replace(',', '')
        return price
    elif price_tag_2:
        price_tag = price_tag_2.text
        if 'EUR' in price_tag:
            price = re.sub('[^0-9\-.,]', '', price_tag).replace(',', '.')
        else:
            price = re.sub('[^0-9\-.]', '', price_tag).replace(',', '')
        return price
    elif price_tag_5:
        price_tag = price_tag_5.find('span', {'class': 'buyingPrice'})
        if price_tag:
            price_text = price_tag.text
            if 'EUR' in price_text:
                price = re.sub('[^0-9\-.,]', '', price_text).replace(',', '.')
            else:
                price = re.sub('[^0-9\-.]', '', price_text).replace(',', '')
            if len(price) != 0:
                return price
            elif price_tag_6:
                price_tag = price_tag_6.find('span', {'class': 'buyingPrice'})
                if price_tag:
                    price_text = price_tag.text
                    if 'EUR' in price_tag:
                        price = re.sub('[^0-9\-.,]', '', price_text).replace(',', '.')
                    else:
                        price = re.sub('[^0-9\-.]', '', price_text).replace(',', '')
                    return price
    elif price_tag_3:
        price_tag = price_tag_3.text
        if 'EUR' in price_tag:
            price = re.sub('[^0-9\-.,]', '', price_tag).replace(',', '.')
        else:
            price = re.sub('[^0-9\-.]', '', price_tag).replace(',', '')
        return price
    elif price_tag_4:
        price_tag = price_tag_4.text
        if 'EUR' in price_tag:
            price = re.sub('[^0-9\-.,]', '', price_tag).replace(',', '.')
        else:
            price = re.sub('[^0-9\-.]', '', price_tag).replace(',', '')
        return price
    elif price_tag_7:
        price_tag = price_tag_7.find('span', {'class':'a-size-large a-color-price guild_priceblock_ourprice'})
        if price_tag:
            price_tag = price_tag.text
            if 'EUR' in price_tag:
                price = re.sub('[^0-9\-.,]', '', price_tag).replace(',', '.')
            else:
                price = re.sub('[^0-9\-.]', '', price_tag).replace(',', '')
            return price
    elif price_tag_8:
        price_tag = price_tag_8.text
        if 'EUR' in price_tag:
            # I am spiting it because selling price and saved price are comming from same tag
            price_text = price_tag.strip().split(" ")
            price = re.sub('[^0-9\-.,]', '', price_text[1]).replace(',', '.')
        else:
            price_text = price_tag.strip().split(" ")
            price = re.sub('[^0-9\-.]', '', price_text[1]).replace(',', '')
        return price
    return 'not_available'

def get_original_price(raw_data):
    price_tag_1 = raw_data.find('span', {'class': 'a-color-secondary a-text-strike'})
    price_tag_2 = raw_data.find('span', {'class': 'a-text-strike'})
    price_tag_3 = raw_data.find('td', {'class': 'a-color-base a-align-bottom a-text-strike'})

    if price_tag_3:
        price_tag = price_tag_3.text
        if 'EUR' in price_tag:
            price = re.sub('[^0-9\-.,]', '', price_tag).replace(',', '.')
        else:
            price = re.sub('[^0-9\-.]', '', price_tag).replace(',', '')
        return price

    elif price_tag_1:
        price_tag = price_tag_1.text
        if 'EUR' in price_tag:
            price = re.sub('[^0-9\-.,]', '', price_tag).replace(',', '.')
        else:
            price = re.sub('[^0-9\-.]', '', price_tag).replace(',', '')
        return price

    elif price_tag_2:
        price_tag = price_tag_2.text
        if 'EUR' in price_tag:
            price = re.sub('[^0-9\-.,]', '', price_tag).replace(',', '.')
        else:
            price = re.sub('[^0-9\-.]', '', price_tag).replace(',', '')
        return price

    return 'not_available'

def get_saved_price(raw_data):
    price_container_1 = raw_data.find('ul', {'class': 'a-unordered-list a-nostyle a-vertical'})
    price_container_2 = raw_data.findAll('div', {'class': 'a-section a-spacing-none a-text-right'})
    price_container_3 = raw_data.find('td', {'class': 'a-span12 a-color-price a-size-base'})
    price_container_4 = raw_data.find('p',{'class': 'a-size-mini a-color-price ebooks-price-savings a-text-normal'})
    if len(price_container_2) != 0:

        for price_container in price_container_2:
            price_tag = price_container.find('span', {'class': 'a-nowrap'})
            if price_tag:
                saved_price = price_tag.find('span', {'class': 'a-size-base a-color-secondary'})
                if saved_price:
                    saved_price_tag = saved_price.text
                    if 'EUR' in price_tag:
                        price = re.sub('[^0-9\-()%.,]', '', str(saved_price_tag)).replace(',', '.')
                    else:
                        price = re.sub('[^0-9\-()%.]', '', str(saved_price_tag)).replace(',', '')
                    return price

    if price_container_1:
        price_tag = price_container_1.find('span', {'class': 'a-size-base a-color-secondary'})
        if price_tag:
            price_tag = price_tag.text
            if 'EUR' in price_tag:
                price = re.sub('[^0-9\-()%.,]', '', price_tag).replace(',', '.')
            else:
                price = re.sub('[^0-9\-()%.]', '', price_tag).replace(',', '')
            return price

    if price_container_3:
        price_tag = price_container_3.text
        if 'EUR' in price_tag:
            price = re.sub('[^0-9\-()%.,]', '', price_tag).replace(',', '.')
        else:
            price = re.sub('[^0-9\-()%.]', '', price_tag).replace(',', '')
        return price

    if price_container_4:
        price_tag = price_container_4.text
        if 'EUR' in price_tag:
            price = re.sub('[^0-9\-.()%,]', '', price_tag).replace(',', '.')
        else:
            price = re.sub('[^0-9\-()%.]', '', price_tag).replace(',', '')
        return price

    return 'not_available'

def get_availablity(raw_data):
    availablity_tag_1 = raw_data.find('div', {'id': 'availability'})
    availablity_tag_2 = raw_data.find('p', {'class': 'a-spacing-micro a-color-secondary a-text-bold'})
    if availablity_tag_1:
        availablity = text_format(availablity_tag_1)
        return availablity
    elif availablity_tag_2:
        availablity = text_format(availablity_tag_2)
        return availablity
    return 'not_available'

def get_highlights(raw_data):
    highlights_tag_1 = raw_data.find('div', {'id': 'bookDescription_feature_div'})
    highlights_tag_2 = raw_data.find('div', {'id': 'feature-bullets'})
    highlights = {'text': []}
    if highlights_tag_1:
        highlights_container = highlights_tag_1.find('noscript')
        if highlights_container:
            highlights['text'].append(text_format(highlights_container))
            return highlights

    elif highlights_tag_2:

        highlights_container_1 = highlights_tag_2.find('ul', {'class': 'a-unordered-list a-vertical a-spacing-none'})
        highlights_container_2 = highlights_tag_2.find('span', {'class': 'a-color-base technicalData'})

        if highlights_container_1:
            highlights_list = highlights_container_1.findAll('li')
            if len(highlights_list) !=0:
                for highlights_text in highlights_list:
                    text = highlights_text.text.strip()
                    highlights['text'].append(text)
                return highlights

        if highlights_container_2:
            highlights_list = highlights_container_2.findAll('li')
            if len(highlights_list) != 0:
                for highlights_text in highlights_list:
                    text = highlights_text.text.strip()
                    highlights['text'].append(text)
                return highlights

    highlights['text'].append('not_available')
    return highlights

# returrns json object
def get_other_format_books_price(raw_data):
    other_format_price_container = raw_data.find('div', {'id': 'tmmSwatches'})
    other_prices = {'default': 'not_available'}
    if other_format_price_container:
        price_tags = other_format_price_container.findAll('span', {'class': 'a-list-item'})
        if len(price_tags) != 0:

            for price_tag in price_tags:
                book_type_tag = price_tag.find('a')
                price_container = price_tag.find('span', {'class': 'a-color-secondary'})
                if book_type_tag and price_container:
                    book_type = text_format(book_type_tag.span)
                    price = text_format(price_container)

                    other_prices.update(((book_type, price.replace('_', '')),))
            return other_prices
    else:
        return other_prices

def get_quantity(raw_data):
    quantity_container = raw_data.find('select', {'name': 'quantity'})
    if quantity_container:
        quantity_no = quantity_container.findAll('option')
        if len(quantity_no) != 0:
            quantity = text_format(quantity_no[-1])
            return quantity
        else:
            return 'not_available'
    else:
        return 'not_available'

def get_image_url(raw_data):
    image_container_1 = raw_data.find('div', {'id': 'img-wrapper'})
    image_container_2 = raw_data.find('div', {'id': 'mainImageContainer'})
    image_container_3 = raw_data.find('div', {'id': 'imgTagWrapperId'})
    image_container_4 = raw_data.find('div', {'id': 'ebooks-img-canvas'})
    if image_container_1:
        image_url_tag = image_container_1.find('img')
        if image_url_tag:
            image_url = image_url_tag['data-a-dynamic-image']
            return image_url
        else:
            return 'not_available'
    elif image_container_2:
        image_url_tag = image_container_2.find('img')
        if image_url_tag:
            image_url = image_url_tag['data-a-dynamic-image']
            return image_url
    elif image_container_3:
        image_url_tag = image_container_3.find('img')
        if image_url_tag:
            image_url = image_url_tag['data-a-dynamic-image']
            return image_url
        else:
            return 'not_available'
    elif image_container_4:
        image_url_tag = image_container_4.find('img')
        if image_url_tag:
            image_url = image_url_tag['data-a-dynamic-image']
            return image_url
        else:
            return 'not_available'

    return 'not_available'

# returns json object
def get_product_description(raw_data):
    description_container = raw_data.find('div', {'id': 'productDescription'})
    description = {'text': ''}
    if description_container:
        description_text_tag = description_container.find('div', {
            'class': 'a-expander-content a-expander-partial-collapse-content'})
        if description_text_tag:
            description['text'] = text_format(description_text_tag)
            return description
        else:
            description['text'] = text_format(description_container)
            return description

    else:
        description['text'] = 'not_available'
        return description

# Gets manufacturer of the product
def get_product_manufacturer(response):
    product_info_table_container_2 = response.find('div', {'class': 'aplus-v2 desktop celwidget'})
    from_manufracture = {'img': [], 'text': []}
    if product_info_table_container_2:

        description_images = product_info_table_container_2.findAll('img')
        description_paragraph = product_info_table_container_2.findAll('p')
        description_text = product_info_table_container_2.findAll('span', {'class': 'a-list-item'})

        if len(description_images) and len(description_text) and len(description_paragraph):

            for image in description_images:
                from_manufracture['img'].append(image['src'])
            for text in description_text:
                from_manufracture['text'].append(text_format(text))
            for text in description_paragraph:
                from_manufracture['text'].append(text_format(text))
            return from_manufracture

        elif len(description_images) and len(description_text):

            for image in description_images:
                from_manufracture['img'].append(image['src'])
            for text in description_text:
                from_manufracture['text'].append(text_format(text))
            return from_manufracture

        elif len(description_images) and len(description_paragraph):

            for image in description_images:
                from_manufracture['img'].append(image['src'])
            for text in description_paragraph:
                from_manufracture['text'].append(text_format(text))
            return from_manufracture

        elif len(description_images):
            for image in description_images:
                from_manufracture['img'].append(image['src'])
            return from_manufracture

        elif len(description_text):

            for text in description_text:
                from_manufracture['text'].append(text_format(text))
            return from_manufracture
    else:
        from_manufracture['text'].append('not_available')
        from_manufracture['img'].append('not_available')
        return from_manufracture

    # return 'not_available'

def get_product_no_of_reviews(page_soup):
    noofreviews = page_soup.find('span', {'id': 'acrCustomerReviewText'})
    if noofreviews:
        reviews_text = noofreviews.text.replace("customer reviews", "").replace(",", "")
        if reviews_text:
            reviews = re.sub('[^0-9\-:]', '', reviews_text)
            return reviews
        else:
            return "not_available"
    else:
        return "not_available"

def get_color_variantes(raw_data):
    varaiants_tag = raw_data.find('div', {'id': 'variation_color_name'})
    if varaiants_tag:
        varaiants_list = varaiants_tag.findAll('li')
        if len(varaiants_list):
            color_list = []
            for varaiants in varaiants_list:
                varaiant_1 = varaiants.find('img')
                varaiant_2 = varaiants.find('div',{'class':'twisterTextDiv text'})
                if varaiant_1:
                    # print varaiant
                    color = varaiant_1['alt']
                    color_list.append(color)
                elif varaiant_2:
                    color = text_format(varaiant_2)
                    color_list.append(color)
            return '|'.join(color_list)

    return 'not_available'

def get_style_variants(raw_data):
    style_tag_container = raw_data.find('div', {'id': 'twisterContainer'})
    if style_tag_container:

        style_list = style_tag_container.findAll('li')
        if len(style_list) != 0:
            style = []
            for style_tag in style_list:
                style_text = style_tag.find('span', {'class': 'a-size-base'})
                if style_text:
                    style_text = text_format(style_text)
                    if style_text:
                        style.append(style_text)
                else:
                    return 'not_available'
            return '|'.join(style)
        else:
            return 'not_available'
    else:
        return 'not_available'

def get_specail_promotion(raw_data):
    promotion_container = raw_data.find('div', {'id': 'quickPromoBucketContent'})
    promotion = {'text': []}
    if promotion_container:
        text_list = promotion_container.find_all('li')
        if len(text_list):
            for text_tag in text_list:
                text_string = text_format(text_tag)
                if text_string:
                    promotion['text'].append(text_string)
            return promotion
    promotion['text'].append('not_available')
    return promotion

def get_seller_info(seller_name, seller_raw_data):
    seller_rating = get_seller_rating(seller_raw_data)
    seller_store_link = get_seller_strore_link(seller_raw_data)
    seller_postive_rating = get_seller_positive_rating(seller_raw_data)
    seller_overall_rating = get_seller_overall_rating(seller_raw_data)  # json
    seller_description = get_seller_description(seller_raw_data)
    seller_detailed_information = get_seller_detailed_information(seller_raw_data)  # json

    return seller_name, seller_store_link, seller_rating, seller_postive_rating, \
           seller_overall_rating, seller_description, seller_detailed_information

def check_and_get_seller_data(raw_data):
    seller_name_tag = raw_data.find('a')
    if seller_name_tag:
        seller_name = text_format(seller_name_tag)
        seller_link = url_format(seller_name_tag['href'])
        seller_raw_data = response_getter.get_content(seller_link)
        if seller_raw_data:
            return get_seller_info(seller_name, seller_raw_data)
        else:
            return seller_name, 'not_available', 'not_available', 'not_available', 'not_available', 'not_available', 'not_available'
    else:
        seller_name = text_format(raw_data)
        if seller_name:
            return seller_name, 'not_available', 'not_available', 'not_available', 'not_available', 'not_available', 'not_available'
    return 'not_available', 'not_available', 'not_available', 'not_available', 'not_available', 'not_available', 'not_available'

def get_seller_details(page_soup):
    seller_container_1 = page_soup.find('div', {'id': 'merchant-info'})
    sellar_container_2 = page_soup.find('p', {'class': 'a-spacing-micro a-color-base'})
    if seller_container_1:
        return check_and_get_seller_data(seller_container_1)
    elif sellar_container_2:
        return check_and_get_seller_data(sellar_container_2)

    return 'not_available', 'not_available', 'not_available', 'not_available', 'not_available', 'not_available', 'not_available'

# returns json data
def get_seller_overall_rating(page_soup):
    seller_raing = {'30_days': {'positive': 'not_available', 'negative': 'not_available', 'neutral': 'not_available',
                                'count': 'not_available'},
                    '90_days': {'positive': 'not_available', 'negative': 'not_available', 'neutral': 'not_available',
                                'count': 'not_available'},
                    '120_days': {'positive': 'not_available', 'negative': 'not_available', 'neutral': 'not_available',
                                 'count': 'not_available'},
                    'life_time': {'positive': 'not_available', 'negative': 'not_available', 'neutral': 'not_available',
                                  'count': 'not_available'}
                    }

    rating_container = page_soup.find('table', {'id': 'feedback-summary-table'})
    if rating_container:
        tables = rating_container.findAll('tr')
        if len(tables) != 0:
            for row in tables[1:]:
                row_list = []
                td_tags = row.findAll('td')
                if len(td_tags) != 0:
                    for element in td_tags:
                        row_list.append((text_format(element)))
                    seller_raing['30_days'][row_list[0].lower()] = row_list[1]
                    seller_raing['90_days'][row_list[0].lower()] = row_list[2]
                    seller_raing['120_days'][row_list[0].lower()] = row_list[3]
                    seller_raing['life_time'][row_list[0].lower()] = row_list[4]
    return seller_raing

def get_seller_strore_link(raw_data):
    store_link_tag = raw_data.find('div', {'id': 'storefront-link'})
    if store_link_tag:
        if store_link_tag.a:
            return url_format(store_link_tag.a['href'])
        else:
            return 'not_avaible'
    else:
        return 'not_avaible'

def get_seller_rating(raw_data):
    rating_container = raw_data.find('span', {'class': 'a-icon-alt'})
    if rating_container:
        rating = text_format(rating_container)
        if 'template-formatted' in rating:
            return 'no_feedback'
        else:
            return rating
    else:
        return 'not_available'

def get_seller_positive_rating(raw_data):
    positive_rating = raw_data.find('a', {'class': 'a-link-normal feedback-detail-description'})
    if positive_rating:
        return text_format(positive_rating.b)
    else:
        return 'not_available'

def get_seller_detailed_information(raw_data):
    information_container = raw_data.findAll('div', {'class': 'a-column a-span6'})
    information = {'default': []}
    if len(information_container) != 0:
        for info_container in information_container:
            info_table_container = info_container.find('ul', {'class': 'a-unordered-list a-nostyle a-vertical'})
            if info_table_container:
                info_list = info_table_container.findAll('span', {'class': 'a-list-item'})
                for info_tag in info_list:
                    info_text = info_tag.find('ul', {'class': 'a-unordered-list a-nostyle a-vertical'})
                    if info_text:
                        key = text_format(info_tag.span)
                        information.update(((key, []),))

                        text_list = info_text.findAll('li')

                        if len(text_list) != 0:
                            for text_tag in text_list:
                                information[key].append(text_tag.text)
                    else:
                        text_tag = info_tag.text
                        if text_tag:
                            try:
                                key_value_pair = text_tag.split(':')
                                information.update(((key_value_pair[0], key_value_pair[1]),))
                            except IndexError:
                                continue
                return information
    information['default'].append('not_available')
    return information

def get_seller_description(raw_data):
    description_container_1 = raw_data.find('span', {'id': 'about-seller-text'})
    description_container_2 = raw_data.find('div', {'id': 'about-seller'})
    if description_container_1:
        description = text_format(description_container_1)
        if len(description) != 0:
            return description
    elif description_container_2:
        description = text_format(description_container_2)
        if len(description) != 0:
            return description
    else:
        return 'not_available'
    return 'not_available'

def get_rating_details(raw_data):
    rating_types = {'5_star': 'not_available',
                    '4_star': 'not_available',
                    '3_star': 'not_available',
                    '2_star': 'not_available',
                    '1_star': 'not_available'}
    review_container = raw_data.find('table', {'id': 'histogramTable'})
    if review_container:
        rating_tr_tag = review_container.findAll('tr')
        if len(rating_tr_tag) != 0:
            for rating_tr in rating_tr_tag:
                rt_list = []
                td_tags = rating_tr.findAll('td')
                if len(td_tags) != 0:
                    for td in td_tags:
                        if td.a:
                            rt_list.append(text_format(td.a))
                        else:
                            rt_list.append('0')
                    rating_types[rt_list[0]] = rt_list[-1]

            return rating_types
        else:
            return rating_types
    return rating_types

def find_if_handmade(raw_data):
    hand_made_container = raw_data.find('div', {'id': 'handmadeLogo_feature_div'})
    if hand_made_container:
        return True
    else:
        return False

def find_if_exits(input_val):
    if input_val:
        if 'not_available' in input_val:
            return 'not_available'
        return input_val.replace('_', '')
    else:
        return 'not_available'

def validate_selling_price(input_val):
    if input_val == '.':
        return 'not_available'
    else:
        return input_val

def find_average_price(input_val):
    if '-' in input_val:
        values = input_val.split('-')
        if len(values) !=0:
            avg = 0
            for value in values:
                avg = avg+float(value)
            avg = avg/2
            return avg
    if 'not_available' == input_val:
        return float(0)

    else:
        return float(input_val)

def get_data_for_cassandra(product_dic):
    product = dict()
    product['id']               = uuid.uuid1()
    product['asin']             = product_dic['asin']
    product['category']         = product_dic['category']
    product['category_level_1'] = product_dic['category_level_1']
    product['category_level_2'] = product_dic['category_level_2']
    product['category_level_3'] = product_dic['category_level_3']
    product['currency']         = product_dic['currency']
    product['date']             = product_dic['date']
    product['marketplace']      = product_dic['marketplace']
    product['price']            = find_average_price(product_dic['product_selling_price'])
    product['product_id']       = product_dic['product_id']
    product['seller_name']      = product_dic['seller_name']
    product['additional_info']  = {}

    product_keys = product.keys()
    product_dic_keys = product_dic.keys()

    for key in product_dic_keys:
        if key not in product_keys:
            product['additional_info'].update(((key, product_dic[key]),))

    return product

def get_data(raw_data, hierarchy, product_url):
    hirerachy_list = get_hirerachy(hierarchy)
    date = get_date_and_time()
    seller_name, seller_store_link, seller_rating, seller_postive_rating, seller_overall_rating, seller_description, seller_detailed_information = get_seller_details(
        raw_data)
    product = dict()
    specifications = get_product_specifications(raw_data)
    asin = 'not_available'
    try:
        asin = specifications.get('ASIN').replace('_', '')
    except AttributeError:
        if find_if_handmade(raw_data):
            pass
        else:
            return None

    # print(hirerachy_list)
    # product is a dictionary and used superset field names as keys and get values by your own
    # parsing methods and assign them key values

    product['sku']                            = 'NA'
    product['asin']                           = asin
    product['date']                           = date[0]
    product['time']                           = date[1]
    product['marketplace']                    = MARKET_PLACE_NAME
    product['domain']                         = DOMAIN_NAME
    product['category']                       = hirerachy_list[0]
    product['category_level_1']               = hirerachy_list[1]
    product['category_level_2']               = hirerachy_list[2]
    product['category_level_3']               = hirerachy_list[3]
    product['category_level_4']               = hirerachy_list[4]
    product['category_level_5']               = hirerachy_list[5]
    product['category_level_6']               = hirerachy_list[6]
    product['category_level_7']               = hirerachy_list[7]
    product['category_level_8']               = hirerachy_list[8]
    product['category_level_9']               = hirerachy_list[9]

    if DataCollectors_Configuration.WRITE_TO == WRITE_TO_CASSANDRA:
        product['condition']                    = 'NA'
        product['additional_policies']          = 'NA'
        product['description']                  = get_product_description(raw_data)
        product['highlights']                   = get_highlights(raw_data)
        product['rating_details']               = get_rating_details(raw_data)
        product['specifications']               = get_product_specifications(raw_data)
        product['seller_overall_rating']        = seller_overall_rating
        product['seller_description']           = seller_description
        product['return_policies']              = 'NA'
        product['warrenty']                     = 'NA'
        product['shipping_policies']            = 'NA'
        product['from_manufracture']            = get_product_manufacturer(raw_data)
        product['promotion']                    = get_specail_promotion(raw_data)
        product['other_format_prices']          = get_other_format_books_price(raw_data)
        product['seller_detailed_information']  = seller_detailed_information
    else:
        product['condition']                    = json.dumps({'condition': 'NA'})
        product['additional_policies']          = json.dumps({'Additional_policies': 'NA'})
        product['description']                  = json.dumps({'description': get_product_description(raw_data)})
        product['highlights']                   = json.dumps({'highlights': get_highlights(raw_data)})
        product['rating_details']               = json.dumps(get_rating_details(raw_data))
        product['specifications']               = json.dumps(get_product_specifications(raw_data))
        product['seller_overall_rating']        = json.dumps(seller_overall_rating)
        product['seller_description']           = json.dumps({'seller_description': seller_description})
        product['return_policies']              = json.dumps({'return_policies': 'NA'})
        product['warrenty']                     = json.dumps({'warrenty': 'NA'})
        product['shipping_policies']            = json.dumps({'shipping_policies': 'NA'})
        product['from_manufracture']            = json.dumps(get_product_manufacturer(raw_data))
        product['promotion']                    = json.dumps(get_specail_promotion(raw_data))
        product['other_format_prices']          = json.dumps(get_other_format_books_price(raw_data))
        product['seller_detailed_information']  = json.dumps(seller_detailed_information)

    product['saved_price']                  = get_saved_price(raw_data)
    product['added_date']                   = 'NA'
    product['availability']                 = get_availablity(raw_data)
    product['brand']                        = get_brand(raw_data)
    product['discount_percentage']          = 'NA'
    product['product_selling_price']        = validate_selling_price(get_selling_price(raw_data))
    product['product_EAN']                  = find_if_exits(specifications.get('EAN'))
    product['product_id']                   = 'NA'
    product['image_url']                    = get_image_url(raw_data)
    product['likes']                        = 'NA'
    product['isbn']                         = 'NA'
    product['isbn-10']                      = find_if_exits(specifications.get('ISBN-10'))
    product['isbn-13']                      = find_if_exits(specifications.get('ISBN-13'))
    product['MPN']                          = find_if_exits(specifications.get('Manufacturer_Part_Number'))
    product['name']                         = get_title(raw_data)
    product['no_of_reviews']                = get_product_no_of_reviews(raw_data)
    product['original_price']               = get_original_price(raw_data)
    product['rating']                       = get_product_rating(raw_data)
    product['shipping_price']               = 'NA'
    product['size']                         = 'NA'
    product['upc']                          = find_if_exits(specifications.get('UPC'))
    product['url']                          = product_url
    product['quantity_available']           = get_quantity(raw_data)
    product['products_slod']                = 'NA'
    product['seller_code']                  = 'NA'
    product['seller_location']              = 'NA'
    product['seller_name']                  = find_if_exits(seller_name)
    product['seller_negative_rating']       = 'NA'
    product['seller_neutral_rating']        = 'NA'
    product['seller_positive_rating']       = seller_postive_rating
    product['seller_rank']                  = 'NA'
    product['seller_store_link']            = seller_store_link
    product['seller_year_of_joining']       = 'NA'
    product['shipping_available_countries'] = 'NA'
    product['shipping_location']            = 'NA'
    product['shipping_logistic_name']       = 'NA'
    product['shipping_price']               = 'NA'
    product['shop_location']                = 'NA'
    product['shop_name']                    = 'NA'
    product['no_of_sales']                  = 'NA'
    product['shop_rating']                  = seller_rating
    product['Tax_info']                     = 'NA'
    product['Visibility']                   = 'NA'
    product['currency']                     = CURRENCY
    product['color_variants']               = get_color_variantes(raw_data)
    product['style_variants']               = get_style_variants(raw_data)
    product['author_name']                  = get_author_name(raw_data)

    return product


#reportlab es la biblioteca que permite la creacion del PDF de la receta medica, de acuerdo a la enfermedad detectada

# MODULOS A UTILIZAR:
# ==================
import datetime					# Módulo empleado para obtener la fecha y hora.
import Enfermedades				# Módulo empleado para determinar la enfermedad.

from reportlab.lib.pagesizes import letter
from reportlab.pdfgen import canvas
from reportlab.platypus import  Image
from reportlab.lib.colors import blue, gray, black
from reportlab.lib.units import cm

""" Generacion_Receta es la función que crea un PDF con una receta de acuerdo a la enfermedad detectada y con los datos ingresados por el paciente"""

#=======VARIABLES OBTENIDAS DESDE EL MODULO ENFERMEDADES=======

#Datos de prueba:
#self_nombre = "Carolina"
#self_edad = "27"
#self_estatura = "1.68"
#self_peso = "61"
#self_sexo = "F"

#=====NOMBRE DEL ARCHIVO PDF A CREAR Y TAMAÑO DE LA HOJA======

#self_nombre = ventana1.nombre

# GENERACIÓN DE LA RECETA:
# =======================
def Generacion_Receta(self_nombre, self_edad, self_estatura, self_peso, self_sexo,enfermedad,medicamento,dosis,categoria,dias):

    'Generacion_Receta es la función que crea un PDF con una receta de acuerdo a la enfermedad detectada y con los datos ingresados por el paciente'

    Nombre_Archivo  = "Receta" + self_nombre + ".pdf"
    c = canvas.Canvas(Nombre_Archivo,pagesize=letter)
    width, height = letter

    # ENCABEZADO DE LA RECETA.-
    # ------------------------

    #Ancho de linea para todo el archivo
    c.setLineWidth(0.1 * cm)

    # Tipo de letra y tamaño
    c.setFont('Helvetica-Bold',24)
    # Texto y ubicacion
    c.drawCentredString(270,760,"I-DOC")
    # Tipo de letra y tamaño
    c.setFont('Helvetica-Bold',20)
    # Color de la letra
    c.setFillColor(black)
    # Texto
    c.drawString(100,720,"Tu Especialista en Enfermedades Comunes")
    #Lineas de separacion
    c.line(10,710,550,710)
    c.line(10,705,550,705)

    # UBUCACIÓN DEL LOGO.-
    # -------------------
    c.drawImage('LogoDoc.jpg',450,610)

    # DATOS DEL PACIENTE.-
    # -------------------
    # Tipo de letra y tamaño
    c.setFont('Helvetica-Bold',16)
    # Texto y ubicacion
    c.drawString(50,680,"Nombre:")
    #Color de la letra
    c.setFillColor(gray)
    # Texto y ubicacion
    c.drawString(120,680, self_nombre)
    #Color de la letra
    c.setFillColor(black)
    # Texto y ubicacion
    c.drawString(50,660,"Edad:")
    #Color de la letra
    c.setFillColor(gray)
    # Texto
    c.drawString(100,660, self_edad + " " + "años")
    #Color de la letra
    c.setFillColor(black)
    # Texto
    c.drawString(50,640,"Estatura:")
    #Color de la letra
    c.setFillColor(gray)
    # Texto
    c.drawString(125,640, self_estatura + " " + "mts.")
    #Color de la letra
    c.setFillColor(black)
    # Texto
    c.drawString(50,620,"Peso:")
    #Color de la letra
    c.setFillColor(gray)
    # Texto
    c.drawString(100,620, self_peso + " " + "Kgs.")
    #Color de la letra
    c.setFillColor(black)
    # Texto
    c.drawString(50,600,"Sexo:")
    #Color de la letra
    c.setFillColor(gray)
    # Texto
    c.drawString(100,600,self_sexo)

    #Lineas de separacion
    c.line(10,590,550,590)
    c.line(10,585,550,585)

    # CONTENIDO DE LA RECETA.-
    # -----------------------
    # Tipo de letra y tamaño
    c.setFont('Helvetica-Bold',18)
    #Color de la letra
    c.setFillColor(black)
    # Texto
    c.drawString(200,560,"RECETA MÉDICA")
     #Linea subarallado
    c.line(197,555,355,555)

    # Tipo de letra y tamaño
    c.setFont('Helvetica-Bold',16)

    # Texto
    c.drawString(50,530,"Diagnóstico:")
     #Color de la letra
    c.setFillColor(blue)
    # Texto
    c.drawString(170,530,enfermedad)
     #Color de la letra
    c.setFillColor(black)
    # Texto
    c.drawString(50,460,"Tratamiento:")
     #Color de la letra
    c.setFillColor(blue)
    # Texto
    c.drawString(170,460,'Tomar'+ ' ' + str(dosis) + ' '+ '[mg] de'+ ' '  + medicamento)
    #Color de la letra
    c.setFillColor(black)
    # Texto
    c.drawString(50,390,"Categoría Médica:")
    #Color de la letra
    c.setFillColor(blue)
    # Texto
    c.drawString(192,390,categoria + ' ' + 'por'+ ' ' + dias + ' ' + 'dias')

    #Lineas de separacion
    c.line(10,330,550,330)
    c.line(10,325,550,325)

    # FIRMA Y FECHA.-
    # ---------------
    #Insertar fecha y hora de generacion de la receta
     #Color de la letra
    c.setFillColor(black)
    actual = datetime.datetime.today()
    fecha = actual.strftime("%h %d %Y %H:%M:%S")
    textobject = c.beginText()
    textobject.setTextOrigin(50,290)
    textobject.textLines('''Fecha de Emision de la Receta: %s ''' % fecha)
    c.drawText(textobject)

    #Firma médico Tratante
    c.drawString(50,250,"Firma Médico Tratante:")
    c.setFont('Times-BoldItalic',16)
    c.drawString(235,250,"I-Doc")

    #Lineas de separacion
    c.line(10,230,550,230)
    c.line(10,225,550,225)

# Finaliza la hoja del archivo
    c.showPage()
#Guarda el archivo PDF generado
    c.save()


import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.nn.utils.rnn import PackedSequence

class SequencePoolingLayer(nn.Module):
    """The SequencePoolingLayer is used to apply pooling operation(sum,mean,max) on variable-length sequence feature/multi-value feature.
      Input shape
        - A list of two  tensor [seq_value,seq_len]
        - seq_value is a 3D tensor with shape: ``(batch_size, T, embedding_size)``
        - seq_len is a 2D tensor with shape : ``(batch_size, 1)``,indicate valid length of each sequence.
      Output shape
        - 3D tensor with shape: ``(batch_size, 1, embedding_size)``.
      Arguments
        - **mode**:str.Pooling operation to be used,can be sum,mean or max.
    """

    def __init__(self, mode='mean', supports_masking=False, device='cpu'):

        super(SequencePoolingLayer, self).__init__()
        if mode not in ['sum', 'mean', 'max']:
            raise ValueError('parameter mode should in [sum, mean, max]')
        self.supports_masking = supports_masking
        self.mode = mode
        self.device = device
        self.eps = torch.FloatTensor([1e-8]).to(device)
        self.to(device)

    def _sequence_mask(self, lengths, maxlen=None, dtype=torch.bool):
        # Returns a mask tensor representing the first N positions of each cell.
        if maxlen is None:
            maxlen = lengths.max()
        row_vector = torch.arange(0, maxlen, 1).to(lengths.device)
        matrix = torch.unsqueeze(lengths, dim=-1)
        mask = row_vector < matrix

        mask.type(dtype)
        return mask

    def forward(self, seq_value_len_list):
        if self.supports_masking:
            uiseq_embed_list, mask = seq_value_len_list  # [B, T, E], [B, 1]
            mask = mask.float()
            user_behavior_length = torch.sum(mask, dim=-1, keepdim=True)
            mask = mask.unsqueeze(2)
        else:
            uiseq_embed_list, user_behavior_length = seq_value_len_list  # [B, T, E], [B, 1]
            mask = self._sequence_mask(user_behavior_length, maxlen=uiseq_embed_list.shape[1],
                                       dtype=torch.float32)  # [B, 1, maxlen]
            mask = torch.transpose(mask, 1, 2)  # [B, maxlen, 1]

        embedding_size = uiseq_embed_list.shape[-1]

        mask = torch.repeat_interleave(mask, embedding_size, dim=2)  # [B, maxlen, E]

        if self.mode == 'max':
            hist = uiseq_embed_list - (1 - mask) * 1e9
            hist = torch.max(hist, dim=1, keepdim=True)[0]
            return hist
        hist = uiseq_embed_list * mask.float()
        hist = torch.sum(hist, dim=1, keepdim=False)

        if self.mode == 'mean':
            self.eps = self.eps.to(user_behavior_length.device)
            hist = torch.div(hist, user_behavior_length.type(torch.float32) + self.eps)

        hist = torch.unsqueeze(hist, dim=1)
        return hist


# Love Calculator

# Instructions

# You are going to write a program that tests the compatibility between two people.
# To work out the love score between two people:

# > Take both people's names and check for the number of times the letters in the word TRUE occurs. Then check for the number of times the letters in the word LOVE occurs. Then combine these numbers to make a 2 digit number.
# For Love Scores **less than 10** or **greater than 90**, the message should be:
# `"Your score is **x**, you go together like coke and mentos."`

# For Love Scores **between 40** and **50**, the message should be:
# `"Your score is **y**, you are alright together."`

# Otherwise, the message will just be their score. e.g.:
# `"Your score is **z**."`

# 🚨 Don't change the code below 👇
print("Welcome to the Love Calculator!")
name1 = input("What is your name? \n")
name2 = input("What is their name? \n")
# 🚨 Don't change the code above 👆

# Write your code below this line 👇
name = str.lower(name1 + name2)
t = name.count("t")
r = name.count("r")
u = name.count("u")
e = name.count("e")
true = str(t + r + u + e)
print(true)
l = name.count("l")
o = name.count("o")
v = name.count("v")
e = name.count("e")
love = str(l + o + v + e)
print(love)
true_love = true + love
print(true_love)
total = int(true_love)

if total < 10 or total > 90:
    print(f"Your score is **{total}**, you go together like coke and mentos.")
elif total >= 40 and total <= 50:
    print(f"Your score is **{total}**, you are alright together.")
else:
    print(f"Yout score is **{total}**")


#7. В одномерном массиве целых чисел определить два наименьших элемента.
# Они могут быть как равны между собой (оба минимальны), так и различаться.

import random

a = [random.randint(1, 100) for _ in range(10) ]
print(a)

a_min_1 = a[0]
a_min_2 = a[0]

for item in a:
    if (item<a_min_1):
        a_min_2 = a_min_1
        a_min_1 = item
    elif (item< a_min_2):
        a_min_2 = item

print(a_min_1)
print(a_min_2)


import argparse
import logging
from pathlib import Path
import time
import platform
import os
import sys
import re
import subprocess
import tempfile
import pandas as pd

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(os.path.basename(__file__))

def _profile_windows(args):
    indexes = [
        '\\Processor Information(*)\\% Processor Time',
        '\\Processor Information(*)\\% Idle Time',
        '\\Processor Information(*)\\Interrupts/sec',
        '\\Processor(*)\\% User Time',
        '\\Processor(*)\\% Privileged Time',
        '\\System\\Processor Queue Length',
        '\\Memory\\Available MBytes',
        '\\Memory\\Pages/sec',
        '\\Memory\\Committed Bytes',
        '\\PhysicalDisk(*)\\% Disk Time',
        '\\PhysicalDisk(*)\\Current Disk Queue Length',
        '\\PhysicalDisk(*)\\Disk Reads/sec',
        '\\PhysicalDisk(*)\\Disk Writes/sec',
        '\\LogicalDisk(*)\\Current Disk Queue Length',
        '\\LogicalDisk(*)\\Avg. Disk Queue Length',
        '\\LogicalDisk(*)\\Avg. Disk Read Queue Length',
        '\\LogicalDisk(*)\\Avg. Disk Write Queue Length',
        '\\PhysicalDisk(*)\\Current Disk Queue Length',
        '\\PhysicalDisk(*)\\Avg. Disk Queue Length',
        '\\PhysicalDisk(*)\\Avg. Disk Read Queue Length',
        '\\PhysicalDisk(*)\\Avg. Disk Write Queue Length',
        '\\Network Interface(*)\\Bytes Total/sec',
        '\\Paging File(*)\\% Usage'
    ]
    _, tmp_index = tempfile.mkstemp()
    with open(tmp_index, 'w') as f:
        f.write('\n'.join(indexes))

    _, tmp_result = tempfile.mkstemp()
    tmp_result = tmp_result + '.csv'

    cmd_perf = 'typeperf -y -cf {index} -si {interval} -f csv -o {result}'.format(
        index=tmp_index,
        interval=args.interval,
        result=tmp_result
    )

    proc_perf = subprocess.Popen(cmd_perf, shell=True)

    cmd_command = args.command
    subprocess.run(cmd_command, shell=True, check=False)

    proc_perf.kill()

    df = pd.read_csv(tmp_result)
    df = df.dropna()
    col_alter = {}
    for i, col in enumerate(df.columns):
        if i == 0:
            col_alter[col] = 'time'
        else:
            items = col.split('\\')[3:]
            col_alter[col] = '-'.join(items)

    df = df[1:]
    df = df.rename(columns=col_alter)
    def convert_time(x):
        col = x.split(' ')
        col_date = col[0].split('/')
        col_time = col[1].split('.')
        return col_date[2]+'-'+col_date[1]+'-'+col_date[0]+' '+col_time[0]

    df['time'] = df['time'].apply(convert_time)

    df.to_csv(args.RESULT_FILE, index=None)

    if args.average:
        se_mean = df.mean()
        df_mean = pd.DataFrame(se_mean).T

        df_mean.to_csv(args.average, index=None)

def _profile_linux(args):
    pass

def main(args):
    if platform.system() == 'Windows':
        _profile_windows(args)
    else:
        _profile_linux(args)

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Server profiler')
    parser.add_argument('-c', '--command', type=str, required=True, help='command')
    parser.add_argument('-i', '--interval', type=str, required=False, default=5, help='iterval sec')
    parser.add_argument('-a', '--average', type=str, required=False, default="", help='path to result file as average')
    parser.add_argument('RESULT_FILE', type=str, help='path of result file')
    args = parser.parse_args()
    main(args)


import pandas as pd
import numpy as np
DataTrain = pd.read_pickle("../../Data/CICMalDroid_Train.csv")
DataTest = pd.read_pickle("../../Data/CICMalDroid_Test.csv")
# DataZero = pd.read_pickle("../../Data/ZD.csv")

featureMatrixTR = DataTrain.iloc[:,:-1].values
labelVectorTR = DataTrain.iloc[:,-1].values
featureMatrix = DataTest.iloc[:,:-1].values
labelVector = DataTest.iloc[:,-1].values
# featureMatrixZ = DataZero.iloc[:,:-1].values
# labelVectorZ = DataZero.iloc[:,-1].values

#       3 Scaling the dataSet
from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
featureMatrixTR = sc.fit_transform(featureMatrixTR)
featureMatrix = sc.fit_transform(featureMatrix)
# featureMatrixZ = sc.fit_transform(featureMatrixZ)

# from tensorflow.keras.utils import to_categorical
# labelVector = to_categorical(labelVector)
from sklearn.preprocessing import LabelEncoder
labelencoder = LabelEncoder()
labelVectorTR = labelencoder.fit_transform(labelVectorTR)
labelVector = labelencoder.fit_transform(labelVector)
# labelVectorZ = labelencoder.fit_transform(labelVectorZ)

# # Feature Extraction
# from sklearn.feature_selection import SelectKBest
# from sklearn.feature_selection import f_classif
#
# selector = SelectKBest(f_classif, k=100)
# selected_features = selector.fit_transform(featureMatrix, labelVector)
#
# print((-selector.scores_).argsort()[:])

import xgboost as xgb
train = xgb.DMatrix(featureMatrixTR, label=labelVectorTR)
test = xgb.DMatrix(featureMatrix, label=labelVector)
# testZ = xgb.DMatrix(featureMatrixZ, label=labelVectorZ)

param = {
    "max_depth":4,
    "eta": 0.3,
    # "objective": "mutli:softmax",
    "num_class": 13,
    "verbosity": 3}
epochs = 3

model = xgb.train(param, train, epochs)
predictions = model.predict(test)

## TESTING
# Y_pred = model.predict(featureMatrix)
from sklearn.metrics import classification_report,confusion_matrix
RF_predictions = model.predict(test)
cm = confusion_matrix(labelVector, RF_predictions)
print(classification_report(labelVector, RF_predictions,digits=4))

from sklearn.metrics import roc_auc_score
from sklearn.preprocessing import LabelBinarizer

lb = LabelBinarizer()
lb.fit(labelVector)
labelVector = lb.transform(labelVector)
RF_predictions = lb.transform(RF_predictions)

auc = roc_auc_score(labelVector, RF_predictions,multi_class="ovo")
# auc = roc_auc_score(labelVector, RF_predictions,multi_class="ovo", labels=["0","1","2","3","4","5","6","7","8","9","10","11","12"] )
print('ROC AUC: %f' % auc)

# ZeroDay Tests

# from sklearn.metrics import classification_report,confusion_matrix
# predictionZ = model.predict(testZ)
# cm = confusion_matrix(labelVectorZ, predictionZ)
# print(classification_report(labelVectorZ, predictionZ,digits=4))
# from sklearn.metrics import roc_auc_score
# auc = roc_auc_score(labelVectorZ, predictionZ.round())
# print('ROC AUC: %f' % auc)


# Quantum Grover's algorithm. Implemented as described in lecture.

import numpy as np
from pyquil import get_qc, Program
from pyquil.api import QuantumComputer
from pyquil.gates import *

from grover_classical import test_only_one, test_01, test_000, test_10010, test_1111
from util import create_Z0_matrix, create_Zf_matrix, process_results, send_to_server

import time
import sys
import argparse
import math

def create_lambda_with_globals(s):
    return eval(s, globals())

parser = argparse.ArgumentParser()

parser.add_argument("-n",dest="n", type=int, required=True)
parser.add_argument("-f",dest="f", type=create_lambda_with_globals, required=True)
parser.add_argument('--aspen', action = 'store_true', default = False)
parser.add_argument('--send_to_server', action = 'store_true', default = False)
parser.add_argument('--email', default = '')
args = parser.parse_args()

n = args.n
f = args.f
t = 10

start = time.time()

p = Program()
p.defgate("Z_0", create_Z0_matrix(n))
p.defgate("Z_f", create_Zf_matrix(f, n))

num_iter = math.floor((math.pi / 4) * math.sqrt(2**n))

if args.aspen:
    if n > 12:
        raise ValueError("Aspen only has 12 qubits.")
    qubits = [0, 1, 2, 6, 7, 10, 11, 13, 14, 15, 16, 17]
    qubits = qubits[:n]
else:
    qubits = range(n)

# Initial Hadamard
for q in qubits:
    p.inst(H(q))
# Repeat G
for i in range(num_iter):
    p.inst(("Z_f",) + tuple(qubits[::-1]))
    for q in qubits:
        p.inst(H(q))
    p.inst(("Z_0",) + tuple(qubits[::-1]))
    for q in qubits:
        p.inst(H(q))

if args.aspen:
    qc = get_qc('Aspen-4-12Q-A', as_qvm=True)
    qc.compiler.client.timeout = 100
    if args.send_to_server and args.email != '':
        p_out = "# grover F=" + args.f.__name__ + " N=" + str(args.n) + "\n" + p.out()
        print("program: ", p_out)
        print("email: ", args.email)
        send_to_server(p_out, args.email)
    else:
        result = qc.run_and_measure(p, trials = t)
        end = time.time()
        print(process_results(result, qubits))
        print("Execution time: ", end - start)
else:
    # You can make any 'nq-qvm' this way for any reasonable 'n'
    qc = get_qc(str(n)+'q-qvm')
    qc.compiler.client.timeout = 100
    result = qc.run_and_measure(p, trials = t)
    end = time.time()
    print(process_results(result, qubits))
    print("Execution time: ", end - start)


"""Defines training regimens."""

import copy

import numpy as np
import tensorflow as tf
import tensorflow.keras as keras

class OptimizerRegimen:
    """This class defines a simple regimen using one optimizer and one set of
    values.

    Often, we wish to optimize a set of values by simply minimizing them up to
    a certain accuracy or at most for a number of steps. This simple class makes
    such a task easier.

    Args:
        optimizer: Any object that can handle a tensor with its 'minimize'
            method.
        eps: If the maximal difference between the last two estimates
            is below this value, the regimen stops.
        max_steps: If this number of steps has been exceeded, the regimen stops.
    """

    def __init__(self, optimizer, eps=1e-5, max_steps=1e5):
        self.optimizer = optimizer
        self.eps = tf.constant(eps)
        self.max_steps = max_steps
        self.n_steps = 0
        self._grads = False
        self.metrics = None

    def start_batch(self):
        """Saves the estimated variables as the old values and increments the
        step number."""
        self._grads = True
        self.n_steps += 1

    def finish_batch(self, metrics=None, it_baseline=0):
        """This function takes care of cleaning up the metrics."""
        metrics = metrics or []
        for metric in metrics:
            tf.summary.scalar(
                metric.name, metric.result(),
                step=it_baseline + self.optimizer.iterations
            )
            metric.reset_states()

    def training_step(self, loss_fun, variables, metrics=None):
        """Take a minimizing step for a tensor or a set of tensors.

        This function uses the optimizer to minimize the 'loss'.

        Args:
            gradients: The gradient the step should follow.
            variables: The variables that should be changed.
        """
        metrics = metrics or []
        self._grads = self._training_step(loss_fun=loss_fun,
                                          variables=variables,
                                          _grads=self._grads,
                                          eps=self.eps,
                                          metrics=metrics)

    @tf.function
    def _training_step(self, loss_fun, variables, _grads, eps, metrics): # pragma: no cover
        # (is only executed within Tensorflow call.)
        with tf.GradientTape() as tape:
            [losses, predictions, values] = loss_fun()
        gradients = tape.gradient(losses, variables)
        gen = []
        for metric in metrics:
            metric.update_state(values, predictions)
        for grad, var in zip(gradients, variables):
            if grad is not None:
                gen.append((grad, var))
                _grads = _grads and (
                    tf.math.reduce_all(
                        tf.pow(tf.reshape(grad, [-1]), 2) < eps
                    )
                )
        self.optimizer.apply_gradients(gen)
        return _grads

    def end(self):
        """The regimen ends when the variables do not change by a significant
        amount anymore or the number of steps have been exceeded.
        """
        if self.n_steps == 0 and self.max_steps > 0:
            return False
        return self._grads or (self.n_steps >= self.max_steps)

    def train(self, loss_fun, variables, metrics=None, it_baseline=0):
        """Trains a model until convergence or the maximum number of steps
        have been exceeded.
        """
        metrics = metrics or []
        while not self.end():
            self.start_batch()
            self.training_step(loss_fun, variables, metrics=metrics)
            self.finish_batch(metrics=metrics, it_baseline=it_baseline)

    def steps_until_convergence(self):
        """Returns the number of steps until convergence.

        If the regimen has converged, returns the step after which the gradient
        was below the threshold. If not, it returns numpy.nan.
        """
        if self._grads:
            return self.n_steps-1
        return np.nan

    def restart(self):
        """Restarts a regimen.

        This categorizes the metrics accordingly, and sets the steps back
        to zero."""
        self.n_steps = 0

    @property
    def iterations(self):
        """The optimizer's iterations."""
        return self.optimizer.iterations

class ConstantRegimen(OptimizerRegimen):
    """This class defines a regimen that remains constant and does not affect
    the corresponding variables."""
    def __init__(self):
        super().__init__(None, max_steps=-1, eps=np.inf)

    def start_batch(self):
        """Indicates the start of a batch in the training regimen.
        """

    def finish_batch(self, metrics=None, it_baseline=0):
        """Indicates the end of a patch in the training regimen."""

    def training_step(self, loss_fun, variables, metrics=None):
        """A single training step."""

    def end(self):
        """Always indicates that the regimen has ended."""
        return True

    def steps_until_convergence(self):
        """Indicates that it took 0 steps until convergence."""
        return 0

    def restart(self):
        """Restarts the regimen."""

    def train(self, loss_fun, variables, metrics=None, it_baseline=0):
        """A training session."""

    @property
    def iterations(self):
        """Returns constant 0, since there are not iterations."""
        return 0

class EMRegimen:
    """This regimen implements an expectation maximization algorithm.

    The expectation maximization algorithm can be used to infer latent states
    and estimate the weights connecting these latent states with observations
    at the same time (see Dempster et al., 1987). This regimen accordingly
    consists of a state regimen and a predictor regimen.

    Since the states are lost if there are several batches that are being
    iterated over, predictor convergence is used as the general convergence
    criterion (with state convergence being the logical implication).

    Args:
        state_regimen: The regimen used for the state estimation.
        predictor_regimen: The regimen used for the predictor estimation.
    """

    def __init__(self, state_regimen, predictor_regimen):
        self.state_regimen = state_regimen
        self.predictor_regimen = predictor_regimen
        self.n_steps = 0
        self.metrics = None
        self._sut = [False]
        self._state_baseline = state_regimen.iterations
        self._predictor_baseline = predictor_regimen.iterations

    def start_batch(self):
        """Starts batch by restarting the regimens and incrementing the number
        of steps.
        """
        self.state_regimen.restart()
        self.predictor_regimen.restart()
        self.n_steps += 1
        self._sut = []

    def finish_batch(self):
        """Finishes batch.
        """

    def end(self, epochs):
        """The regimen ends when the weight regimen had immediately converged.

        This means that even the very first gradient was below the threshold.
        """
        if (self.n_steps == 0) and (epochs > 0):
            return False
        return all(self._sut) or (self.n_steps >= epochs)

    def training_step(self, loss_fun, state_variables, predictor_variables,
                      metrics=None):
        """Takes one training steps by first learning the states and then
        learning the weights.
        """
        metrics = metrics or []
        self.state_regimen.train(
            loss_fun, variables=state_variables,
            metrics=metrics,
            it_baseline=self._predictor_baseline
        )
        self.predictor_regimen.train(
            loss_fun, variables=predictor_variables,
            metrics=metrics,
            it_baseline=self._state_baseline
        )
        self._sut.append(self.predictor_regimen.steps_until_convergence() == 0)

    def train(self, loss_fun, state_variables, predictor_variables, # (mostly internal method) pylint:disable=too-many-arguments
              metrics=None, epochs=1):
        """Trains a model until convergence or the maximum number of steps
        have been exceeded.
        """
        metrics = metrics or []
        while not self.end(epochs):
            self.start_batch()
            self.training_step(loss_fun, state_variables, predictor_variables,
                               metrics=metrics)
            self.finish_batch()

    def restart(self):
        """Restarts a regimen.
        """
        self.n_steps = 0
        self._sut = [False]

def _get_sor(identifier):
    if isinstance(identifier, OptimizerRegimen):
        return copy.deepcopy(identifier)
    try:
        identifier = keras.optimizers.get(identifier)
    except ValueError as e:
        raise ValueError('Could not interpret regimen identifier.') from e
    return OptimizerRegimen(optimizer=copy.deepcopy(identifier))

def get(identifier):
    """Retrieves a EMRegimen instance.

    Args:
        identifier: Regimen identifier, one of:
            - String: Name of a keras optimizer
            - Dictionary: Regimen specified independently for states and
                predictors
            - EMRegimen: Returned unchanged
            - Keras optimizer instance: The optimizer used for state and
                predictor optimization
            - Regimen instance: The regimen used for state and predictor
                optimization

    Returns:
        An EMRegimen instance.

    Raises:
        ValueError: if 'identifier' cannot be interpreted.
    """
    if isinstance(identifier, OptimizerRegimen):
        return EMRegimen(
            state_regimen=copy.deepcopy(identifier),
            predictor_regimen=copy.deepcopy(identifier)
        )
    if isinstance(identifier, EMRegimen):
        return identifier
    if isinstance(identifier, dict):
        if not set(identifier.keys()).issubset({'states', 'predictors'}):
            raise ValueError('You can only specify "states" and "predictors" '
                             'in a dictionary.')
        for key in ['states', 'predictors']:
            if key not in identifier:
                identifier[key] = ConstantRegimen()
        return EMRegimen(
            state_regimen=_get_sor(identifier['states']),
            predictor_regimen=_get_sor(identifier['predictors'])
        )
    return EMRegimen(
        state_regimen=_get_sor(identifier),
        predictor_regimen=_get_sor(identifier)
    )


#2. Bir işletmenin müşterilerle çalışma süresi aşağıdaki formül ile bulunmaktadır.

#Müşterilerle çalışma süresi=Çalışılan süre / Toplam Müşteri Sayısı

#2016 yılında çalışılan süre 170 saat ve toplam müşteri sayısı 50 dir. 2017 yılında çalışılan süre 50 saat artmış ve müşteri sayısı 20 kişi artmıştır.

#Buna göre 2016 ve 2017 yılı müşterilerle çalışma  sürelerini fonksiyon kullanarak hesaplayınız ve 2017 ve 2016 yılları müşterilerle çalışma süreleri arasındaki
#farkı bulan python kodunu yazınız.

def hesap(calisilansure,toplammusterisayisi):
    musterilerlecalisma=calisilansure/toplammusterisayisi
    return musterilerlecalisma

def yıl2016():
    global yıl2016hesap
    yıl2016hesap=hesap(170,50)
    print("2016 yılı çalışma süresi:",yıl2016hesap)
    return yıl2016hesap

yıl2016()

def yıl2017():
    global yıl2017hesap
    yıl2017hesap=hesap(220,70)
    print("2017 yılı çalışma süresi:",yıl2017hesap)
    return yıl2017hesap

yıl2017()

def fark():
    yılfarkı=(yıl2017hesap)-(yıl2016hesap)
    print("2017 ve 2016 yılları arasındaki müşterilerle çalışma süreleri farkı:",yılfarkı)
    return yılfarkı

fark()


"""
device controll class for the LakeShore Temperature Monitor Model 218
so far only used on device with serial: 21EB3L
"""

import serial
import TangoHelper

class LakeShore218:
    def __init__(self, serial_number='21EB3L'):
        self.serial_number = serial_number
        self.ser = serial.Serial()

    def connect(self):
        if self.ser.is_open:
            print('device already connected')
            return True

        self.ser = serial.Serial(baudrate=9600,
                                 timeout=1,
                                 bytesize=7,
                                 parity='O',
                                 stopbits=1)

        return TangoHelper.connect_by_serial_number(self.ser, self.serial_number)

    def disconnect(self):
        self.ser.close()
        print('connection closed')

    def read_temp(self, sensor):
        """read temperature of specified sensor (can be 1-8)"""
        self.ser.write(('KRDG? %s\n' % sensor).encode())
        return float(self.ser.readline().decode().strip())

    def log_start(self, continue_last_log=False, interval=20, overwrite_at_full_memory=True, number_of_readings=2):
        """start internal temperature logging

        interval in s
        StorageCapability per Readings: (1500/1, 1000/2, 750/3, 600/4 ...) more details in the Manual
        """

        self.ser.write(('LOGSET 1 %d %d %d %d\n' %
                        (overwrite_at_full_memory, continue_last_log, interval, number_of_readings)).encode())
        self.ser.readline()  # wait for LOGSET command to finish

        self.ser.write('LOG 1\n'.encode())
        self.ser.readline()  # wait for LOG command to finish

    def log_stop(self):
        self.ser.write('LOG 0\n'.encode())
        self.ser.readline()  # wait for LOG command to finish

    def log_read(self, sensors=None):
        """read contents of the temperature log"""
        if sensors is None:  # avoiding list as default value (mutable)
            sensors = [1, 2]

        self.ser.write('LOGNUM ?\n'.encode())
        last_record_number = int(self.ser.readline().decode().strip())

        data = {'date,time': []}
        for sensor_id in sensors:
            data['sensor%d' % sensor_id] = []

        for record_number in range(1, last_record_number + 1):

            date_time = ''

            for sensor_id in sensors:
                self.ser.write(('LOGVIEW? %d %d\n' % (record_number, int(sensor_id))).encode())
                record = self.ser.readline().decode().split(',')

                if int(record[3]) != 0:
                    print('WARNING: error code %s returned on sensor %s' % (record[3], sensor_id))
                if int(record[4]) != 1:
                    print('WARNING: temperature unit of sensor %s is not Kelvin!' % sensor_id)

                date_time = record[0] + ',' + record[1]
                data['sensor%d' % sensor_id].append(float(record[2].strip('+')))
            else:
                data['date,time'].append(date_time)

            print('.', end='')

        return data

    def log_status(self):
        self.ser.write('LOG?\n'.encode())
        return bool(int(self.ser.readline().decode().strip()))