import numpy as np
from tensorflow.keras.models import load_model
import cv2
import dlib

class Pred:
    def __init__(self):
        self.detector = dlib.get_frontal_face_detector()
        self.predictor = dlib.shape_predictor("F:/Models/shape_predictor_68_face_landmarks.dat")
        self.model = load_model("F:/Projects/Beast/Models/L/L.h5")
        self.kernel = np.array([[-1,-1,-1],[-1,9,-1],[-1,-1,-1]])
        print("Models Initialized")

    def sharpen(self,frame):
        sharp_frame = cv2.filter2D(frame, -1, self.kernel)
        return sharp_frame

    def get_eyes(self,frame):
        #Currently for a single face only
        faces = self.detector(frame)
        L_eye = -1
        R_eye = -1
        L_mask = np.zeros((50,50))
        R_mask = np.zeros((50,50))
        if(len(faces)==0):
            return -1,-1,-1,-1,-1,-1
        for face in faces:
            shape = self.predictor(frame,face)
            L_max_x = shape.part(45).x + 10 if shape.part(45).x + 10>0 else 0
            L_min_x = shape.part(42).x - 10
            L_min_y = min([shape.part(43).y,shape.part(44).y]) - 10
            L_min_y = L_min_y if L_min_y > 0 else 0
            L_max_y = max([shape.part(47).y,shape.part(46).y]) + 10
            L_eye = np.reshape(cv2.resize(frame[L_min_y:L_max_y,L_min_x:L_max_x],(50,50)),(50,50,1))
            L_roi_corners = np.array([[(shape.part(i).x-L_min_x,shape.part(i).y-L_min_y) for i in range(42,48)]])
            L_mask = cv2.fillPoly(np.zeros((L_max_y-L_min_y,L_max_x-L_min_x)),L_roi_corners,(255))
            R_max_x = shape.part(39).x + 10
            R_min_x = shape.part(36).x - 10 if shape.part(36).x -   10>0 else 0
            R_min_y = min([shape.part(37).y,shape.part(38).y]) - 10
            R_min_y = R_min_y if R_min_y > 0 else 0
            R_max_y = max([shape.part(41).y,shape.part(40).y]) + 10
            R_roi_corners = np.array([[(shape.part(i).x-R_min_x,shape.part(i).y-R_min_y) for i in range(36,42)]])
            R_mask = cv2.fillPoly(np.zeros((R_max_y-R_min_y,R_max_x-R_min_x)),R_roi_corners,(255))
            R_eye = np.reshape(cv2.resize(frame[R_min_y:R_max_y,R_min_x:R_max_x],(50,50)),(50,50,1))
            for i in range(10):
                L_eye = self.sharpen(L_eye)
                R_eye = self.sharpen(R_eye)
        return L_eye,R_eye,[L_min_y,L_max_y,L_min_x,L_max_x],[R_min_y,R_max_y,R_min_x,R_max_x],L_mask.astype(np.uint8),R_mask.astype(np.uint8)

    def get_pred(self,frame):
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        L_eye,R_eye,L_coords,R_coords,L_mask,R_mask = self.get_eyes(gray)
        if(type(L_eye)==int):
            return frame
        L_eye = np.reshape(L_eye,(50,50,1))/255
        R_eye = np.reshape(cv2.flip(R_eye,1),(50,50,1))/255
        L_eye,R_eye = self.model.predict(np.array([L_eye,R_eye]))
        L_eye = cv2.resize(L_eye,(L_coords[3]-L_coords[2],L_coords[1]-L_coords[0]))*255
        L_eye = L_eye.astype(np.uint8)
        R_eye = cv2.resize(cv2.flip(R_eye,1),(R_coords[3]-R_coords[2],R_coords[1]-R_coords[0]))*255
        R_eye = R_eye.astype(np.uint8)
        L_eye_masked = cv2.cvtColor(cv2.bitwise_and(L_eye, L_mask),cv2.COLOR_GRAY2BGR)
        R_eye_masked = cv2.cvtColor(cv2.bitwise_and(R_eye, R_mask),cv2.COLOR_GRAY2BGR)
        L_orig_masked = cv2.bitwise_and(frame[L_coords[0]:L_coords[1],L_coords[2]:L_coords[3]].astype(np.uint8),cv2.cvtColor(255-L_mask,cv2.COLOR_GRAY2BGR))
        R_orig_masked = cv2.bitwise_and(frame[R_coords[0]:R_coords[1],R_coords[2]:R_coords[3]].astype(np.uint8),cv2.cvtColor(255-R_mask,cv2.COLOR_GRAY2BGR))
        frame[L_coords[0]:L_coords[1],L_coords[2]:L_coords[3]] = L_orig_masked + L_eye_masked
        frame[R_coords[0]:R_coords[1],R_coords[2]:R_coords[3]] = R_orig_masked + R_eye_masked
        return frame

pred = Pred()
vid = cv2.VideoCapture("rec2.mp4")
out = cv2.VideoWriter('F:/Projects/Beast/outpy_4.avi',cv2.VideoWriter_fourcc('M','J','P','G'), 30, (640,480))
print("Starting Recording")
while 1:
    ret,img = vid.read()
    if(not(ret)):
        break
    img = cv2.resize(img,(640,480))
    new_frame = pred.get_pred(img)
    cv2.imshow("Original",img)
    cv2.imshow("New",new_frame)
    out.write(new_frame)
    if cv2.waitKey(1) ==27:
        break
cv2.destroyAllWindows()
vid.release()
out.release()


"""PyQt5 specifieke routines voor mijn op een treeview gebaseerde HTML-editor
"""
import os
import sys
import PyQt5.QtWidgets as qtw
import PyQt5.QtGui as gui
import PyQt5.QtCore as core
## import PyQt5.QtWebKit as webkit
# import PyQt5.QtWebKitWidgets as webkit
import PyQt5.QtWebEngineWidgets as webeng

from ashe.shared import masks
from ashe.dialogs_qt import (ElementDialog, TextDialog, DtdDialog, CssDialog, LinkDialog,
                             ImageDialog, VideoDialog, AudioDialog, ListDialog, TableDialog,
                             ScrolledTextDialog, CodeViewDialog, SearchDialog)

class VisualTree(qtw.QTreeWidget):
    """tree representation of HTML
    """
    def __init__(self, parent):
        self._parent = parent
        super().__init__()
        self.setAcceptDrops(True)
        self.setDragEnabled(True)
        self.setSelectionMode(self.SingleSelection)
        self.setDragDropMode(self.InternalMove)
        self.setDropIndicatorShown(True)

    def mouseDoubleClickEvent(self, event):
        "reimplemented event handler"
        item = self.itemAt(event.x(), event.y())
        if item and item != self._parent.top:
            if str(item.text(0)).startswith(self._parent.editor.constants['ELSTART']) and \
                    item.childCount() == 0:
                self._parent.editor.edit()
                return
        super().mouseDoubleClickEvent(event)

    def mouseReleaseEvent(self, event):
        "reimplemented event handler"
        if event.button() == core.Qt.RightButton:
            xc, yc = event.x(), event.y()
            item = self.itemAt(xc, yc)
            if item and item != self._parent.top:
                self.setCurrentItem(item)
                self._parent.popup_menu(item)
                return
        super().mouseReleaseEvent(event)

    def dropEvent(self, event):
        """wordt aangeroepen als een versleept item (dragitem) losgelaten wordt over
        een ander (dropitem)
        Het komt er altijd *onder* te hangen als laatste item
        deze methode breidt de Treewidget methode uit met wat visuele zaken
        """
        item = self.itemAt(event.pos())
        if not item or not item.text(0).startswith(self._parent.editor.constants['ELSTART']):
            self._parent.meld('Can only drop on element')
            return
        dragitem = self.selectedItems()[0]
        super().dropEvent(event)
        dropitem = dragitem.parent()
        self.setCurrentItem(dragitem)
        dropitem.setExpanded(True)
        self._parent.editor.mark_dirty(True)
        self._parent.editor.refresh_preview()

class EditorGui(qtw.QMainWindow):
    "Main GUI"

    def __init__(self, parent=None, editor=None, err=None, icon=None):
        self.parent = parent
        self.editor = editor
        self.app = qtw.QApplication(sys.argv)
        super().__init__()
        if err:
            self.meld(err)
            return

        self.dialog_data = {}
        # self.search_args = []
        self.setWindowTitle(self.editor.title)
        self.appicon = gui.QIcon(icon)
        self.setWindowIcon(self.appicon)
        self.resize(1200, 900)

        self.setup_menu()
        self.in_contextmenu = False

        self.pnl = qtw.QSplitter(self)
        self.setCentralWidget(self.pnl)

        self.tree = VisualTree(self)
        self.tree.headerItem().setHidden(True)
        self.pnl.addWidget(self.tree)

        # self.html = webkit.QWebView(self.pnl)  # , -1,
        self.html = webeng.QWebEngineView(self.pnl)
        self.pnl.addWidget(self.html)

        self.sb = self.statusBar()

        self.tree.resize(500, 100)
        self.pnl.setSizes([300, 900])
        self.tree.setFocus()
        self.adv_menu.setChecked(True)
        self.show()

    def go(self):
        """show the screen
        """
        sys.exit(self.app.exec_())

    def setup_menu(self):
        """build application menu
        """
        menu_bar = self.menuBar()
        self.contextmenu_items = []
        for menu_text, data in self.editor.get_menulist():
            menu = qtw.QMenu(menu_text, self)
            for item in data:
                if len(item) == 1:
                    menu.addSeparator()
                    continue
                menuitem_text, hotkey, modifiers, status_text, callback = item[:5]
                if 'A' in modifiers:
                    hotkey = "+".join(("Alt", hotkey))
                if 'C' in modifiers:
                    hotkey = "+".join(("Ctrl", hotkey))
                if 'S' in modifiers:
                    hotkey = "+".join(("Shift", hotkey))
                act = qtw.QAction(menuitem_text, self)
                menu.addAction(act)
                act.setStatusTip(status_text)
                act.setShortcut(hotkey)
                act.triggered.connect(callback)
                if menuitem_text.startswith('Advance selection'):
                    act.setCheckable(True)
                    self.adv_menu = act
                elif menu_text == '&View':
                    self.contextmenu_items.append(('A', act))
                elif menuitem_text == 'Add &DTD':
                    self.dtd_menu = act
                elif menuitem_text == 'Add &Stylesheet':
                    self.css_menu = act
                if menu_text in ('&Edit', '&Search', '&HTML'):
                    self.contextmenu_items.append(('M', menu))
            if menu_text == '&View':
                self.contextmenu_items.append(('', ''))
            menu_bar.addMenu(menu)

    # def setfilenametooltip((self):
        # """bedoeld om de filename ook als tooltip te tonen, uit te voeren
        # aan het eind van new, open, save, saveas en reload"""
        # zie ticket 406 voor een overweging om dit helemaal achterwege te laten

    def get_screen_title(self):
        "retrieve the screen's title"
        return self.windowTitle()

    def set_screen_title(self, title):
        "change the screen's title"
        self.setWindowTitle(title)

    @staticmethod
    def get_element_text(node):
        "return text in visual tree for this element"
        return node.text(0)

    @staticmethod
    def get_element_parent(node):
        "return parent in visual tree for this element"
        return node.parent()

    @staticmethod
    def get_element_parentpos(item):
        "return parent and position under parent in visual tree for this element"
        parent = item.parent()
        return parent, parent.indexOfChild(item)

    @staticmethod
    def get_element_data(node):
        "return attributes stored with this element"
        return node.data(0, core.Qt.UserRole)

    @staticmethod
    def get_element_children(node):
        "return iterator over children in visual tree for this element"
        count = node.childCount()
        # return (node.child(idx) for idx in range(count))
        return [node.child(idx) for idx in range(count)]

    @staticmethod
    def set_element_text(node, text):
        "change text in visual tree for this element"
        node.setText(0, text)

    @staticmethod
    def set_element_data(node, data):
        "change stored attrs for this element"""
        node.setData(0, core.Qt.UserRole, data)

    @staticmethod
    def addtreeitem(node, naam, data, index=-1):
        """itemnaam en -data toevoegen aan de interne tree
        default is achteraan onder node, anders index meegeven
        geeft referentie naar treeitem terug
        """
        newnode = qtw.QTreeWidgetItem()
        newnode.setText(0, naam)  # self.tree.AppendItem(node, naam)
        # data is ofwel leeg, ofwel een string, ofwel een dictionary
        newnode.setData(0, core.Qt.UserRole, data)  # self.tree.SetPyData(newnode, data)
        if index == -1:
            node.addChild(newnode)
        else:
            node.insertChild(index, newnode)
        return newnode

    def addtreetop(self, fname, titel):
        """titel en root item in tree instellen"""
        self.setWindowTitle(titel)
        self.tree.clear()
        self.top = qtw.QTreeWidgetItem()
        self.top.setText(0, fname)
        self.tree.addTopLevelItem(self.top)  # AddRoot(titel)

    def get_selected_item(self):
        """geef het in de tree geselecteerde item terug
        """
        return self.tree.currentItem()

    def set_selected_item(self, item):
        """stel het in de tree geselecteerde item in
        """
        self.tree.setCurrentItem(item)

    def init_tree(self, message):
        "toolkit specifieke zaken van tree instellen"
        self.tree.setCurrentItem(self.top)
        self.adv_menu.setChecked(True)
        self.show_statusbar_message(message)

    def show_statusbar_message(self, text):
        """toon tekst in de statusbar
        """
        self.sb.showMessage(text)

    def adjust_dtd_menu(self):
        "set text for dtd menu option"
        if self.editor.has_dtd:
            self.dtd_menu.setText('Remove &DTD')
            self.dtd_menu.setStatusTip('Remove the document type declaration')
        else:
            self.dtd_menu.setText('Add &DTD')
            self.dtd_menu.setStatusTip('Add a document type description')

    def popup_menu(self, arg=None):
        'build/show context menu'
        # get type of node
        menu = qtw.QMenu()
        for itemtype, item in self.contextmenu_items:
            if itemtype == 'A':
                menu.addAction(item)
            elif itemtype == 'M':
                menu.addMenu(item)
            else:
                menu.addSeparator()
        y = self.tree.visualItemRect(arg).bottom()
        x = self.tree.visualItemRect(arg).left()
        popup_location = core.QPoint(int(x) + 200, y)
        self.in_contextmenu = True
        menu.exec_(self.tree.mapToGlobal(popup_location))
        self.in_contextmenu = False
        # del menu

    def keyReleaseEvent(self, event):
        "reimplemented event handler"
        skip = self.on_keyup(event)
        if not skip:
            super().keyReleaseEvent(event)

    def on_keyup(self, ev=None):
        "determine if key event needs to be skipped"
        ky = ev.key()
        item = self.tree.currentItem()
        skip = False
        if item and item != self.top:
            if ky == core.Qt.Key_Menu:
                self.popup_menu(item)
                skip = True
        return skip

    def ask_how_to_continue(self, title, text):
        """vraag of de wijzigingen moet worden opgeslagen
        keuze uitvoeren en teruggeven (i.v.m. eventueel gekozen Cancel)
        retourneert 1 = Yes, 0 = No, -1 = Cancel
        """
        retval = dict(zip((qtw.QMessageBox.Yes, qtw.QMessageBox.No, qtw.QMessageBox.Cancel),
                          (1, 0, -1)))
        hlp = qtw.QMessageBox.question(self, title, text, qtw.QMessageBox.Yes |
                                       qtw.QMessageBox.No | qtw.QMessageBox.Cancel,
                                       defaultButton=qtw.QMessageBox.Yes)
        return retval[hlp]

    @staticmethod
    def build_mask(ftype):
        """build mask for FileDialog
        """
        text, filetypes = masks['all']
        all_mask = "{} ({})".format(text, filetypes[0])
        text, filetypes = masks[ftype]
        filetypes_text = " ".join(filetypes)
        if os.name == 'posix':
            filetypes_text = ' '.join((filetypes_text, filetypes_text.upper()))
        return "{0} ({1})".format(text, filetypes_text) + ';;' + all_mask

    def ask_for_open_filename(self):
        """open een dialoog om te vragen welk file geladen moet worden
        """
        filename = qtw.QFileDialog.getOpenFileName(self, "Choose a file",
                                                   self.editor.xmlfn or os.getcwd(),
                                                   self.build_mask('html'))[0]
        return filename

    def ask_for_save_filename(self):
        """open een dialoog om te vragen onder welke naam de html moet worden opgeslagen
        """
        filename = qtw.QFileDialog.getSaveFileName(self, "Save file as ...",
                                                   self.editor.xmlfn or os.getcwd(),
                                                   self.build_mask('html'))[0]
        return filename

    @staticmethod
    def set_item_expanded(item, state):
        """show item's children
        """
        item.setExpanded(state)

    def expand(self):
        "toolkit specifieke voortzetting van gelijknamige editor methode"
        def expand_all(item):
            "recursively expand items"
            all_results = []
            for ix in range(item.childCount()):
                sub = item.child(ix)
                sub.setExpanded(True)
                all_results.append(sub)
                result = expand_all(sub)
                if result:
                    all_results.extend(result)
            return all_results
        item = self.tree.currentItem()
        self.tree.expandItem(item)
        results = expand_all(item)
        self.tree.resizeColumnToContents(0)
        self.tree.scrollToItem(results[-1])

    def collapse(self):
        "toolkit specifieke voortzetting van gelijknamige editor methode"
        def collapse_all(item):
            "recursively collapse items"
            for ix in range(item.childCount()):
                sub = item.child(ix)
                collapse_all(sub)
                sub.setExpanded(False)
        item = self.tree.currentItem()
        collapse_all(item)
        self.tree.collapseItem(item)
        self.tree.resizeColumnToContents(0)

    def get_adv_sel_setting(self):
        "callback for menu option"
        return self.adv_menu.isChecked()

    def refresh_preview(self, soup):
        "toolkit specifieke implementatie van gelijknamige editor methode"
        print(os.path.abspath(self.editor.xmlfn))
        self.html.setHtml(str(soup).replace('%SOUP-ENCODING%', 'utf-8'),
                          baseUrl=core.QUrl.fromLocalFile(os.path.abspath(self.editor.xmlfn)))
        self.tree.setFocus()

    def call_dialog(self, obj):
        "send dialog and transmit results"
        edt = obj.exec_()
        if edt == qtw.QDialog.Accepted:
            return True, self.dialog_data
        return False, None

    def do_edit_element(self, tagdata, attrdict):
        """show dialog for existing element"""
        obj = ElementDialog(self, title='Edit an element', tag=tagdata, attrs=attrdict)
        return self.call_dialog(obj)

    def do_add_element(self, where):
        """show dialog for new element"""
        obj = ElementDialog(self, title="New element (insert {0})".format(where))
        return self.call_dialog(obj)

    def do_edit_textvalue(self, textdata):
        """show dialog for existing text"""
        return self.call_dialog(TextDialog(self, title='Edit Text', text=textdata))

    def do_add_textvalue(self):
        """show dialog for new text"""
        return self.call_dialog(TextDialog(self, title="New Text"))

    def ask_for_condition(self):
        "zet een IE conditie om het element heen"
        cond, ok = qtw.QInputDialog.getText(self, self.title, 'Enter the condition', text='')
        if ok:
            return cond
        return ''

    def do_delete_item(self, item):
        """remove element from tree
        """
        parent = item.parent()
        ix = parent.indexOfChild(item)
        if ix > 0:
            ix -= 1
            prev = parent.child(ix)
        else:
            prev = parent
            if prev == self.editor.root:
                prev = parent.child(ix + 1)
        parent.removeChild(item)
        return prev

    def get_search_args(self, replace=False):
        """show search options dialog"""
        title = 'Search options'
        return self.call_dialog(SearchDialog(self, title, replace))

    def meld(self, text):
        """notify about some information"""
        self.in_dialog = True
        qtw.QMessageBox.information(self, self.editor.title, text)

    def meld_fout(self, text, abort=False):
        """notify about an error"""
        self.in_dialog = True
        qtw.QMessageBox.critical(self, self.title, text)
        if abort:
            self.quit()

    def ask_yesnocancel(self, prompt):
        """stelt een vraag en retourneert het antwoord
        1 = Yes, 0 = No, -1 = Cancel
        """
        retval = dict(zip((qtw.QMessageBox.Yes, qtw.QMessageBox.No,
                           qtw.QMessageBox.Cancel), (1, 0, -1)))
        self.in_dialog = True
        h = qtw.QMessageBox.question(
            self, self.title, prompt,
            qtw.QMessageBox.Yes | qtw.QMessageBox.No | qtw.QMessageBox.Cancel,
            defaultButton=qtw.QMessageBox.Yes)
        return retval[h]

    def ask_for_text(self, prompt):
        """vraagt om tekst en retourneert het antwoord"""
        self.in_dialog = True
        data, ok = qtw.QInputDialog.getText(self, self.title, prompt, qtw.QLineEdit.Normal, "")
        return data, ok

    def ensure_item_visible(self, item):
        """make sure we can see the item
        """
        self.tree.scrollToItem(item)

    def get_dtd(self):
        """show dialog for dtd
        """
        return self.call_dialog(DtdDialog(self))

    def get_css_data(self):
        """show dialog for new style element
        """
        return self.call_dialog(CssDialog(self))

    def get_link_data(self):
        """show dialog for new link element
        """
        return self.call_dialog(LinkDialog(self))

    def get_image_data(self):
        """show dialog for new image element
        """
        return self.call_dialog(ImageDialog(self))

    def get_video_data(self):
        """show dialog for new video element
        """
        return self.call_dialog(VideoDialog(self))

    def get_audio_data(self):
        """show dialog for new audio element
        """
        return self.call_dialog(AudioDialog(self))

    def get_list_data(self):
        """show dialog for new list element
        """
        return self.call_dialog(ListDialog(self))

    def get_table_data(self):
        """show dialog for new table element
        """
        return self.call_dialog(TableDialog(self))

    def validate(self, htmlfile, fromdisk):
        "start validation"
        ScrolledTextDialog(self, "Validation output", htmlfile=htmlfile, fromdisk=fromdisk).show()

    def show_code(self, title, caption, data):
        "show dialog for view source"
        CodeViewDialog(self, title, caption, data).show()


# All Import Statements Defined Here
# Note: Do not add to this list.
# ----------------

import sys
assert sys.version_info[0]==3
assert sys.version_info[1] >= 5

from platform import python_version
assert int(python_version().split(".")[1]) >= 5, "Please upgrade your Python version following the instructions in \
    the README.txt file found in the same directory as this notebook. Your Python version is " + python_version()

from gensim.models import KeyedVectors
from gensim.test.utils import datapath
import pprint
import matplotlib.pyplot as plt
plt.rcParams['figure.figsize'] = [10, 5]

import nltk
nltk.download('reuters')
#to specify download location, optionally add the argument: download_dir='/specify/desired/path/'
from nltk.corpus import reuters

import numpy as np
import random
import scipy as sp
from sklearn.decomposition import TruncatedSVD
from sklearn.decomposition import PCA

START_TOKEN = '<START>'
END_TOKEN = '<END>'

np.random.seed(0)
random.seed(0)
# ----------------

# Co-Occurrence vector : how often some word occurs in a document
def read_corpus(category = "gold"):
    files = reuters.fileids(category)
    return [[START_TOKEN] + [w.lower() for w in list(reuters.words(f))] + [END_TOKEN] for f in files]

reuters.corpus = read_corpus()
pprint.pprint(reuters.corpus[:3], compact = True, width = 100)

def distinct_words(corpus):
    """
    Pseudo-code explanation
    For each document:
        for each word in a given document:
            add the word to the set -> set theory -> one of each word (element)

    Sort the list of corpus words
    then, get length
    return corpus word set, and number of corpus words
    """
    corpus_words = []
    n_corpus_words = -1

    corpus_words = set()
    for document in corpus:
        for word in document:
            corpus_words.add(word)

    corpus_words = sorted(list(corpus_words))
    n_corpus_words = len(corpus_words)
    return corpus_words, n_corpus_words

def co_occurrence_matrix(corpus, window_size):
    """
    Pseudo-code explanation
    We initialize a zero-matrix of dimension = n_words:
        initialize a dictionary to store indexes of corpus words

    For each doc in our corpus:
        for each target word and it's corresponding index:
            get the index of the target word
            initialize a starting/ending point pointer(s)

            for being the range of our (start, end):
                if the index i != j:
                we set the context word at position j
                get context index
                at the corresponding pos (target index, context_word)
                    set it equal to 1 // track our co-occurrences with 1/0 binaries
    """
    words, n_words = distinct_words(corpus)
    M = np.zeros((n_words, n_words), dtype = np.float32)
    word_idx = {word: index for index, word in enumerate(words)}

    for doc in corpus:
        for i, target_word in enumerate(doc):
            target_idx = word_idx[target_word]
            start = max(0, i - window_size)
            end = min(len[doc], i + window_size + 1)

            for j in range(start, end):
                if i != j:
                    context_word = doc[j]
                    context_index = word_idx[context_word]
                    M[target_idx][context_word] += 1
    return M, word_idx

def reduce_k_dim(M, k):
    n_iters = 10
    print("Running truncated SVD over %i words..." % (M.shape[0]))
    svd = TruncatedSVD(n_iter = n_iters)
    M_reduced = svd.fit_transform(M)
    print("Done.")
    return M_reduced

def plot_embeddings(M_reduced, word_idx, words):
    word_ind = [word_idx[word] for word in words]
    word_embed = M_reduced[word_idx]

    plt.figure(figsize = (10, 8))
    plt.figure(figsize = (10, 8))
    plt.scatter(word_embed[:, 0], word_embed[:, 1], marker = 'o', color = 'r', s = 50)

    for i, word in enumerate(words):
        plt.annotate(word, (word_embed[i, 0], word_embed[i, 1]), fontsize = 12)

    plt.xlabel("Dimension 1")
    plt.ylabel("Dimension 2")
    plt.title("Word Embeddings")

if __name__ == "__main__":
    test_corpus = ["{} All that glitters isn't gold {}".format(START_TOKEN, END_TOKEN).split(" "),
                   "{} All's well that ends well {}".format(START_TOKEN, END_TOKEN).split(" ")]

    M_test, word2_ind = co_occurrence_matrix(test_corpus, window_size = 1)


import logging
import os
import sys
from datetime import datetime
from getpass import getuser

import sentry_sdk
from jupyterhub.log import CoroutineLogFormatter, log_request
from jupyterhub.utils import url_path_join
from sentry_sdk.integrations.tornado import TornadoIntegration
from sqlalchemy.exc import OperationalError
from tornado import web
from tornado.httpserver import HTTPServer
from tornado.ioloop import IOLoop
from tornado.log import access_log, app_log, gen_log
from tornado_prometheus import MetricsHandler, PrometheusMixIn
from traitlets import Bool, Dict, Integer, Type, Unicode, default
from traitlets.config import Application, catch_config_error

import nbexchange.dbutil
from nbexchange import dbutil, handlers
from nbexchange.handlers import base
from nbexchange.handlers.auth.naas_user_handler import NaasUserHandler
from nbexchange.handlers.auth.user_handler import BaseUserHandler

ROOT = os.path.dirname(__file__)
STATIC_FILES_DIR = os.path.join(ROOT, "static")

flags = {
    "debug": (
        {"Application": {"log_level": logging.DEBUG}},
        "set log level to logging.DEBUG (maximize logging output)",
    ),
    "upgrade-db": (
        {"NbExchange": {"upgrade_db": True}},
        """Automatically upgrade the database if needed on startup.

        Only safe if the database has been backed up.
        Only SQLite database files will be backed up automatically.
        """,
    ),
}

class NbExchange(PrometheusMixIn, Application):
    """The nbexchange application"""

    name = "nbexchange"

    @property
    def version(self):
        import pkg_resources

        return pkg_resources.get_distribution("nbexchange").version

    description = """
        Manage notebook submissions and collections for nbgrader
    """

    flags = Dict(flags)

    config_file = Unicode("nbexchange_config.py", help="The config file to load").tag(config=True)

    base_url = os.environ.get("JUPYTERHUB_SERVICE_PREFIX", "/services/nbexchange/")
    base_storage_location = os.environ.get("NBEX_BASE_STORE", "/tmp/courses")
    # naas_url = os.environ.get("NAAS_URL", "https://127.0.0.1:8080")
    user_plugin_class = Type(
        NaasUserHandler,
        klass=BaseUserHandler,
        help="The class to use for handling users",
    ).tag(config=True)

    debug = bool(int(os.environ.get("DEBUG", 0)))

    ip = Unicode("0.0.0.0").tag(config=True)

    port = Integer(9000).tag(config=True)

    sentry_dsn = os.environ.get("SENTRY_DSN", "")

    tornado_settings = Dict()

    _log_formatter_cls = CoroutineLogFormatter

    @default("log_level")
    def _log_level_default(self):
        if self.debug:
            return logging.DEBUG
        return logging.INFO

    @default("log_datefmt")
    def _log_datefmt_default(self):
        """Exclude date from default date format"""
        return "%Y-%m-%d %H:%M:%S"

    @default("log_format")
    def _log_format_default(self):
        """override default log format to include time"""
        return "%(color)s[%(levelname)1.1s %(asctime)s.%(msecs).03d %(name)s %(module)s:%(lineno)d]%(end_color)s %(message)s"  # noqa: E501

    @staticmethod
    def add_url_prefix(prefix, handlers):
        """add a url prefix to handlers"""
        for i, tup in enumerate(handlers):
            lis = list(tup)
            lis[0] = url_path_join(prefix, tup[0])
            handlers[i] = tuple(lis)

        return handlers

    def init_logging(self):
        """Initialize logging"""
        # This prevents double log messages because tornado use a root logger that
        # self.log is a child of. The logging module dipatches log messages to a log
        # and all of its ancenstors until propagate is set to False.
        self.log.propagate = False

        # Is this actually used anywhere? flake says it isn't
        # _formatter = self._log_formatter_cls(fmt=self.log_format, datefmt=self.log_datefmt)

        # hook up tornado 3's loggers to our app handlers
        for log in (app_log, access_log, gen_log):
            # ensure all log statements identify the application they come from
            log.name = self.log.name
        logger = logging.getLogger("tornado")
        logger.propagate = True
        logger.parent = self.log
        logger.setLevel(self.log.level)

        access_log.propagate = False
        # make sure access log is enabled even if error level is WARNING|ERROR
        access_log.setLevel(logging.INFO)
        stdout_handler = logging.StreamHandler(sys.stdout)
        access_log.addHandler(stdout_handler)

    db_url = os.environ.get("NBEX_DB_URL", "sqlite:///:memory:")  # nbexchange2.sqlite")

    db_kwargs = Dict(
        help="""Include any kwargs to pass to the database connection.
        See sqlalchemy.create_engine for details.
        """
    ).tag(config=True)

    upgrade_db = Bool(
        False,
        help="""Upgrade the database automatically on start.

        Only safe if database is regularly backed up.
        Only SQLite databases will be backed up to a local file automatically.
    """,
    ).tag(config=True)
    reset_db = Bool(False, help="Purge and reset the database.").tag(config=True)
    debug_db = Bool(False, help="log all database transactions. This has A LOT of output").tag(config=True)

    max_buffer_size = Integer(5253530000, help="The maximum size, in bytes, of an upload (defaults to 5GB)").tag(
        config=True
    )

    def _check_db_path(self, path):
        """More informative log messages for failed filesystem access"""
        path = os.path.abspath(path)
        parent, fname = os.path.split(path)
        user = getuser()
        if not os.path.isdir(parent):
            self.log.error(f"Directory {parent} does not exist")
        if os.path.exists(parent) and not os.access(parent, os.W_OK):
            self.log.error(f"{user} cannot create files in {parent}")
        if os.path.exists(path) and not os.access(path, os.W_OK):
            self.log.error(f"{user} cannot edit {path}")

    def init_db(self):
        """Initialize the nbexchange database"""
        self.log.debug(f"db_url = {self.db_url}")
        if self.upgrade_db:
            dbutil.upgrade_if_needed(self.db_url, log=self.log)

        try:
            nbexchange.dbutil.setup_db(
                self.db_url,
                reset=self.reset_db,
                echo=self.debug_db,
                log=self.log,
                **self.db_kwargs,
            )
        except OperationalError as e:
            self.log.error(f"Failed to connect to db: {self.db_url}")
            self.log.debug(f"Database error was: {e}", exc_info=True)
            if self.db_url.startswith("sqlite:///"):
                self._check_db_path(self.db_url.split(":///", 1)[1])
            self.log.critical(
                "\n".join(
                    [
                        "If you recently upgraded NbExchange, try running",
                        "    nbexchange upgrade-db",
                        "to upgrade your nbexchange database schema",
                    ]
                )
            )
            self.exit(1)
        except nbexchange.dbutil.DatabaseSchemaMismatch as e:
            self.exit(e)

    def init_tornado_settings(self):
        """Initialize tornado config"""

        # if running from git directory, disable caching of require.js
        # otherwise cache based on server start time
        parent = os.path.dirname(ROOT)
        if os.path.isdir(os.path.join(parent, ".git")):
            version_hash = ""
        else:
            version_hash = (datetime.now().strftime("%Y%m%d%H%M%S"),)

        settings = dict(
            log_function=log_request,
            config=self.config,
            log=self.log,
            base_url=self.base_url,
            base_storage_location=self.base_storage_location,
            # naas_url=self.naas_url,
            max_buffer_size=self.max_buffer_size,
            user_plugin=self.user_plugin_class(),
            version_hash=version_hash,
            xsrf_cookies=False,
            debug=self.debug,
        )
        # allow configured settings to have priority
        settings.update(self.tornado_settings)
        self.log.info(settings)
        self.tornado_settings = settings

    def init_handlers(self):
        """Load nbexchange's tornado request handlers"""
        self.handlers = []

        for handler in handlers.default_handlers:
            for url in handler.urls:
                self.handlers.append((url_path_join(self.base_url, url), handler))

        self.handlers.append((r"/metrics", MetricsHandler))

        self.handlers.append((r".*", base.Template404))
        self.log.debug("##### ALL HANDLERS" + str(self.handlers))

    def init_tornado_application(self):
        self.tornado_application = web.Application(self.handlers, **self.tornado_settings)
        if self.sentry_dsn:
            sentry_sdk.init(
                dsn=self.sentry_dsn,
                integrations=[TornadoIntegration()],
                release="nbexchange@" + os.environ.get("COMMIT_SHA", "untagged"),
            )

    @catch_config_error
    def initialize(self, *args, **kwargs):
        """Load configuration settings."""
        super().initialize(*args, **kwargs)
        self.load_config_file(self.config_file)
        if self.subapp:
            return
        self.init_db()
        # self.init_hub_auth()
        self.init_tornado_settings()
        self.init_handlers()
        self.init_tornado_application()

    def stop(self):
        self.http_server.stop()

    def start(self, run_loop=True):
        if self.subapp:
            self.subapp.start()
            return

        # *NOT* adding 'max_buffer_size=self.max_buffer_size' here, as we handle the
        # size-checks in code (both plugin & exchange side)
        self.http_server = HTTPServer(self.tornado_application, xheaders=True)
        self.http_server.listen(self.port, address=self.ip)
        if run_loop:
            IOLoop.current().start()

if __name__ == "__main__":
    NbExchange.launch_instance()


import numpy as np
import cv2
import pytesseract
import skimage
pytesseract.pytesseract.tesseract_cmd = 'C:/Program Files (x86)/Tesseract-OCR/tesseract.exe'

class LPR:
    def __init__(self, min_w=80, max_w=110, min_h=25, max_h=52, ratio=3.07692307692):
        self.min_w = min_w
        self.max_w = max_w
        self.min_h = min_h
        self.max_h = max_h
        self.ratio = ratio

    def grayscale(self, img):
        return cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    def apply_threshold(self, img):
        return cv2.threshold(img, 170, 255, cv2.THRESH_BINARY_INV)[1]

    def apply_adaptive_threshold(self, img):
        return cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY_INV, 7, 13)

    def find_contours(self, img):
        return cv2.findContours(img, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)[0]

    def filter_candidates(self, contours):
        candidates = []
        for cnt in contours:
            x, y, w, h = cv2.boundingRect(cnt)
            aspect_ratio = float(w) / h
            if (np.isclose(aspect_ratio, self.ratio, atol=0.7) and
               (self.max_w > w > self.min_w) and
               (self.max_h > h > self.min_h)):
                candidates.append(cnt)
        return candidates

    def get_lowest_candidate(self, candidates):
        ys = []
        for cnt in candidates:
            x, y, w, h = cv2.boundingRect(cnt)
            ys.append(y)
        return candidates[np.argmax(ys)]

    def crop_license_plate(self, img, license):
        x, y, w, h = cv2.boundingRect(license)
        return img[y:y+h,x:x+w]

    def clear_border(self, img):
        return skimage.segmentation.clear_border(img)

    def invert_image(self, img):
        return cv2.bitwise_not(img)

    def read_license(self, img, psm=7):
        alphanumeric = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
        options = "-c tessedit_char_whitelist={}".format(alphanumeric)
        options += " --psm {}".format(psm)

        gray = self.grayscale(img)
        thresh = self.apply_threshold(gray)
        contours = self.find_contours(thresh)
        candidates = self.filter_candidates(contours)
        if candidates:
            license = candidates[0]
            if len(candidates) > 1:
                license = self.get_lowest_candidate(candidates)
            cropped = self.crop_license_plate(gray, license)
            thresh_cropped = self.apply_adaptive_threshold(cropped)
            clear_border = self.clear_border(thresh_cropped)
            final = self.invert_image(clear_border)
            txt = pytesseract.image_to_string(final, config=options)
            return txt
        else:
            return "No license plate found"


from ast import operator
from cProfile import label
from cgitb import text
from email.utils import localtime
from tkinter import*
import random
import time
from tkinter import font
from turtle import right

from numpy import pad
pencere=Tk()
pencere.geometry("900x500+0+0")
pencere.title("KAFE OTOMATI")

text_Input=StringVar()
operator=""

Tops=Frame(pencere,width=1600,height=50,bg="powder blue",relief=SUNKEN)
Tops.pack(side=TOP)

f1=Frame(pencere,width=800,height=700,bg="powder blue",relief=SUNKEN)
f1.pack(side=LEFT)

f2=Frame(pencere,width=300,height=300,bg="powder blue",relief=SUNKEN)
f2.pack(side=RIGHT)
#********************** TİME *************************
localtime=time.asctime(time.localtime(time.time()))
#********************* info *************************
lblınfo=Label(Tops,font=("arial",50,"bold"),text="RESTOURANT OTOMASYONU",fg="steel blue",bd=10,anchor='w')
lblınfo.grid(row=0,column=0)

lblınfo=Label(Tops,font=("arial",20,"bold"),text=localtime,fg="steel blue",bd=10,anchor='w')
lblınfo.grid(row=1,column=0)

# *************************** CALCULATOR ******************************
def btnClick(numbers):
    global operator
    operator=operator+str(numbers)
    text_Input.set(operator)

def btncleardisplay():
    global operator
    operator=""
    text_Input.set("")

def btnesittir():
    global operator
    sumup=str(eval(operator))
    text_Input.set(sumup)
    operator=""

def Ref():
    x=random.randint(10908,50076)
    randomRef=str(x)
    rand.set(randomRef)
    Cof=float(Fries.get())
    Cod=float(Drinks.get())
    Cofilet=float(Filet.get())
    Coburger=float(Burger.get())
    coCohicburger=float(Chicken_burger.get())
    coCheese=float(Cheese_burger.get())

    CostofFries= Cof*0.99
    CostofDrinks= Cod*1.00
    CostofFilet= Cofilet*2.99
    CostofBURGER= Coburger*2.89
    Costochicken= coCohicburger*3.00
    Costofcheese= coCheese*2.99

    CostoMeal="₺",str('%.2f' % (CostofFries+CostofDrinks+CostofFilet+CostofBURGER+Costochicken+Costofcheese))

    PayTax=((CostofFries+CostofDrinks+CostofFilet+CostofBURGER+Costochicken+Costofcheese)*0.2)
    TotalCost=(CostofFries+CostofDrinks+CostofFilet+CostofBURGER+Costochicken+Costofcheese)
    Ser_Charge=((CostofFries+CostofDrinks+CostofFilet+CostofBURGER+Costochicken+Costofcheese)/99)

    Servicet="₺",str('%.2f' % Ser_Charge)
    OverAllCost="₺",str('%.2f' % (PayTax+TotalCost+Ser_Charge))
    PaidTax="₺",str('%.2f' % PayTax)

    Service.get(Servicet)
    Cost.get(CostoMeal)
    Tax.set(PaidTax)
    Subtotal.set(CostoMeal)
    Total.set(OverAllCost)

def Exit():
    pencere.destroy()

def Reset():
 rand.set("")
 Fries.set("")
 Burger.set("")
 Filet.set("")
 Subtotal.set("")
 Total.set("")
 Service.set("")
 Drinks.set("")
 Tax.set("")
 Cost.set("")
 Chicken_burger.set("")
 Cheese_burger.set("")

txtDisplay=Entry(f2,font=("arial",20,"bold"),textvariable=text_Input,bd=30,insertwidth=4,bg="powder blue",justify="right")
txtDisplay.grid(columnspan=4)

btn7=Button(f2,padx=2,pady=16,bd=8,fg="black",font=("arial",20,"bold"),text="7",bg="powder blue",command=lambda:btnClick(7))
btn7.grid(row=2,column=0)

btn8=Button(f2,padx=2,pady=16,bd=8,fg="black",font=("arial",20,"bold"),text="8",bg="powder blue",command=lambda:btnClick(8))
btn8.grid(row=2,column=1)

btn9=Button(f2,padx=2,pady=16,bd=8,fg="black",font=("arial",20,"bold"),text="9",bg="powder blue",command=lambda:btnClick(9))
btn9.grid(row=2,column=2)

btnarti=Button(f2,padx=2,pady=16,bd=8,fg="black",font=("arial",20,"bold"),text="+",bg="powder blue",command=lambda:btnClick('+'))
btnarti.grid(row=2,column=3)

btn4=Button(f2,padx=2,pady=16,bd=8,fg="black",font=("arial",20,"bold"),text="4",bg="powder blue",command=lambda:btnClick(4))
btn4.grid(row=3,column=0)

btn5=Button(f2,padx=2,pady=16,bd=8,fg="black",font=("arial",20,"bold"),text="5",bg="powder blue",command=lambda:btnClick(5))
btn5.grid(row=3,column=1)

btn6=Button(f2,padx=2,pady=16,bd=8,fg="black",font=("arial",20,"bold"),text="6",bg="powder blue",command=lambda:btnClick(6))
btn6.grid(row=3,column=2)

btneksi=Button(f2,padx=2,pady=16,bd=8,fg="black",font=("arial",20,"bold"),text="-",bg="powder blue",command=lambda:btnClick('-'))
btneksi.grid(row=3,column=3)

btn1=Button(f2,padx=2,pady=16,bd=8,fg="black",font=("arial",20,"bold"),text="1",bg="powder blue",command=lambda:btnClick(1))
btn1.grid(row=4,column=0)

btn2=Button(f2,padx=2,pady=16,bd=8,fg="black",font=("arial",20,"bold"),text="2",bg="powder blue",command=lambda:btnClick(2))
btn2.grid(row=4,column=1)

btn3=Button(f2,padx=2,pady=16,bd=8,fg="black",font=("arial",20,"bold"),text="3",bg="powder blue",command=lambda:btnClick(3))
btn3.grid(row=4,column=2)

btncarp=Button(f2,padx=2,pady=16,bd=8,fg="black",font=("arial",20,"bold"),text="*",bg="powder blue",command=lambda:btnClick('*'))
btncarp.grid(row=4,column=3)

btn0=Button(f2,padx=2,pady=16,bd=8,fg="black",font=("arial",20,"bold"),text="0",bg="powder blue",command=lambda:btnClick(0))
btn0.grid(row=5,column=0)

btnesit=Button(f2,padx=2,pady=16,bd=8,fg="black",font=("arial",20,"bold"),text="=",bg="powder blue",command=btnesittir)
btnesit.grid(row=5,column=1)

btnclear=Button(f2,padx=2,pady=16,bd=8,fg="black",font=("arial",20,"bold"),text="C",bg="powder blue",command=btncleardisplay)
btnclear.grid(row=5,column=2)

btnbol=Button(f2,padx=2,pady=16,bd=8,fg="black",font=("arial",20,"bold"),text="/",bg="powder blue",command=lambda:btnClick('/'))
btnbol.grid(row=5,column=3)

#*************************************
rand=StringVar()
Fries=StringVar()
Burger=StringVar()
Filet=StringVar()
Subtotal=StringVar()
Total=StringVar()
Service=StringVar()
Drinks=StringVar()
Tax=StringVar()
Cost=StringVar()
Chicken_burger=StringVar()
Cheese_burger=StringVar()

lblreferance=Label(f1,font=("arial",16,"bold"),text="referance",bd=16,anchor='w')
lblreferance.grid(row=0,column=0)
txtreferance=Entry(f1,font=("arial",16,"bold"),textvariable=rand,bd=10,insertwidth=4,bg="powder blue")
txtreferance.grid(row=0,column=1)

lblFries=Label(f1,font=("arial",16,"bold"),text="Fries",bd=16,anchor='w')
lblFries.grid(row=1,column=0)
txtFries=Entry(f1,font=("arial",16,"bold"),textvariable=Fries,bd=10,insertwidth=4,bg="powder blue")
txtFries.grid(row=1,column=1)

lblBurger=Label(f1,font=("arial",16,"bold"),text="Burger",bd=16,anchor='w')
lblBurger.grid(row=2,column=0)
txtBurger=Entry(f1,font=("arial",16,"bold"),textvariable=Burger,bd=10,insertwidth=4,bg="powder blue")
txtBurger.grid(row=2,column=1)

lblFilet=Label(f1,font=("arial",16,"bold"),text="Filet",bd=16,anchor='w')
lblFilet.grid(row=3,column=0)
txtFilet=Entry(f1,font=("arial",16,"bold"),textvariable=Filet,bd=10,insertwidth=4,bg="powder blue")
txtFilet.grid(row=3,column=1)

lblSubtotal=Label(f1,font=("arial",16,"bold"),text="Subtotal",bd=16,anchor='w')
lblSubtotal.grid(row=4,column=0)
txtSubtotal=Entry(f1,font=("arial",16,"bold"),textvariable=Subtotal,bd=10,insertwidth=4,bg="powder blue")
txtSubtotal.grid(row=4,column=1)

lbltotal=Label(f1,font=("arial",16,"bold"),text="Total",bd=16,anchor='w')
lbltotal.grid(row=5,column=0)
txttotal=Entry(f1,font=("arial",16,"bold"),textvariable=Total,bd=10,insertwidth=4,bg="powder blue")
txttotal.grid(row=5,column=1)

lblservice=Label(f1,font=("arial",16,"bold"),text="Service",bd=16,anchor='w')
lblservice.grid(row=6,column=0)
txtservice=Entry(f1,font=("arial",16,"bold"),textvariable=Service,bd=10,insertwidth=4,bg="powder blue")
txtservice.grid(row=6,column=1)

lbldrinks=Label(f1,font=("arial",16,"bold"),text="Drinks",bd=16,anchor='w')
lbldrinks.grid(row=7,column=0)
txtdrinks=Entry(f1,font=("arial",16,"bold"),textvariable=Drinks,bd=10,insertwidth=4,bg="powder blue")
txtdrinks.grid(row=7,column=1)

lbltax=Label(f1,font=("arial",16,"bold"),text="Tax",bd=16,anchor='w')
lbltax.grid(row=8,column=0)
txttax=Entry(f1,font=("arial",16,"bold"),textvariable=Tax,bd=10,insertwidth=4,bg="powder blue")
txttax.grid(row=8,column=1)

lblcost=Label(f1,font=("arial",16,"bold"),text="Cost",bd=16,anchor='w')
lblcost.grid(row=0,column=2)
txtcost=Entry(f1,font=("arial",16,"bold"),textvariable=Cost,bd=10,insertwidth=4,bg="powder blue")
txtcost.grid(row=0,column=3)

lblcburger=Label(f1,font=("arial",16,"bold"),text="Chicken_burger",bd=16,anchor='w')
lblcburger.grid(row=1,column=2)
txtcburger=Entry(f1,font=("arial",16,"bold"),textvariable=Chicken_burger,bd=10,insertwidth=4,bg="powder blue")
txtcburger.grid(row=1,column=3)

lblcb=Label(f1,font=("arial",16,"bold"),text="Cheese_burger",bd=16,anchor='w')
lblcb.grid(row=2,column=2)
txtcb=Entry(f1,font=("arial",16,"bold"),textvariable=Cheese_burger,bd=10,insertwidth=4,bg="powder blue")
txtcb.grid(row=2,column=3)
#****************************** BUTONLAR************
btntotal=Button(f1,padx=16,pady=8,bd=16,fg="black",font=("arial",20,"bold"),width=10,text="Total",bg="red",command=Ref)
btntotal.grid(row=10,column=1)

btnreset=Button(f1,padx=16,pady=8,bd=16,fg="black",font=("arial",20,"bold"),width=10,text="Reset",bg="red",command=Reset)
btnreset.grid(row=10,column=2)

btnrexit=Button(f1,padx=16,pady=8,bd=16,fg="black",font=("arial",20,"bold"),width=10,text="EXİT",bg="red",command=Exit)
btnrexit.grid(row=10,column=3)

pencere.mainloop()


import warnings
from pathlib import Path

import cv2
import matplotlib.pyplot as plt
import numpy as np
import onnxruntime
import pandas as pd
import requests
import torch
import torchvision
from onnxruntime.quantization import QuantType
from onnxruntime.quantization.quantize import quantize_dynamic
from segment_anything import SamPredictor, sam_model_registry
from segment_anything.utils.onnx import SamOnnxModel
from sklearn.cluster import DBSCAN
from sklearn.preprocessing import StandardScaler

import hdbscan

def delete_content(directory):
    for child in directory.glob("*"):
        if child.is_file():
            child.unlink()
        else:
            delete_content(child)

def show_mask(mask, ax):
    color = np.array([30 / 255, 144 / 255, 255 / 255, 0.6])
    h, w = mask.shape[-2:]
    mask_image = mask.reshape(h, w, 1) * color.reshape(1, 1, -1)
    ax.imshow(mask_image)

def show_points(coords, labels, ax, marker_size=375):
    pos_points = coords[labels == 1]
    neg_points = coords[labels == 0]
    ax.scatter(
        pos_points[:, 0],
        pos_points[:, 1],
        color="green",
        marker="*",
        s=marker_size,
        edgecolor="white",
        linewidth=1.25,
    )
    ax.scatter(
        neg_points[:, 0],
        neg_points[:, 1],
        color="red",
        marker="*",
        s=marker_size,
        edgecolor="white",
        linewidth=1.25,
    )

def show_box(box, ax):
    x0, y0 = box[0], box[1]
    w, h = box[2] - box[0], box[3] - box[1]
    ax.add_patch(
        plt.Rectangle((x0, y0), w, h, edgecolor="green", facecolor=(0, 0, 0, 0), lw=2)
    )

def load_segment_anything_model(model_type: str, checkpoint: str):
    model_path = Path("models") / checkpoint
    model_path.parent.mkdir(exist_ok=True)

    if model_path.exists():
        sam = sam_model_registry[model_type](checkpoint=model_path)
    else:
        url = f"https://dl.fbaipublicfiles.com/segment_anything/{checkpoint}"
        resp = requests.get(url, allow_redirects=True)
        model_path.write_bytes(resp.content)
        sam = sam_model_registry[model_type](checkpoint=checkpoint)

    return sam

def create_onnx_runtime_session(
    sam,
    onnx_model_path: str = "models/sam_onnx_example.onnx",
    quantized_model_path: str = "models/sam_onnx_quantized_example.onnx",
):
    export_onnx_model(sam, onnx_model_path)
    quantize_onnx_model(onnx_model_path, quantized_model_path)

    return onnxruntime.InferenceSession(quantized_model_path)

def export_onnx_model(sam, onnx_model_path: str) -> str:
    onnx_model = SamOnnxModel(sam, return_single_mask=True)

    dynamic_axes = {
        "point_coords": {1: "num_points"},
        "point_labels": {1: "num_points"},
    }

    embed_dim = sam.prompt_encoder.embed_dim
    embed_size = sam.prompt_encoder.image_embedding_size
    mask_input_size = [4 * x for x in embed_size]
    dummy_inputs = {
        "image_embeddings": torch.randn(1, embed_dim, *embed_size, dtype=torch.float),
        "point_coords": torch.randint(
            low=0, high=1024, size=(1, 5, 2), dtype=torch.float
        ),
        "point_labels": torch.randint(low=0, high=4, size=(1, 5), dtype=torch.float),
        "mask_input": torch.randn(1, 1, *mask_input_size, dtype=torch.float),
        "has_mask_input": torch.tensor([1], dtype=torch.float),
        "orig_im_size": torch.tensor([1500, 2250], dtype=torch.float),
    }
    output_names = ["masks", "iou_predictions", "low_res_masks"]

    with warnings.catch_warnings():
        warnings.filterwarnings("ignore", category=torch.jit.TracerWarning)
        warnings.filterwarnings("ignore", category=UserWarning)
        with open(onnx_model_path, "wb") as f:
            torch.onnx.export(
                onnx_model,
                tuple(dummy_inputs.values()),
                f,
                export_params=True,
                verbose=False,
                opset_version=17,
                do_constant_folding=True,
                input_names=list(dummy_inputs.keys()),
                output_names=output_names,
                dynamic_axes=dynamic_axes,
            )

def quantize_onnx_model(onnx_model_path: str, onnx_model_quantized_path: str) -> str:
    quantize_dynamic(
        model_input=onnx_model_path,
        model_output=onnx_model_quantized_path,
        optimize_model=True,
        per_channel=False,
        reduce_range=False,
        weight_type=QuantType.QUInt8,
    )

def get_input_params(image, step: int = 100) -> dict[str, np.ndarray]:
    input_points = []
    input_labels = []

    height, width = image.shape[:2]

    for x in range(step, width, step):
        for y in range(step, height, step):
            if x in (step, width - step) or y in (step, height - step):
                input_points.append([x, y])
                input_labels.append(0)

    for pos in range(1, 4):
        shift = step * ((pos - 1) % 2) * 4
        range_x = range(pos * width // 6, pos * width * 2 // 6 + 1, step)
        range_y = range(shift + height // 2, shift + height * 2 // 3 + 1, step)
        for i, (x, y) in enumerate(zip(range_x, range_y)):
            input_points.append([x, y])
            input_points.append([x, range_y.stop - i * step])
            input_labels.extend([1, 1])

    input_box = np.array([0, 0, width, height])
    input_points = np.array(input_points)
    input_labels = np.array(input_labels)

    return dict(box=input_box, points=input_points, labels=input_labels)

def extract_regions(predictor, idx, image, input_params: dict[str, np.ndarray]):
    # plt.figure(figsize=(10, 10))
    # plt.imshow(image, cmap="gray")
    # # show_mask(masks[0], plt.gca())
    # # for box in areas:
    # #     show_box(box, plt.gca())
    # # show_points(input_point, input_label, plt.gca())
    # plt.axis("on")
    # plt.show()

    predictor.set_image(image)
    image_embedding = predictor.get_image_embedding().cpu().numpy()

    onnx_coord = np.concatenate(
        [input_params["points"], np.array([[0.0, 0.0]])], axis=0
    )[None, :, :]
    onnx_label = np.concatenate([input_params["labels"], np.array([-1])], axis=0)[
        None, :
    ].astype(np.float32)
    onnx_coord = predictor.transform.apply_coords(onnx_coord, image.shape[:2]).astype(
        np.float32
    )

    onnx_mask_input = np.zeros((1, 1, 256, 256), dtype=np.float32)
    onnx_has_mask_input = np.zeros(1, dtype=np.float32)

    ort_inputs = {
        "image_embeddings": image_embedding,
        "point_coords": onnx_coord,
        "point_labels": onnx_label,
        "mask_input": onnx_mask_input,
        "has_mask_input": onnx_has_mask_input,
        "orig_im_size": np.array(image.shape[:2], dtype=np.float32),
    }

    masks, _, _ = ort_session.run(None, ort_inputs)
    masks = masks > predictor.model.mask_threshold

    masks = np.where(
        masks.sum(keepdims=True, axis=-1) < 0.12 * masks.shape[-1], False, masks
    )
    masks = np.where(
        masks.sum(keepdims=True, axis=-2) < 0.12 * masks.shape[-2], False, masks
    )

    raw_coords = pd.DataFrame(np.argwhere(masks[0][0]), columns=["y", "x"]).iloc[::100]

    coords = StandardScaler().fit_transform(raw_coords)
    clustering = DBSCAN(eps=0.08, min_samples=10).fit(coords)
    # clustering = hdbscan.HDBSCAN(min_cluster_size=300).fit(coords)

    labels, counts = np.unique(clustering.labels_, return_counts=True)

    areas = []
    for label, count in zip(labels, counts):
        if count > 2500:
            points = raw_coords.iloc[clustering.labels_ == label]
            y_min, x_min = points.min(axis=0)
            y_max, x_max = points.max(axis=0)
            areas.append((x_min, y_min, x_max, y_max))

    print()
    print("Page", idx)
    print(sorted(counts, reverse=True))
    print("\n".join(map(str, areas)))

    if idx in (4, 6):
        plt.figure(figsize=(10, 10))
        plt.imshow(image, cmap="gray")
        show_mask(masks[0], plt.gca())
        for box in areas:
            show_box(box, plt.gca())
        show_points(input_params["points"], input_params["labels"], plt.gca())
        plt.axis("on")
        plt.show()

    new_masks = np.zeros_like(masks, dtype=bool)
    new_areas = []
    for area in areas:
        x_min, y_min, x_max, y_max = area
        area_mask = masks[:, :, y_min:y_max, x_min:x_max].copy()

        area_mask = np.where(
            area_mask.sum(keepdims=True, axis=-2) < 0.5 * area_mask.shape[-2],
            False,
            area_mask,
        )
        area_mask = np.where(
            area_mask.sum(keepdims=True, axis=-1) < 0.5 * area_mask.shape[-1],
            False,
            area_mask,
        )
        new_masks[:, :, y_min:y_max, x_min:x_max] = area_mask

        coords = np.argwhere(area_mask[0][0]) + [y_min, x_min]
        if coords.size > 0:
            y_min, x_min = coords.min(axis=0)
            y_max, x_max = coords.max(axis=0)

        new_areas.append((x_min, y_min, x_max, y_max))

    if idx in (4, 6):
        plt.figure(figsize=(10, 10))
        plt.imshow(image, cmap="gray")
        show_mask(new_masks[0], plt.gca())
        for box in new_areas:
            show_box(box, plt.gca())
        show_points(input_params["points"], input_params["labels"], plt.gca())
        plt.axis("on")
        plt.show()

    return new_areas

if __name__ == "__main__":
    model_type = "vit_h"
    checkpoint = "sam_vit_h_4b8939.pth"

    DATA_DIR = Path("data_bis")
    DATA_DIR.mkdir(exist_ok=True)
    delete_content(DATA_DIR)

    sam = load_segment_anything_model(model_type, checkpoint)
    ort_session = create_onnx_runtime_session(sam)
    predictor = SamPredictor(sam.to(device="cuda"))

    input_params = None
    for idx in range(1, 8):
        image = cv2.imread(f"cvat/images/page-{idx}.jpg")
        image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
        image_size = image.shape[0] * image.shape[1]

        if input_params is None:
            input_params = get_input_params(image, step=100)

        regions = extract_regions(predictor, idx, image, input_params)
        regions = pd.DataFrame(regions, columns=["x_min", "y_min", "x_max", "y_max"])

        regions["width"] = regions.x_max - regions.x_min
        regions["height"] = regions.y_max - regions.y_min
        regions["area"] = regions.width * regions.height

        regions = regions.loc[regions.area < 0.8 * image_size]
        regions.sort_values("area", ascending=False, inplace=True)

        for i, (__, reg) in enumerate(regions.iterrows(), start=1):
            region_path = DATA_DIR / f"page-{idx}-{i}.jpg"
            region_image = image[reg.y_min : reg.y_max, reg.x_min : reg.x_max]
            cv2.imwrite(region_path.as_posix(), region_image)


"""Main module."""
import os

import boto3  # type: ignore
import botocore.client  # type: ignore
import botocore.model  # type: ignore
import botocore.awsrequest  # type: ignore
import sqlalchemy  # type: ignore
import sqlalchemy.orm  # type: ignore
import sqlalchemy.ext.declarative  # type: ignore

from aws_session_recorder.lib.schema.functions import ApiCallMap
from aws_session_recorder.lib.schema.base import Base

class Session(boto3.session.Session):
    db: sqlalchemy.orm.Session
    Base: sqlalchemy.ext.declarative.DeclarativeMeta

    def __init__(self, connection_string: str = f"sqlite:///{os.path.join(os.getcwd(), 'sqlite.db')}", *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.setup(connection_string=connection_string)

    def setup(self, connection_string: str):
        engine = sqlalchemy.create_engine(connection_string, echo=False)
        Base.metadata.create_all(engine)
        self.db = sqlalchemy.orm.Session(engine)

    def client(self, *args, **kwargs):
        client: botocore.client.BaseClient = super().client(*args, **kwargs)
        client.meta.events.register('provide-client-params.iam.*', self.record_request)
        client.meta.events.register('after-call.iam.*', self.record_response)
        return client

    def record_request(
        self,
        params: dict,
        model: botocore.model.OperationModel,
        context: dict,
        event_name: str,
        *args, **kwargs
    ):
        context['request_params'] = params

    def record_response(self,
                        http_response: botocore.awsrequest.AWSResponse,
                        parsed: dict,
                        model: botocore.model.OperationModel,
                        context: dict,
                        event_name: str,
                        *args, **kwargs):

        try:
            f = ApiCallMap[model.name]
        except KeyError:
            print("Schema not implemented for {}".format(model.name))
            return

        request_params = context['request_params']
        parsed_resp = parsed
        row = f(request_params, parsed_resp)  # type: ignore[arg-type]
        if hasattr(row, '__next__'):
            for r in row:
                self.db.merge(r)
        else:
            self.db.merge(row)

        self.db.commit()
        self.db.flush()


from pymongo import MongoClient

#########################################
# DETAILS
#########################################
url = "<your-cluster-link>"
client = MongoClient(url)

# Send a ping to connection
try:
    client.admin.command('ping')
    print("Database is online.")
except Exception as e:
    print(e)

# Creating a database.
db = client.SIH_23


import operator

import six
from django.utils.translation import get_language, gettext as _
from elasticsearch_dsl.query import Bool, Q
from flatdict import FlatDict
from marshmallow import fields
from marshmallow.exceptions import ValidationError
from marshmallow.validate import Validator

from mcod import settings
from mcod.core.api.search import constants
from mcod.lib import field_validators

MISSING_ERROR_MESSAGE = (
    'ValidationError raised by `{class_name}`, but error key `{key}` does '
    'not exist in the `error_messages` dictionary.'
)

class TranslatedErrorsMixin:
    def make_error(self, key, **kwargs):
        try:
            msg = _(self.error_messages[key])
        except KeyError:
            class_name = self.__class__.__name__
            msg = _(MISSING_ERROR_MESSAGE).format(class_name=class_name, key=key)
            raise AssertionError(msg)
        if isinstance(msg, (str, bytes)):
            msg = msg.format(**kwargs)
        raise ValidationError(msg)

    def _validate(self, value):
        errors = []
        kwargs = {}
        for validator in self.validators:
            try:
                r = validator(value)
                if not isinstance(validator, Validator) and r is False:
                    self.make_error('validator_failed')
            except ValidationError as err:
                kwargs.update(err.kwargs)
                if isinstance(err.messages, dict):
                    errors.append(err.messages)  # TODO
                else:
                    errors.extend((_(msg) for msg in err.messages))
        if errors:
            raise ValidationError(errors, **kwargs)

class DataMixin:
    def prepare_data(self, name, data):
        return data

    def prepare_queryset(self, queryset, context=None):
        return queryset

class SearchFieldMixin:
    @staticmethod
    def _filter_empty(filter_list):
        return list(filter(lambda el: el != '', filter_list))

    def split_lookup_value(self, value, maxsplit=-1):
        return self._filter_empty(value.split(constants.SEPARATOR_LOOKUP_VALUE, maxsplit))

    def split_lookup_filter(self, value, maxsplit=-1):
        return self._filter_empty(value.split(constants.SEPARATOR_LOOKUP_FILTER, maxsplit))

    def split_lookup_complex_value(self, value, maxsplit=-1):
        return self._filter_empty(value.split(constants.SEPARATOR_LOOKUP_COMPLEX_VALUE, maxsplit))

class Raw(DataMixin, TranslatedErrorsMixin, fields.Raw):
    pass

class Nested(DataMixin, TranslatedErrorsMixin, fields.Nested):
    pass

class List(DataMixin, TranslatedErrorsMixin, fields.List):
    pass

class String(DataMixin, TranslatedErrorsMixin, fields.String):
    pass

Str = String

class UUID(DataMixin, TranslatedErrorsMixin, fields.UUID):
    pass

class Number(DataMixin, TranslatedErrorsMixin, fields.Number):
    pass

class Integer(DataMixin, TranslatedErrorsMixin, fields.Integer):
    pass

Int = Integer

class Decimal(DataMixin, TranslatedErrorsMixin, fields.Decimal):
    pass

class Boolean(DataMixin, TranslatedErrorsMixin, fields.Boolean):
    pass

class Float(DataMixin, TranslatedErrorsMixin, fields.Float):
    pass

class DateField(DataMixin, TranslatedErrorsMixin, fields.DateTime):
    pass

class Time(DataMixin, TranslatedErrorsMixin, fields.Time):
    pass

class Date(DataMixin, TranslatedErrorsMixin, fields.Date):
    pass

class TimeDelta(DataMixin, TranslatedErrorsMixin, fields.TimeDelta):
    pass

class Dict(DataMixin, TranslatedErrorsMixin, fields.Dict):
    pass

class Url(DataMixin, TranslatedErrorsMixin, fields.Url):
    pass

class Email(DataMixin, TranslatedErrorsMixin, fields.Email):
    pass

class Method(DataMixin, TranslatedErrorsMixin, fields.Method):
    pass

class Function(DataMixin, TranslatedErrorsMixin, fields.Function):
    pass

class Constant(DataMixin, TranslatedErrorsMixin, fields.Constant):
    pass

class Base64(String):
    default_error_messages = {
        'invalid_base64': 'Invalid data format for base64 encoding.',
        'too_long': 'Too long data.'
    }

    def __init__(self, max_size=None, **kwargs):
        super().__init__(**kwargs)
        self.validators.insert(0, field_validators.Base64(
            max_size=max_size,
            base64_error=self.error_messages['invalid_base64'],
            length_error=self.error_messages['too_long']
        ))

class FilteringFilterField(SearchFieldMixin, DataMixin, TranslatedErrorsMixin, fields.Field):
    def __init__(self, field_name='', lookups=None, translated=False, **metadata):
        super().__init__(**metadata)
        self.lookups = lookups if isinstance(lookups, list) else []
        self.field_name = field_name
        self.trans = translated

    @property
    def _name(self):
        return (self.field_name or self.name) + (f".{get_language()}" if self.trans else "")

    @property
    def _base_name(self):
        return self.field_name or self.name

    def prepare_data(self, name, data):
        data = dict(data)
        if name in data:
            nkey = '%s%s%s' % (name, constants.SEPARATOR_LOOKUP_FILTER, constants.LOOKUP_FILTER_TERM)
            data[nkey] = data.pop(name)
        field_data = {k: v for k, v in data.items() if k.startswith(name)}
        data.update(FlatDict(field_data, delimiter=constants.SEPARATOR_LOOKUP_FILTER).as_dict())
        return data

    def _deserialize(self, value, attr, data):
        if isinstance(value, str):
            return {constants.LOOKUP_FILTER_TERM: value}
        return value

    def _validate(self, values):
        unsupported_lookups = list(set(values.keys() - self.lookups))
        if unsupported_lookups:
            raise ValidationError('Unsupported filter')

    def get_range_params(self, value):
        __values = self.split_lookup_value(value, maxsplit=3)
        __len_values = len(__values)

        if __len_values == 0:
            return {}

        params = {
            'gte': __values[0]
        }

        if __len_values == 3:
            params['lte'] = __values[1]
            params['boost'] = __values[2]
        elif __len_values == 2:
            params['lte'] = __values[1]

        return params

    def get_gte_lte_params(self, value, lookup):
        __values = self.split_lookup_value(value, maxsplit=2)
        __len_values = len(__values)

        if __len_values == 0:
            return {}

        params = {
            lookup: __values[0]
        }

        if __len_values == 2:
            params['boost'] = __values[1]

        return params

    def prepare_queryset(self, queryset, context=None):  # noqa:C901
        data = context or self.context
        if not data:
            return queryset
        if self.trans:
            _qs = []
            for lookup, value in data.items():
                func = getattr(self, 'get_filter_{}'.format(lookup), None)
                if not func:
                    continue
                q = func(value)
                if q:
                    _qs.append(q)

            return queryset.query(Q('nested', path=self._base_name, query=six.moves.reduce(operator.and_, _qs)))
        else:
            for lookup, value in data.items():
                func = getattr(self, 'get_filter_{}'.format(lookup), None)
                if not func:
                    continue
                q = func(value)
                if q:
                    queryset = queryset.query(q)

            return queryset

    def get_filter_onlist(self, value):
        if isinstance(value, (list, tuple)):
            __values = value
        else:
            __values = self.split_lookup_value(value)
        must = []
        for value in list(set(__values)):
            must.append(Q('term', **{self._name: value}))
        return Q('bool', must=must)

    def get_filter_term(self, value):
        return Q('term', **{self._name: value})

    def get_filter_terms(self, value):
        if isinstance(value, (list, tuple)):
            __values = value
        else:
            __values = self.split_lookup_value(value)

        return Q(
            'terms',
            **{self._name: __values}
        )

    def get_filter_range(self, value):
        return Q(
            'range',
            **{self._name: self.get_range_params(value)}
        )

    def get_filter_exists(self, value):
        _value_lower = value.lower()
        if _value_lower in constants.TRUE_VALUES:
            return Q("exists", field=self._name)
        elif _value_lower in constants.FALSE_VALUES:
            return ~Q("exists", field=self._name)
        return None

    def get_filter_prefix(self, value):
        return Q(
            'prefix',
            **{self._name: value}
        )

    def get_filter_wildcard(self, value):
        return Q('wildcard', **{self._name: value})

    def get_filter_contains(self, value):
        return Q('wildcard', **{self._name: '*{}*'.format(value)})

    def get_filter_startswith(self, value):
        return Q('prefix', **{self._name: '{}'.format(value)})

    def get_filter_endswith(self, value):
        return Q('wildcard', **{self._name: '*{}'.format(value)})

    def get_filter_in(self, value):
        return self.get_filter_terms(value)

    def get_filter_gt(self, value):
        return Bool(filter=[
            Q('range', **{self._name: self.get_gte_lte_params(value, 'gt')})
        ])

    def get_filter_gte(self, value):
        return Bool(filter=[
            Q('range', **{self._name: self.get_gte_lte_params(value, 'gte')})
        ])

    def get_filter_lt(self, value):
        return Bool(filter=[Q(
            'range',
            **{self._name: self.get_gte_lte_params(value, 'lt')}
        )])

    def get_filter_lte(self, value):
        return Bool(filter=[Q(
            'range',
            **{self._name: self.get_gte_lte_params(value, 'lte')}
        )])

    def get_filter_exclude(self, value):
        __values = self.split_lookup_value(value)

        __queries = []
        for __value in __values:
            __queries.append(
                ~Q('term', **{self._name: __value})
            )

        if __queries:
            return six.moves.reduce(operator.or_, __queries)

        return None

class NestedFilteringField(FilteringFilterField):
    def __init__(self, path, field_name=None, lookups=[], **kwargs):
        super().__init__(field_name=field_name, lookups=lookups, **kwargs)
        self.path = path

    def prepare_queryset(self, queryset, context=None):  # noqa:C901
        data = context or self.context
        if not data:
            return queryset
        for lookup, value in data.items():
            func = getattr(self, 'get_filter_{}'.format(lookup), None)
            if not func:
                continue
            q = func(value)
            if q:
                queryset = queryset.query('nested', path=self.path, query=q)

        return queryset

class IdsSearchField(SearchFieldMixin, DataMixin, TranslatedErrorsMixin, fields.Field):
    def prepare_queryset(self, queryset, context=None):
        data = context or self.context
        if not data:
            return queryset
        __ids = []
        for item in data:
            __values = self.split_lookup_value(item)
            __ids += __values

        if __ids:
            __ids = list(set(__ids))
            queryset = queryset.query(
                'ids', **{'values': __ids}
            )
        return queryset

class SuggesterFilterField(SearchFieldMixin, DataMixin, TranslatedErrorsMixin, fields.Field):
    def __init__(self, field, suggesters=None, **metadata):
        self.field_name = field
        self.suggesters = suggesters if isinstance(suggesters, list) else (constants.ALL_SUGGESTERS,)
        super().__init__(**metadata)

    def prepare_data(self, name, data):
        data = dict(data)
        field_data = {k: v for k, v in data.items() if k.startswith(name)}
        data.update(FlatDict(field_data, delimiter=constants.SEPARATOR_LOOKUP_FILTER).as_dict())
        return data

    def apply_suggester_term(self, queryset, value):
        return queryset.suggest(
            self.name,
            value,
            term={'field': self.field_name}
        )

    def apply_suggester_phrase(self, queryset, value):
        return queryset.suggest(
            self.name,
            value,
            phrase={'field': self.field_name}
        )

    def apply_suggester_completion(self, queryset, value):
        return queryset.suggest(
            self.name,
            value,
            completion={'field': self.field_name}
        )

    def prepare_queryset(self, queryset, context=None):
        data = context or self.context
        if not data:
            return queryset
        for suggester_type, value in data.items():
            if suggester_type in self.suggesters:
                if suggester_type == constants.SUGGESTER_TERM:
                    queryset = self.apply_suggester_term(queryset, value)
                elif suggester_type == constants.SUGGESTER_PHRASE:
                    queryset = self.apply_suggester_phrase(queryset, value)
                elif suggester_type == constants.SUGGESTER_COMPLETION:
                    queryset = self.apply_suggester_completion(queryset, value)
        return queryset

class SearchFilterField(SearchFieldMixin, DataMixin, TranslatedErrorsMixin, fields.Field):
    def __init__(self, search_fields=None, search_nested_fields=None, search_i18n_fields=None, **metadata):
        self.field_names = search_fields if isinstance(search_fields, (list, tuple, dict)) else ()
        self.search_nested_fields = search_nested_fields if isinstance(search_nested_fields, dict) else {}
        self.search_i18n_fields = search_i18n_fields if isinstance(search_i18n_fields, (list, tuple)) else ()
        super().__init__(**metadata)

    def _deserialize(self, value, attr, data):
        if isinstance(value, str):
            return [value, ]
        return value

    def construct_nested_search(self, data):
        __queries = []
        for search_term in data:
            for path, _fields in self.search_nested_fields.items():
                queries = []
                for field in _fields:
                    field_key = "{}.{}".format(path, field)
                    queries.append(
                        Q("match", **{field_key: {
                            'query': search_term,
                            'fuzziness': 'AUTO',
                            'fuzzy_transpositions': True
                        }})
                    )

                __queries.append(
                    Q(
                        "nested",
                        path=path,
                        query=six.moves.reduce(operator.or_, queries)
                    )
                )

        return __queries

    def construct_translated_search(self, data):
        __queries = []
        for search_term in data:
            for field in self.search_i18n_fields:
                queries = []
                for lang in settings.MODELTRANS_AVAILABLE_LANGUAGES:
                    field_key = f"{field}.{lang}"
                    queries += [
                        Q("match", **{field_key: {
                            'query': search_term,
                            'fuzziness': 'AUTO',
                            'fuzzy_transpositions': True
                        }}),
                        Q("match", **{field_key + ".asciied": {
                            'query': search_term,
                            'fuzziness': 'AUTO',
                            'fuzzy_transpositions': True
                        }}),
                    ]

                __queries.append(
                    Q(
                        "nested",
                        path=field,
                        query=six.moves.reduce(operator.or_, queries)
                    )
                )
        return __queries

    def _prepare_match_query(self, field, value):
        # Initial kwargs for the match query
        field_kwargs = {field: {
            'query': value,
            'fuzziness': 'AUTO',
            'fuzzy_transpositions': True,
        }}
        # In case if we deal with structure 2
        if isinstance(self.field_names, dict):
            extra_field_kwargs = self.field_names[field]
            if extra_field_kwargs:
                field_kwargs[field].update(extra_field_kwargs)

        return Q("match", **field_kwargs)

    def construct_search(self, data):
        __queries = []

        for search_term in data:
            __values = self.split_lookup_value(search_term, 1)
            __len_values = len(__values)
            if __len_values > 1:
                field, value = __values
                if field in self.field_names:
                    __queries.append(
                        self._prepare_match_query(field, value)
                    )

            else:
                for field in self.field_names:
                    __queries.append(
                        self._prepare_match_query(field, search_term)
                    )
        return __queries

    def prepare_queryset(self, queryset, context=None):
        data = context or self.context
        if not data:
            return queryset
        __queries = sum((self.construct_search(data),
                         self.construct_nested_search(data),
                         self.construct_translated_search(data)),
                        [])

        if __queries:
            queryset = queryset.query('bool', should=__queries)
        return queryset

class FacetedFilterField(SearchFieldMixin, DataMixin, TranslatedErrorsMixin, fields.Field):
    def __init__(self, facets=None, **metadata):
        self.facets = facets if isinstance(facets, dict) else {}
        super().__init__(**metadata)

    def _deserialize(self, value, attr, data):
        if isinstance(value, str):
            return value.split(',')
        return value

    def prepare_queryset(self, queryset, context=None):
        data = context or self.context
        if not data:
            return queryset

        for __field, __facet in self.facets.items():
            if __field in data:
                agg = __facet.get_aggregation()
                agg_filter = Q('match_all')

                queryset.aggs.bucket(
                    '_filter_' + __field,
                    'filter',
                    filter=agg_filter
                ).bucket(__field, agg)
        return queryset

class OrderingFilterField(SearchFieldMixin, DataMixin, TranslatedErrorsMixin, fields.Field):
    ordering_param = 'sort'

    def __init__(self, ordering_fields=None, default_ordering=None, **metadata):
        self.ordering_fields = ordering_fields if isinstance(ordering_fields, dict) else {}
        self.ordering_fields['_score'] = '_score'
        self.default_ordering = default_ordering or []
        super().__init__(**metadata)

    def prepare_fields_data(self, data):
        sort_params = data or self.default_ordering
        if isinstance(sort_params, str):
            sort_params = [sort_params, ]
        __sort_params = []
        for param in sort_params:
            __key = param.lstrip('-')
            __direction = '-' if param.startswith('-') else ''
            if __key in self.ordering_fields:
                __field_name = self.ordering_fields[__key] or __key
                if '{lang}' in __field_name:
                    __field_name = __field_name.format(lang=get_language())
                    nested_path = __field_name.split('.')[0]
                    __sort_params.append({
                        __field_name: {
                            'order': 'desc' if __direction == '-' else 'asc',
                            'nested': {
                                'path': nested_path
                            }
                        }
                    })
                else:
                    __sort_params.append('{}{}'.format(__direction, __field_name.format(lang=get_language())))
        return __sort_params

    def prepare_queryset(self, queryset, context=None):
        data = context or self.context
        if not data:
            return queryset

        return queryset.sort(*self.prepare_fields_data(data))

class HighlightBackend(SearchFieldMixin, DataMixin, TranslatedErrorsMixin, fields.Field):
    _ALL = '_all'
    _ES_ALL_KEY = _ALL

    def __init__(self, highlight_fields=None, **metadata):
        self.highlight_fields = highlight_fields or {}
        super().__init__(**metadata)

    def prepare_fields_data(self, data):
        highlight_fields = data or []
        __params = {}
        if isinstance(highlight_fields, str):
            highlight_fields = [highlight_fields, ]

        if self._ALL in self.highlight_fields:
            __params[self._ES_ALL_KEY] = self.highlight_fields[self._ALL]
            __params[self._ES_ALL_KEY]['enabled'] = True

        for field in highlight_fields:
            if field in self.highlight_fields:
                if 'enabled' not in self.highlight_fields[field]:
                    self.highlight_fields[field]['enabled'] = False

                if 'options' not in self.highlight_fields[field]:
                    self.highlight_fields[field]['options'] = {}
                __params[field] = self.highlight_fields[field]
        return __params

    def prepare_queryset(self, queryset, context=None):
        data = context or self.context
        if not data:
            return queryset

        params = self.prepare_fields_data(data)

        for __field, __options in params.items():
            if __options['enabled']:
                queryset = queryset.highlight(__field, **__options['options'])

        return queryset


import torch
from torch import nn
from tqdm.auto import tqdm
from torchvision import transforms
from torchvision.datasets import MNIST
from torchvision.utils import make_grid
from torch.utils.data import DataLoader
import matplotlib.pyplot as plt

def show_tensor_images(image_tensor, num_images=25):
    image_tensor = (image_tensor + 1) / 2
    image_unflat = image_tensor.detach().cpu()
    image_grid = make_grid(image_unflat[:num_images], nrow=5)
    plt.imshow(image_grid.permute(1, 2, 0).squeeze())
    plt.show()

def get_noise(n_samples, z_dim, device='cpu'):
    return torch.randn(n_samples, z_dim, device=device)

def weights_init(m):
    if isinstance(m, nn.Conv2d) or isinstance(m, nn.ConvTranspose2d):
        torch.nn.init.normal_(m.weight, 0.0, 0.02)
    if isinstance(m, nn.BatchNorm2d):
        torch.nn.init.normal_(m.weight, 0.0, 0.02)
        torch.nn.init.constant_(m.bias, 0)

class Generator(nn.Module):
    def __init__(self, z_dim=10, im_chan=1, hidden_dim=64):
        super(Generator, self).__init__()
        self.z_dim = z_dim
        self.gen = nn.Sequential(
            self.make_gen_block(z_dim, hidden_dim * 4),
            self.make_gen_block(hidden_dim * 4, hidden_dim * 2, kernel_size=4, stride=1),
            self.make_gen_block(hidden_dim * 2, hidden_dim),
            self.make_gen_block(hidden_dim, im_chan, kernel_size=4, final_layer=True),
        )

    @staticmethod
    def make_gen_block(input_channels, output_channels, kernel_size=3, stride=2, final_layer=False):
        if not final_layer:
            return nn.Sequential(
                nn.ConvTranspose2d(input_channels, output_channels, kernel_size, stride),
                nn.BatchNorm2d(output_channels),
                nn.ReLU()
            )
        else:
            return nn.Sequential(
                nn.ConvTranspose2d(input_channels, output_channels, kernel_size, stride),
                nn.Tanh()
            )

    def unsqueeze_noise(self, noise):
        return noise.view(len(noise), self.z_dim, 1, 1)

    def forward(self, noise):
        x = self.unsqueeze_noise(noise)
        return self.gen(x)

class Discriminator(nn.Module):

    def __init__(self, im_chan=1, hidden_dim=16):
        super(Discriminator, self).__init__()
        self.disc = nn.Sequential(
            self.make_disc_block(im_chan, hidden_dim),
            self.make_disc_block(hidden_dim, hidden_dim * 2),
            self.make_disc_block(hidden_dim * 2, 1, final_layer=True),
        )

    @staticmethod
    def make_disc_block(self, input_channels, output_channels, kernel_size=4, stride=2, final_layer=False):
        if not final_layer:
            return nn.Sequential(
                nn.Conv2d(input_channels, output_channels, kernel_size, stride),
                nn.BatchNorm2d(output_channels),
                nn.LeakyReLU(negative_slope=0.2)
            )
        else:  # Final Layer
            return nn.Sequential(
                nn.Conv2d(input_channels, output_channels, kernel_size, stride),
            )

    def forward(self, image):
        disc_pred = self.disc(image)
        return disc_pred.view(len(disc_pred), -1)

if __name__ == "__main__":
    criterion = nn.BCEWithLogitsLoss()
    z_dim = 64
    display_step = 500
    batch_size = 128
    lr = 0.0002

    beta_1 = 0.5
    beta_2 = 0.999
    device = 'cpu'

    transform = transforms.Compose([
        transforms.ToTensor(),
        transforms.Normalize((0.5,), (0.5,)),
    ])

    dataloader = DataLoader(
        MNIST('.', download=False, transform=transform),
        batch_size=batch_size,
        shuffle=True)

    gen = Generator(z_dim).to(device)
    gen_opt = torch.optim.Adam(gen.parameters(), lr=lr, betas=(beta_1, beta_2))
    disc = Discriminator().to(device)
    disc_opt = torch.optim.Adam(disc.parameters(), lr=lr, betas=(beta_1, beta_2))

    gen = gen.apply(weights_init)
    disc = disc.apply(weights_init)

    n_epochs = 50
    cur_step = 0
    mean_generator_loss = 0
    mean_discriminator_loss = 0
    for epoch in range(n_epochs):
        for real, _ in tqdm(dataloader):
            cur_batch_size = len(real)
            real = real.to(device)

            disc_opt.zero_grad()
            fake_noise = get_noise(cur_batch_size, z_dim, device=device)
            fake = gen(fake_noise)
            disc_fake_pred = disc(fake.detach())
            disc_fake_loss = criterion(disc_fake_pred, torch.zeros_like(disc_fake_pred))
            disc_real_pred = disc(real)
            disc_real_loss = criterion(disc_real_pred, torch.ones_like(disc_real_pred))
            disc_loss = (disc_fake_loss + disc_real_loss) / 2

            mean_discriminator_loss += disc_loss.item() / display_step
            disc_loss.backward(retain_graph=True)
            disc_opt.step()

            gen_opt.zero_grad()
            fake_noise_2 = get_noise(cur_batch_size, z_dim, device=device)
            fake_2 = gen(fake_noise_2)
            disc_fake_pred = disc(fake_2)
            gen_loss = criterion(disc_fake_pred, torch.ones_like(disc_fake_pred))
            gen_loss.backward()
            gen_opt.step()

            mean_generator_loss += gen_loss.item() / display_step

            if cur_step % display_step == 0 and cur_step > 0:
                print(f"Epoch {epoch}, step {cur_step}: Generator loss: {mean_generator_loss}, "
                      f"discriminator loss: {mean_discriminator_loss}")
                show_tensor_images(fake)
                show_tensor_images(real)
                mean_generator_loss = 0
                mean_discriminator_loss = 0
            cur_step += 1


# Python 3.5

import sys
import string
import itertools

h = [int(h_temp) for h_temp in input().strip().split(' ')]

heights = dict (zip (string.ascii_lowercase, itertools.cycle (h)))
word = list (input().strip())

width = 1

total_width = len (word) * width
total_height = 0

for letter in word:
    new_height = heights [letter]

    if (new_height > total_height):
        total_height = new_height

print ("%d" % (total_width * total_height))

HackerRank/Core CS/Algorithms/Implementation/Designer PDF Viewer.py


import torch
import torch.nn as nn
import torch.nn.functional as F
from typing import Optional

from torch import Tensor
import segmentation_models_pytorch as smp
from segmentation_models_pytorch.utils.base import Loss
from segmentation_models_pytorch.utils.functional import f_score

class CrossEntropyLoss(nn.CrossEntropyLoss):
    __name__ = 'CrossEntropyLoss'

    def forward(self, input: Tensor, target: Tensor) -> Tensor:
        target = target.argmax(1).long()
        return F.cross_entropy(input, target, weight=self.weight,
                               ignore_index=self.ignore_index, reduction=self.reduction)

class CrossEntropyLoss2d(nn.Module):
    __name__ = 'CrossEntropyLoss2D'
    def __init__(self, weight=None, size_average=True):
        super(CrossEntropyLoss2d, self).__init__()
        self.nll_loss = nn.NLLLoss(weight, size_average)
        self.softmax = nn.LogSoftmax(dim=1)

    def forward(self, inputs, targets):
        return self.nll_loss(self.softmax(inputs), targets.argmax(dim=1))

class CE_Dice_Loss(nn.Module):
    __name__ = 'CE_Dice_Loss'
    def __init__(self, weight=None, size_average=True):
        super(CE_Dice_Loss, self).__init__()
        self.nll_loss = nn.NLLLoss(weight, size_average)
        self.softmax = nn.LogSoftmax(dim=1)
        self.diceloss = smp.utils.losses.DiceLoss(ignore_channels=[0])

    def forward(self, inputs, targets):
        CEloss = self.nll_loss(self.softmax(inputs), targets.argmax(dim=1))
        diceloss = self.diceloss(self.softmax(inputs), targets)
        return diceloss*0.1 + CEloss

class CrossEntropyWithDiceLoss(nn.CrossEntropyLoss, Loss):
    __name__ = 'CrossEntropyWithDiceLoss'

    def __init__(self, weight: Optional[torch.Tensor] = None,\
                    size_average=None, ignore_index: int = -100,\
                    reduce=None, reduction: str = 'mean',\
                    eps=1., beta=1., ignore_channels=None):
        super(nn.CrossEntropyLoss, self).__init__(weight=weight, \
            size_average=size_average, \
            reduce=reduce, reduction=reduction)
        self.ignore_index=ignore_index
        self.eps = eps
        self.beta = beta
        self.ignore_channels = ignore_channels

    def forward(self, input: Tensor, target: Tensor) -> Tensor:
        dice = 1 - f_score(input, target,
            beta=self.beta, eps=self.eps, threshold=None,
            ignore_channels=self.ignore_channels,)
        target = target.argmax(1).long()
        crossentropy = F.cross_entropy(input, target, weight=self.weight,
                               ignore_index=self.ignore_index, reduction=self.reduction)
        return 0.5 * crossentropy + dice