from collections import deque

# given a directed graph, determine if there is a path between two nodes

def path_exists(graph, start, end):
    """
    Given a directed graph stored as a adjacency sets, determine if there
    is a path between a node holding the 'start' value and a node holding
    the 'end' value.

    :param dict graph: graph represented as a adjacency sets
    :param start: start value
    :param end: end value
    """
    explored = set()
    q = deque([start])
    while q:
        current = q.pop()
        if current == end:
            return True
        if current in explored:
            continue
        explored.add(current)
        for adjacent in graph.get(current, set()):
            q.appendleft(adjacent)
    return False

def test1():
    graph = {
        "A": {"B", "C"},
        "B": {"D"},
        "D": {"F"},
        "E": {"D"},
    }
    assert path_exists(graph, "A", "D") is True
    print("test 1 successful")

def test2():
    graph = {
        "A": {"B", "C"},
        "B": {"D"},
        "D": {"F"},
        "E": {"D"},
    }
    assert path_exists(graph, "A", "E") is False
    print("test 2 successful")

def test3():
    graph = {
        "A": {"B", "C"},
        "B": {"D"},
        "D": {"F"},
        "E": {"D"},
    }
    assert path_exists(graph, "C", "D") is False
    print("test 3 successful")

def main():
    test1()
    test2()
    test3()

if __name__ == "__main__":
    main()


import torchvision.datasets
import torchvision.transforms
import numpy as np
import torch

def get_data_loaders():
    transformImg = torchvision.transforms.Compose([torchvision.transforms.ToTensor(),
                                                   torchvision.transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])
    train = torchvision.datasets.MNIST(root='./data', train=True, download=True, transform=transformImg)
    valid = torchvision.datasets.MNIST(root='./data', train=True, download=True, transform=transformImg)
    test = torchvision.datasets.MNIST(root='./data', train=False, download=True, transform=transformImg)

    # create training and validation set indexes (80-20 split)
    idx = list(range(len(train)))
    np.random.seed(1009)
    np.random.shuffle(idx)
    train_idx = idx[ : int(0.8 * len(idx))]
    valid_idx = idx[int(0.8 * len(idx)) : ]

    # generate training and validation set samples
    train_set = torch.utils.data.sampler.SubsetRandomSampler(train_idx)
    valid_set = torch.utils.data.sampler.SubsetRandomSampler(valid_idx)

    # Load training and validation data based on above samples
    # Size of an individual batch during training and validation is 30
    # Both training and validation datasets are shuffled at every epoch by 'SubsetRandomSampler()'. Test set is not shuffled.
    train_loader = torch.utils.data.DataLoader(train, batch_size=32, sampler=train_set, num_workers=4)
    valid_loader = torch.utils.data.DataLoader(train, batch_size=32, sampler=valid_set, num_workers=4)
    test_loader = torch.utils.data.DataLoader(test, num_workers=4)
    return train_loader, valid_loader, test_loader


from tkinter import *
import tkinter as tk
from tkinter import messagebox, ttk
from deposito import *

def depositar():
        ventana_deposito = tk.Toplevel()
        ventana_deposito.title("Deposito de dinero")
        ventana_deposito.geometry("600x400")

        ##Secciones ventana depositar
        seccionD1 = Frame (ventana_deposito,bg= "black")
        seccionD1.pack(expand=True,fill='both')
        seccionD2 = Frame (ventana_deposito,bg= "black")
        seccionD2.pack(expand=True,fill='both')
        seccionD3 = Frame (ventana_deposito,bg= "black")
        seccionD3.pack(expand=True,fill='both')

        ##Textos ventana depositar
        txtDe= Label(seccionD1,text="Deposito de cuenta",bg= "black", fg="orange")
        txtDe.configure(font=("arial", 14))
        txtDe.place(width="650", height="80")
        txtNoc= Label(seccionD2,text="Numero de cuenta: ",bg= "black", fg="orange")
        txtNoc.configure(font=("arial",10))
        txtNoc.place(x=90,y=40)
        txtTI= Label(seccionD2,text="Total a ingresar: ",bg= "black", fg="orange")
        txtTI.configure(font=("arial",10))
        txtTI.place(x=90,y=80)

        ##cuadros ventana deposito
        NoDep= Entry(seccionD2, bg="#F3F3F3")
        NoDep.place(x=220, y=43)
        CanDep= Entry(seccionD2, bg="#F3F3F3")
        CanDep.place(x=200, y=80)

        def depo():

             NoCuDep = NoDep.get()
             CanDeDep = int(CanDep.get())
             consultaS.Depo(NoCuDep,CanDeDep)

        ##Botones ventana depositar
        botonDepo = Button(seccionD3,text="Confirmar", fg= "black", bg="orange", command= depo )
        botonDepo.place(x=90, y=40)
        botonDepo = Button(seccionD3,text="regresar", fg= "black", bg="orange", command= ventana_deposito.destroy)
        botonDepo.place(x=180, y=40)

def retirar():
        ventana_retiro = tk.Toplevel()
        ventana_retiro.title("Reitro de dinero")
        ventana_retiro.geometry("600x400")

        ##Secciones ventana Retirar
        seccionR1 = Frame (ventana_retiro,bg= "black")
        seccionR1.pack(expand=True,fill='both')
        seccionR2 = Frame (ventana_retiro,bg= "black")
        seccionR2.pack(expand=True,fill='both')
        seccionR3 = Frame (ventana_retiro,bg= "black")
        seccionR3.pack(expand=True,fill='both')

        ##Textos ventana Retirar
        txtRe= Label(seccionR1,text="Retiro de efectivo",bg= "black", fg="orange")
        txtRe.configure(font=("arial", 14))
        txtRe.place(width="650", height="80")
        txtNoc= Label(seccionR2,text="Numero de cuenta: ",bg= "black", fg="orange")
        txtNoc.configure(font=("arial",10))
        txtNoc.place(x=90,y=40)
        txtNIP= Label(seccionR2,text="Ingresa tu NIP: ",bg= "black", fg="orange")
        txtNIP.configure(font=("arial",10))
        txtNIP.place(x=90,y=80)
        txtTR= Label(seccionR2,text="Total a retirar: ",bg= "black", fg="orange")
        txtTR.configure(font=("arial",10))
        txtTR.place(x=90,y=110)

        ##cuadros ventana Retirar
        NoRe= Entry(seccionR2, bg="#F3F3F3")
        NoRe.place(x=220, y=43)
        Retnip= Entry(seccionR2, bg="#F3F3F3")
        Retnip.place(x=200, y=80)
        CanRe= Entry(seccionR2, bg="#F3F3F3")
        CanRe.place(x=200, y=110)

        def ret():

             NoCuDep = NoRe.get()
             Gnip = Retnip.get()
             CanDeRet = CanRe.get()
             consultaS.Ret(NoCuDep,Gnip,CanDeRet)

        ##Botones ventana Retirar
        botonDepo = Button(seccionR3,text="Retirar", fg= "black", bg="orange", command= ret)
        botonDepo.place(x=90, y=40)
        botonDepo = Button(seccionR3,text="Regresar", fg= "black", bg="orange", command= ventana_retiro.destroy)
        botonDepo.place(x=180, y=40)

def Saldo():
        ventana_saldo = tk.Toplevel()
        ventana_saldo.title("Reitro de dinero")
        ventana_saldo.geometry("600x400")

        ##Secciones ventana Retirar
        seccionS1 = Frame (ventana_saldo,bg= "black")
        seccionS1.pack(expand=True,fill='both')
        seccionS2 = Frame (ventana_saldo,bg= "black")
        seccionS2.pack(expand=True,fill='both')
        seccionS3 = Frame (ventana_saldo,bg= "black")
        seccionS3.pack(expand=True,fill='both')

        ##Textos ventana Retirar
        txtSe= Label(seccionS1,text="Consultar saldo",bg= "black", fg="orange")
        txtSe.configure(font=("arial", 14))
        txtSe.place(width="650", height="80")
        txtSNoc= Label(seccionS2,text="Numero de cuenta: ",bg= "black", fg="orange")
        txtSNoc.configure(font=("arial",10))
        txtSNoc.place(x=90,y=40)
        txtSNIP= Label(seccionS2,text="Ingresa tu NIP: ",bg= "black", fg="orange")
        txtSNIP.configure(font=("arial",10))
        txtSNIP.place(x=90,y=80)

        ##cuadros ventana Retirar
        NoCu= Entry(seccionS2, bg="#F3F3F3")
        NoCu.place(x=220, y=43)
        Connip= Entry(seccionS2, bg="#F3F3F3")
        Connip.place(x=200, y=80)

        def Consultar():

            NoCuDep = NoCu.get()
            Gnip  = Connip.get()
            consultaS.Consu(NoCuDep,Gnip)

        ##Botones ventana Retirar
        botonDepo = Button(seccionS3,text="Consultar", fg= "black", bg="orange", command= Consultar)
        botonDepo.place(x=90, y=40)
        botonDepo = Button(seccionS3,text="Regresar", fg= "black", bg="orange", command= ventana_saldo.destroy)
        botonDepo.place(x=180, y=40)

ventana= Tk()
consultaS = banco()
ventana.geometry("600x400")
ventana.title("Banco del Frank")

##Secciones
seccion1= Frame(ventana,bg= "black")
seccion1.pack(expand=True,fill='both')

seccion2= Frame(ventana,bg= "black")
seccion2.pack(expand=True,fill='both')

seccion3= Frame(ventana, bg="black")
seccion3.pack(expand=True,fill='both')

##Textos
txtinicio= Label(seccion1,text="Bienvenido a FB",bg= "black", fg="orange")
txtinicio.configure(font=("arial", 14))
txtinicio.place(width="650", height="80")

txtinicio= Label(seccion2,text="Indica que accion deseas realizar",bg= "black", fg="orange")
txtinicio.configure(font=("arial", 14))
txtinicio.place(width="650", height="80")

botonDepo = Button(seccion3,text="Depositar", fg= "black", bg="orange", command = depositar )
botonDepo.place(x=90, y=40)

botonRet = Button(seccion3,text="Retirar", fg= "black", bg="orange", command = retirar)
botonRet.place(x= 300, y=40)

botonCon = Button(seccion3,text="Consultar saldo", fg= "black", bg="orange", command = Saldo)
botonCon.place(x= 500, y=40)

ventana.mainloop()


from __future__ import print_function

import numpy as np
import cv2

import alpha_utils as au
import rotator
from .utils import compatible_contours

def degrees_interp(x, alpha, beta):
    """ convex combination of two angles
    x is list of combination coefficients from [0, 1]; alpha and beta angles in degrees. Picks the shorter arc. """
    # get both angles to positive values
    alpha = (alpha + 360) % 360
    beta  = (beta + 360) % 360

    diff = abs(beta-alpha)
    if diff >= 180:
        if alpha > beta:
            alpha = alpha - 360
        else:
            beta = beta - 360

    return np.interp(x, [0, 1], [alpha, beta])

def transform_H(H, coords):
    homo = np.array([[coords[0]],
                     [coords[1]],
                     [1]])

    proj = np.matmul(H, homo)
    proj = np.array((proj[0] / proj[2],
                     proj[1] / proj[2]))
    proj = np.squeeze(proj)

    return proj

def motion_blur(img, pre_angles, angles, post_angles, xs, ys, n_steps=100, vis_animation=False):
    """Motion blur an object

    The object is blurred by a 3D rotation and an in-image translation
    using rotator.rotate.

    Args:
    img: [H x W x 4] BGRA uint8 image
    pre_angles: (begin, end) angles in degrees, corresponding to rotate() angle_in parameter
    angles: (begin, end) angles in degrees, corresponding to rotate() angle parameter
    post_angles: (begin, end) angles in degrees, corresponding to rotate() angle_post parameter
    xs: (begin, end) pixel coordinates for translation blur
    ys: (begin, end) pixel coordinates for translation blur
    n_steps: number of interpolation steps
    vis_animation: True if the underlying object animation should be shown (default: False)

    Outputs:
    canvas: [H' x W' x 4] BGRA uint8 image with the blurred object
    GT_canvas: [H' x W'] uint8 image with the GT object mask in the middle of the motion
    GT_H: the object homography corresponding to the GT_canvas
    homographies: list of homographies from object image frame to the canvas frame (n_steps long)
    """
    ## find object center
    mask = img[..., 3]
    moments = cv2.moments(mask)
    center = (int(moments['m10'] / moments['m00']),
              int(moments['m01'] / moments['m00']))

    ## interpolate the pose
    start_angles = (pre_angles[0], angles[0], post_angles[0])
    end_angles   = (pre_angles[1], angles[1], post_angles[1])

    start_xy = (xs[0], ys[0])
    end_xy   = (xs[1], ys[1])

    interp_xs = np.linspace(0, 1, n_steps)
    angles = [degrees_interp(interp_xs, start_angles[i], end_angles[i]) for i in range(len(start_angles))]
    xys = (np.interp(interp_xs, [0, 1], [start_xy[0], end_xy[0]]),
           np.interp(interp_xs, [0, 1], [start_xy[1], end_xy[1]]))

    xys = zip(*xys)
    angles = zip(*angles)

    for i in range(len(angles)):
        angles[i] = (angles[i], xys[i])

    ## rotate the object in all of the steps
    steps = []
    for i, ((angle, pre_angle, post_angle), (x, y)) in enumerate(angles):
        rot, H = rotator.rotate(img,
                                angle=angle, angle_in=pre_angle, angle_post=post_angle,
                                fit_in=True, return_H=True)

        ## compute the object's center in the rotated image
        new_center = transform_H(H, center)

        # the translation is done by virtually translating the
        # object's center to the opposite side
        center_shift = -np.array((x, y))
        new_center += center_shift

        new_center = new_center.astype(np.int)

        steps.append({'img': rot, 'center': new_center,
                      'shift': center_shift, 'H': H})

    ## now we have the object rotated, but the coordinate system is
    ## different in each image.  This will be unified now.
    # First, collect the extents of the final blurred image
    central_origin = (0, 0)
    extremes = {'left': 0, 'right': 0, 'top': 0, 'bottom': 0}
    for step in steps:
        img, shift = step['img'], step['shift']

        left = 0 + shift[0]
        right = img.shape[1] + shift[0]
        top = 0 + shift[1]
        bottom = img.shape[0] + shift[1]

        if left < extremes['left']:
            extremes['left'] = left
        if right > extremes['right']:
            extremes['right'] = right
        if top < extremes['top']:
            extremes['top'] = top
        if bottom > extremes['bottom']:
            extremes['bottom'] = bottom

    # The global coordinates and the canvases are created
    top_left = (extremes['left'], extremes['top'])
    new_h, new_w = (extremes['bottom'] - extremes['top'],
                    extremes['right'] - extremes['left'])
    new_h, new_w = int(np.ceil(new_h)), int(np.ceil(new_w))

    canvas = np.zeros((new_h, new_w, 4), dtype=np.float32)
    GT_canvas = np.zeros((new_h, new_w), dtype=np.float32)

    GT_frame = len(steps) / 2

    blur_homographies = []
    ## Finally, the blurring is done by taking average of the images
    for i, step in enumerate(steps):
        img = step['img']
        h, w = img.shape[:2]

        total_shift = step['shift'] - np.array(top_left)

        H = step['H'].copy()

        shift_H = np.eye(3)
        shift_H[:2, 2] = total_shift
        H = np.matmul(shift_H, H)

        blur_homographies.append(H)

        current_corner = np.ceil(total_shift).astype(np.int)

        canvas[current_corner[1]:current_corner[1]+h,
               current_corner[0]:current_corner[0]+w,
               :] += img

        if i == GT_frame:
            GT_canvas[current_corner[1]:current_corner[1]+h,
                      current_corner[0]:current_corner[0]+w] = np.squeeze(img[..., 3])
            GT_H = H

        if vis_animation:
            H_center = transform_H(H, center).astype(np.int)
            local_canvas = np.zeros((new_h, new_w, 4), dtype=np.uint8)
            local_canvas[current_corner[1]:current_corner[1]+h,
                         current_corner[0]:current_corner[0]+w,
                         :] = img
            local_canvas[H_center[1],
                         H_center[0], :] = np.array([0, 0, 255, 255]).T

            cv2.imshow("cv: animation", local_canvas)
            c = cv2.waitKey(0)
            if c == ord('q'):
                import sys
                sys.exit(1)

    canvas /= len(steps)
    ## visualize motion centers
    # for H in blur_homographies:
    #     H_center = transform_H(H, center)
    #     H_center = np.ceil(H_center).astype(np.int)
    #     canvas[H_center[1],
    #            H_center[0],
    #            :] = (0, 0, 255, 255)

    return canvas.astype(np.uint8), GT_canvas.astype(np.uint8), GT_H, blur_homographies

def main():
    obj_img = cv2.imread('/home/jonas/dev/thesis/synth_rot/images/tux.png', cv2.IMREAD_UNCHANGED)

    start_angles = (0, 0, 0)
    end_angles = (75, 0, 0)

    start_xy = (0, 0)
    end_xy   = (135, 250)

    blurred, blurred_mask, GT_H, Hs = motion_blur(obj_img,
                                                  pre_angles=(start_angles[0], end_angles[0]),
                                                  angles=(start_angles[1], end_angles[1]),
                                                  post_angles=(start_angles[2], end_angles[2]),
                                                  xs=(start_xy[0], end_xy[0]),
                                                  ys=(start_xy[1], end_xy[1]),
                                                  n_steps=60,
                                                  vis_animation=False)

    ret, thresh = cv2.threshold(blurred_mask,127,255,0)
    contours = compatible_contours(thresh)
    cnt = contours[0]
    cv2.drawContours(blurred, [cnt], 0, (0,0,255,255), 1)

    cv2.imshow("mask", blurred_mask)
    cv2.imshow("blurred blend", au.transparent_blend(blurred))
    cv2.imshow("blurred", blurred)
    c = cv2.waitKey(0)

if __name__ == '__main__':
    main()


import csv
import glob
import math
import os
import shutil
from copy import deepcopy
from datetime import datetime
from pathlib import Path
from typing import Callable, Tuple, Any, List, Optional, Union

import cv2
import numpy as np
from PIL import Image
from PyQt5.QtCore import Qt, QCoreApplication, QSize
from PyQt5.QtGui import QFont, QDoubleValidator
from PyQt5.QtWidgets import QMainWindow, QFileDialog, QMessageBox, QFileSystemModel, QWidget, QLabel, QVBoxLayout, \
    QProgressBar, QSizePolicy, QStatusBar, QDockWidget, QSplitter, QGroupBox, QGridLayout, QSpacerItem, \
    QPushButton, QTreeView, QFrame, QTabBar
from matplotlib import pyplot as plt
from scipy.optimize import curve_fit, minimize_scalar, root_scalar
from scipy.signal import argrelextrema

import src
from src.interface_setup import plotControl, fftControl
from src.matplotlibWidget import fft_graphic_widget, matplotlibWidget
from src.postprocessing.csvReader import csvReader
from src.postprocessing.fft_analysis import FFTAnalysis
from src.ui_mainwindow import Ui_MainWindow
from src.utils import create_rounded_pixmap, signature, printText
from src.utils.utilities import draw_ruler

class MainWindow(QMainWindow, Ui_MainWindow):
    _project_directory: str = ''
    _data_path: str = ''
    _project_name: str = ''
    _csv_data_path: str = ''
    _running: bool = False
    progressBar: QProgressBar = None
    _label_left: list = []
    _label_right: list = []
    _slip_data: list = []

    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.add_progress_bar()

        self.file_model = QFileSystemModel()
        self.file_model.setRootPath("")
        self.file_list.setModel(self.file_model)
        self.file_list.setRootIndex(self.file_model.index(""))

        self.post_dock_widget = QDockWidget("Postprocessing control", self)
        self.set_post_widget()
        self.post_dock_widget.close()

        self.__set_connections()

    def __set_connections(self) -> None:
        self.tabWidget.setStyleSheet(src.QSS_Q_TAB_WIDGET)

        self.source_gbox.setStyleSheet(src.QSS_Q_GROUP)
        self.options_gbox.setStyleSheet(src.QSS_Q_GROUP)
        self.advanced_options_gbox.setStyleSheet(src.QSS_Q_GROUP)

        self.browse_file_button.clicked.connect(
            lambda: self.open_file_dialog(
                self.load_data, 'Load images', src.IMG_FILTER))

        self.preview_button.clicked.connect(self.preview)
        self.path_to_save.clicked.connect(lambda: self.open_file_dialog(
            self.directory_valid, 'Path to save', src.IMG_FILTER))

        self.start_conv.clicked.connect(self.run_conversion)
        self.stop_button.clicked.connect(self.stop_conversion)
        self.tabWidget.currentChanged.connect(self.state_changed)
        self.plot_options_gbox.plot_button.clicked.connect(self.on_plot_clicked)
        self.browse_csv.clicked.connect(lambda: self.open_file_dialog(
            self.load_csv, 'Load images', src.CSV_FILTER))

        self.fft_options_gbox.fft_plot_button.clicked.connect(
            self.plot_fft_clicked)
        self.fft_options_gbox.fft_clear_button.clicked.connect(
            self.on_clear_plot_clicked)

    @property
    def project_directory(self):
        """ Property for keeping the path of the output files. """
        return self._project_directory

    @property
    def data_path(self) -> str:
        """ Property for keeping the path of images directory. """
        return self._data_path

    @property
    def project_name(self) -> str:
        """ Property for setting the default name of output file. """
        return self._project_name

    @property
    def csv_data_path(self) -> str:
        """ Property for keeping the path of csv directory. """
        return self._csv_data_path

    @project_directory.setter
    def project_directory(self, path: str):
        self._project_directory = path

    @data_path.setter
    def data_path(self, path: str):
        self._data_path = path

    @project_name.setter
    def project_name(self, name: str):
        self._project_name = name

    @csv_data_path.setter
    def csv_data_path(self, name: str):
        self._csv_data_path = name

    def state_changed(self, index) -> None:
        current_tab = self.tabWidget.tabText(index)
        self.print_message(f'Current tab view changed to: {current_tab}')
        if current_tab == 'Postprocessing':
            self.removeDockWidget(self.outputTerminal)
            self.removeDockWidget(self.option_control)
            self.addDockWidget(Qt.LeftDockWidgetArea, self.post_dock_widget)
            self.addDockWidget(Qt.LeftDockWidgetArea, self.outputTerminal)
            self.post_dock_widget.show()
            self.outputTerminal.show()
        else:
            self.removeDockWidget(self.outputTerminal)
            self.removeDockWidget(self.post_dock_widget)
            self.addDockWidget(Qt.LeftDockWidgetArea, self.option_control)
            self.addDockWidget(Qt.LeftDockWidgetArea, self.outputTerminal)
            self.option_control.show()
            self.outputTerminal.show()

    def directory_valid(self, fname: str) -> None:
        if not os.path.exists(fname):
            os.makedirs(fname)

        # Set path to save output files
        self.project_directory = fname
        self.path_line_edit.setText(fname)

    def load_csv(self, fname: str) -> None:
        """Load directory with the given `fname`."""
        basename = os.path.basename(fname)

        if len(os.listdir(fname)) == 0:
            QMessageBox.warning(
                self, src.PROJ_NAME,
                f'The folder "{basename}" is empty.\n' +
                'Operation aborted.')
            return

        # Assign chosen path to data_path attribute and project_name
        self.csv_data_path = fname

        self.csv_file_model.setRootPath(fname)
        self.csv_file_model.setNameFilters(["*.csv"])
        self.csv_file_model.setNameFilterDisables(False)
        self.csv_list.setRootIndex(self.csv_file_model.index(fname))

    def load_data(self, fname: str) -> None:
        """Load directory with the given `fname`."""
        basename = os.path.basename(fname)

        if len(os.listdir(fname)) == 0:
            QMessageBox.warning(
                self, src.PROJ_NAME,
                f'The folder "{basename}" is empty.\n' +
                'Operation aborted.')
            return

        # Assign chosen path to data_path attribute and project_name
        self.data_path = fname
        self.project_name = basename

        self.file_model.setRootPath(fname)
        self.file_model.setNameFilters(["*.png"])
        self.file_model.setNameFilterDisables(False)
        self.file_list.setRootIndex(self.file_model.index(fname))

    def add_progress_bar(self):
        statusBar = QStatusBar()
        self.setStatusBar(statusBar)
        self.progressBar = QProgressBar()

        self.progressBar.setMaximum(100)
        self.progressBar.setMinimum(0)

        statusBar.addWidget(self.progressBar, 1)  # Add progress bar with stretch factor 1
        statusBar.setSizeGripEnabled(False)
        self.progressBar.setMaximumHeight(15)
        self.progressBar.setMaximumWidth(300)

        self.progressBar.setStyleSheet(src.QSS_PROGRESS)
        self.progressBar.hide()

    def stop_conversion(self):
        self._running = False

    def run_conversion(self) -> None:
        """ Runs the conversion process for all images available in chosen directory. """

        self._slip_data.clear()  # Reset content of slip data list
        if os.path.exists(self.data_path) is False:
            QMessageBox.warning(
                self, src.PROJ_NAME,
                'First you have to select directory containing data.\n' +
                'Operation aborted.')
            return

        if len(os.listdir(self.data_path)) == 0:
            QMessageBox.warning(
                self, src.PROJ_NAME,
                f'The folder "{self.data_path}" is empty.\n' +
                'Operation aborted.')
            return

        if os.path.exists(self.project_directory) is False:
            QMessageBox.warning(
                self, src.PROJ_NAME,
                'You have to select directory to save the files.\n' +
                'Operation aborted.')
            return

        self._running = True
        self.output_panel.clear()
        self.print_message(f'Conversion process started: {datetime.now().time()}')
        self.progressBar.show()

        try:
            conv_data = self._run_conversion()
            if conv_data[0]:
                # csv writer
                self.export_to_csv(conv_data[0], conv_data[1], conv_data[2], conv_data[3], conv_data[4])

        except Exception as e:
            QMessageBox.warning(
                self, src.PROJ_NAME,
                f'Error while converting:\n' +
                f'{e}')
            self.print_message(f'\n\nERROR: Operation failed:\n {e}')

        self.progressBar.hide()

    def _run_conversion(self) -> Tuple[List[Any], List[Any], List[Any], List[Any]]:
        if os.path.exists(src.TEMP_DIR):
            shutil.rmtree(src.TEMP_DIR)
        os.mkdir(src.TEMP_DIR)

        converted_dir = os.path.join(src.TEMP_DIR, 'converted')
        if not os.path.exists(converted_dir):
            os.mkdir(converted_dir)
        else:
            shutil.rmtree(converted_dir)
            os.mkdir(converted_dir)

        frame = []
        paths = []
        for path in Path(self.data_path).glob("*.png"):
            frame.append(int(str(path)[-9] + str(path)[-8] + str(path)[-7] + str(path)[-6] + str(path)[-5]))
            paths.append(str(path))

        leftAngle = []
        rightAngle = []
        contactLength = []
        crossSectionArea = []
        for i in range(len(frame)):
            if not self._running:
                self.print_message(f'\n\nWARNING: Operation aborted by the user.')
                break
            self.print_message(f'{[i]} - Converting: {paths[i]}')
            self.progressBar.setValue(int(i / len(frame) * 100))

            ret_img = self.binary_threshold(paths[i])
            pure_image = self.partial_filter(paths[i])
            ret_img_copy = deepcopy(ret_img)
            cont_img, cont_obj = self.contour_detecting(ret_img_copy)
            # remove pure_image from args list to avoid saving converted images
            result_img, ret_1, ret_2, ret_3, ret_4 = \
                self.interpolate_polynomials(cont_img, cont_obj, True, pure_image)
            leftAngle.append(ret_1)
            rightAngle.append(ret_2)
            contactLength.append(ret_3)
            contactLength.append(ret_3)
            crossSectionArea.append(ret_4)

            if self.on_fly_preview.isChecked():
                # Manage the existing widgets to avoid window size adjusting
                while self.img_view_layout.count():
                    item = self.img_view_layout.takeAt(0)
                    widget = item.layout()
                    if widget:
                        widget.setParent(None)
                        widget.deleteLater()
                self.set_photo(path=paths[i], qlabel=self.ren_win_1)
                self.set_photo(img=ret_img, qlabel=self.ren_win_2)
                self.set_photo(img=cont_img, qlabel=self.ren_win_3)
                self.set_photo(img=result_img, qlabel=self.ren_win_4)

            if self.make_gif.isChecked():
                path_to_save = f'{src.TEMP_DIR}/' + paths[i][-23:]
                cv2.imwrite(str(path_to_save), result_img)  # type: ignore

                path_to_save = os.path.join(src.TEMP_DIR, 'converted', paths[i][-23:])
                cv2.imwrite(str(path_to_save), pure_image)

            # Process pending events to keep the GUI responsive
            QCoreApplication.processEvents()

        time = [frame_ / self.fps.value() for frame_ in frame]
        slip_data = [x - self._slip_data[0] for x in self._slip_data]
        self.export_to_csv(time, slip_data)
        plt.plot(time, slip_data)
        plt.show()

        if self._running:
            self.progressBar.setValue(100)
            self.print_message(f'\n\nSuccessfully converted {len(paths)} files.')

            # Manage creating GIF - output
            if self.make_gif.isChecked():
                self.create_gif()
                self.print_message(f'\nGIF file has been created.')

            self.print_message(f'\nOutput folder: {self.project_directory}/{self.project_name}')

            return time, leftAngle, rightAngle, contactLength, crossSectionArea

        return [], [], [], []

    @staticmethod
    def partial_filter(path):
        img = cv2.imread(path, cv2.IMREAD_GRAYSCALE)  # type: ignore
        return img

    def export_to_csv(
            self, list_1: list = None,
            list_2: list = None,
            list_3: list = None,
            list_4: list = None,
            list_5: list = None) -> None:

        args = [list_1, list_2, list_3, list_4, list_5]
        if None not in args:
            rows = zip(list_1, list_2, list_3, list_4, list_5)
            name = self.project_name
            with open(f'{self.project_directory}/{name}.csv', 'w', newline='') as file:
                writer = csv.writer(file)
                writer.writerow(['Time', 'Left Angle', 'Right Angle', 'Contact Length', 'Cross Section Area'])
                writer.writerows(rows)
        else:
            rows = zip(list_1, list_2)
            name = self.project_name
            with open(f'{self.project_directory}/{name}_slip.csv', 'w', newline='') as file:
                writer = csv.writer(file)
                writer.writerow(['Time', 'l0'])
                writer.writerows(rows)

    def preview(self):
        first_index = self.file_model.index(0, 0, self.file_list.rootIndex())
        first_file_path = self.file_model.filePath(first_index)

        _, extension = os.path.splitext(first_file_path)
        if extension.lower() != '.png':
            QMessageBox.warning(
                self, src.PROJ_NAME,
                'First you have to select directory containing data.\n' +
                'Operation aborted.')
            return

        image_path = first_file_path
        selected_item = None
        if self.file_list.selectedIndexes():
            for index in self.file_list.selectedIndexes():
                selected_item = self.file_model.filePath(index)
            image_path = selected_item

        while self.img_view_layout.count():
            item = self.img_view_layout.takeAt(0)
            widget = item.layout()
            if widget:
                widget.setParent(None)
                widget.deleteLater()

        self.image_view_tab.setStyleSheet(src.QSS_Q_TAB_WIDGET)
        self.set_photo(path=image_path, qlabel=self.ren_win_1)

        ret_img = None
        if self.raw_image.isChecked():
            ret_img = self.binary_threshold(image_path)
            self.set_photo(qlabel=self.ren_win_2, img=ret_img)
        else:
            self.set_photo(f'{src.RES_DIR}/background.png', self.ren_win_2)

        cont_img = None
        if self.raw_contour.isChecked() and ret_img is not None:
            try:
                cont_img, contour = self.contour_detecting(ret_img)  # type: ignore
            except Exception as e:
                QMessageBox.warning(
                    self, src.PROJ_NAME,
                    f'Error while converting:\n' +
                    f'{e}')
                self.print_message(f'\n\nERROR: Operation failed:\n {e}')

            self.set_photo(qlabel=self.ren_win_3, img=cont_img)
        else:
            self.set_photo(f'{src.RES_DIR}/background.png', self.ren_win_3)

        result_img = None
        if self.result_data.isChecked() and cont_img is not None:
            try:
                result_img = self.interpolate_polynomials(cont_img, contour)  # noqa
            except Exception as e:
                QMessageBox.warning(
                    self, src.PROJ_NAME,
                    f'Error while converting:\n' +
                    f'{e}')
                self.print_message(f'\n\nERROR: Operation failed:\n {e}')

            if self.invert.currentText() == 'Yes':
                result_img = cv2.bitwise_not(result_img)  # type: ignore
            self.set_photo(qlabel=self.ren_win_4, img=result_img)
        else:
            self.set_photo(f'{src.RES_DIR}/background.png', self.ren_win_4)

    def open_file_dialog(
            self, action: Callable[[str], None],
            action_title: str, filter_: str) -> int:
        """Show file dialog to open the file and perform the *action*.

        :return: returns ACTION_OK if the action succeed or ACTION_NO
        otherwise.
        :rtype: int
        """
        fname = QFileDialog.getExistingDirectory(
            self, f'Select folder')

        if fname:
            action(fname)
            return src.ACTION_OK

        return src.ACTION_CANCEL

    @staticmethod
    def set_photo(
            path: str = None, qlabel: QLabel = None, img=None) -> None:
        if path is None:
            image = img
        else:
            image = cv2.imread(path)

        pixmap = create_rounded_pixmap(image, 15)
        qlabel.setPixmap(pixmap)

    def binary_threshold(self, path: str):
        img = cv2.imread(path, cv2.IMREAD_GRAYSCALE)  # type: ignore

        threshold = self.threshold.value()

        """ Binary thresholding """
        _, thresh = cv2.threshold(img, threshold, 255, cv2.THRESH_BINARY)  # type: ignore
        thresh = 255 - thresh

        return thresh

    def contour_detecting(self, img):
        # cutting out everything below the plate
        img[self.ground_height.value() + 1:len(img), :] = 0

        contours, _ = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)  # type: ignore
        filter_matrix = np.zeros_like(img)
        output_object = np.zeros_like(img)

        if len(contours) != 0:
            c_object = max(contours, key=cv2.contourArea)  # type: ignore
            cv2.drawContours(filter_matrix, c_object, -1, 255, 1)  # type: ignore
            cv2.fillPoly(filter_matrix, pts=[c_object], color=(255, 255, 255))  # type: ignore
            self.use_filter(filter_matrix, c_object, self.ground_height.value())  # type: ignore
            cont_filtered, _ = cv2.findContours(filter_matrix, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)  # type: ignore
            cv2.drawContours(output_object, cont_filtered, -1, 255, 1)  # type: ignore

        output_object[self.ground_height.value(), :] = 125
        # Draw ruler representing interpolation range
        draw_ruler(output_object, self.interpolation_range.value(), 5, (15, self.ground_height.value()))

        return output_object, cont_filtered

    @staticmethod
    def use_filter(img, contour, init_height):
        # Initialize min and max x-coordinates with the first point
        min_x = contour[0][0][0]
        max_x = contour[0][0][0]

        # Iterate over the remaining points and update min and max x-coordinates
        for point in contour:
            x = point[0][0]
            if x < min_x:
                min_x = x
            if x > max_x:
                max_x = x

        height = init_height
        right_corn_coord = (max_x - 60, height - 40)

        # Todo: Think about how it should work using PointPolygonTest
        cv2.rectangle(img, (min_x + 60, init_height), right_corn_coord, 255, -1)  # type: ignore

    def interpolate_polynomials(
            self, img, contour_object, ret: bool = False, pure_img: Optional[np.ndarray] = None):
        pixels = np.argwhere(img == 255)
        x = (pixels[:, 1])
        y = (pixels[:, 0])

        # Selecting set of points on which the spline will be spanned
        x, y = zip(*sorted(zip(x, y)))

        x_select = x[0:len(x):1]
        y_select = y[0:len(y):1]
        y_select = np.asarray(y_select)
        x_select = np.asarray(x_select)

        int_thresh = self.ground_height.value() - \
                     self.interpolation_range.value()

        y_cutoff_ids = np.where(y_select > int_thresh)
        x_split = x_select[np.argmin(y_select)]
        y_select = y_select[y_cutoff_ids]
        x_select = x_select[y_cutoff_ids]

        # split points to left and right groups in order to create separate polynomials
        idx_left = np.where(x_select < x_split)
        y_left = y_select[idx_left]
        x_left = x_select[idx_left]
        idx_right = np.where(x_select > x_split)
        y_right = y_select[idx_right]
        x_right = x_select[idx_right]

        z_left = np.polyfit(y_left, x_left, self.interpolation_deg.value())
        p_left = np.poly1d(z_left)

        z_right = np.polyfit(y_right, x_right, self.interpolation_deg.value())
        p_right = np.poly1d(z_right)

        # calculate derivatives and use them to get the angle
        dp_left = np.polyder(p_left, 1)
        angle_left = np.pi / 2 + np.arctan(dp_left(max(y_left)))

        dp_right = np.polyder(p_right, 1)
        angle_right = np.pi - (np.pi / 2 + np.arctan(dp_right(max(y_right))))

        # draw tangent lines
        line_len = 150
        line_thickness = 1

        img_copy = np.zeros_like(img)
        p1 = np.array([x_left[np.argmax(y_left)], max(y_left)])
        p2 = p1 + np.array([line_len * np.cos(angle_left), -line_len * np.sin(angle_left)])
        cv2.line(img_copy, (p1[0], p1[1]), (round(p2[0]), round(p2[1])), 255, thickness=line_thickness)  # type: ignore

        p1 = np.array([x_right[np.argmax(y_right)], max(y_right)])
        p2 = p1 + np.array([-line_len * np.cos(angle_right), -line_len * np.sin(angle_right)])
        cv2.line(img_copy, (p1[0], p1[1]), (round(p2[0]), round(p2[1])), 255, thickness=line_thickness)  # type: ignore

        # Make the contour bold
        for i in range(0, len(x)):
            cv2.circle(img_copy, (x[i], y[i]), radius=1, color=255, thickness=-1)  # type: ignore
        img_copy[self.ground_height.value(), :] = 125

        # Add info signature
        crossSectionArea = cv2.contourArea(max(contour_object, key=cv2.contourArea))  # type: ignore
        signature(img_copy, [10, 20], 0.4, self.fps.value())
        printText(img_copy, [math.degrees(angle_left), math.degrees(angle_right),
                             x_right[np.argmax(y_right)] - x_left[np.argmax(y_left)],
                             crossSectionArea], [10, 60], 0.4)

        left_apex = x_left[np.argmax(y_left)]
        right_apex = x_right[np.argmax(y_right)]
        self.extract_slip_data((left_apex, self.ground_height.value()), (right_apex, self.ground_height.value() - 50))

        if pure_img is not None:
            pure_img[self.ground_height.value(), :] = 125
            p1 = np.array([x_left[np.argmax(y_left)], max(y_left)])
            p2 = p1 + np.array([line_len * np.cos(angle_left), -line_len * np.sin(angle_left)])
            cv2.line(pure_img, (p1[0], p1[1]), (round(p2[0]), round(p2[1])), 255,
                     thickness=line_thickness)  # type: ignore

            p1 = np.array([x_right[np.argmax(y_right)], max(y_right)])
            p2 = p1 + np.array([-line_len * np.cos(angle_right), -line_len * np.sin(angle_right)])
            cv2.line(pure_img, (p1[0], p1[1]), (round(p2[0]), round(p2[1])), 255,
                     thickness=line_thickness)  # type: ignore

            signature(pure_img, [10, 20], 0.4, self.fps.value())
            printText(pure_img, [math.degrees(angle_left), math.degrees(angle_right),
                                 x_right[np.argmax(y_right)] - x_left[np.argmax(y_left)],
                                 crossSectionArea], [10, 60], 0.4)

        if ret:
            return img_copy, \
                   math.degrees(angle_left), \
                   math.degrees(angle_right), x_right[np.argmax(y_right)] - x_left[np.argmax(y_left)], \
                   crossSectionArea
        else:
            return img_copy

    def extract_slip_data(
            self, origin: Tuple[float, float],
            end: Tuple[float, float]) -> None:
        self._slip_data.append(origin[0])

    def print_message(self, msg: str) -> None:
        current_time = datetime.now().strftime("%H:%M:%S")
        self.output_panel.append(f'{current_time}: {msg}')

    def create_gif(self):
        if os.path.exists(src.TEMP_DIR):
            frames = [Image.open(image) for image in glob.glob(f"{src.TEMP_DIR}/*.png")]  # type: ignore
        else:
            return
        frame_one = frames[0]
        path_to_save_gif = f'{self.project_directory}/{self.project_name}.gif'
        frame_one.save(str(path_to_save_gif), format="GIF", append_images=frames,
                       save_all=True, duration=100, loop=0)

    def set_post_widget(self):
        """ Set up interface for postprocessor QDockWidget. """

        self.data_gbox = QGroupBox("Data selection")  # noqa
        self.dock_wid_cont = QWidget()  # noqa
        self.m_layout = QVBoxLayout()  # noqa
        self.m_layout.setContentsMargins(5, 5, 5, 5)

        sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.data_gbox.sizePolicy().hasHeightForWidth())
        self.data_gbox.setSizePolicy(sizePolicy)
        self.data_gbox.setMinimumSize(QSize(0, 100))
        self.data_gbox.setMaximumSize(QSize(16777215, 16777215))
        self.data_gbox.setFlat(False)
        self.data_gbox.setCheckable(False)
        self.data_gbox.setObjectName("data_gbox")
        self.m_grid_layout_1 = QGridLayout(self.data_gbox)  # noqa
        self.m_grid_layout_1.setContentsMargins(5, 5, 5, 5)
        self.m_grid_layout_1.setObjectName("m_grid_layout_1")

        font = QFont("Open Sans", 8)  # Create a QFont object with desired font properties
        self.data_gbox.setFont(font)
        self.dock_wid_cont.setFont(font)
        self.browse_csv = QPushButton(self.data_gbox)  # noqa
        self.browse_csv.setObjectName("browse_csv")
        self.browse_csv.setText('Browse')
        self.browse_csv.setFont(font)
        self.m_grid_layout_1.addWidget(self.browse_csv, 1, 1, 1, 1)
        spacerItem1 = QSpacerItem(210, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
        self.m_grid_layout_1.addItem(spacerItem1, 1, 0, 1, 1)

        self.csv_list = QTreeView(self.data_gbox)  # noqa
        sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.csv_list.sizePolicy().hasHeightForWidth())
        self.csv_list.setSizePolicy(sizePolicy)
        self.data_gbox.setMinimumSize(QSize(0, 343))
        self.csv_list.setFrameShape(QFrame.Box)
        self.csv_list.setFrameShadow(QFrame.Sunken)
        self.csv_list.setLineWidth(1)
        self.csv_list.setObjectName("csv_list")
        self.m_grid_layout_1.addWidget(self.csv_list, 0, 0, 1, 2)

        self.csv_file_model = QFileSystemModel()  # noqa
        self.csv_file_model.setRootPath("")
        self.csv_list.setModel(self.csv_file_model)
        self.csv_list.setRootIndex(self.csv_file_model.index(""))
        self.csv_list.setFont(font)

        self.plot_options_gbox = plotControl(self.dock_wid_cont)  # noqa
        self.plot_options_gbox.setTitle('Plot controls')
        self.plot_options_gbox.setStyleSheet(src.QSS_Q_GROUP)
        self.data_gbox.setStyleSheet(src.QSS_Q_GROUP)

        self.fft_options_gbox = fftControl(self.dock_wid_cont)  # noqa
        self.fft_options_gbox.setTitle('FFT analysis')
        self.fft_options_gbox.setStyleSheet(src.QSS_Q_GROUP)
        self.post_tabWidget.setStyleSheet(src.QSS_Q_CHILD_TAB_WIDGET)

        splitter_top = QSplitter(Qt.Vertical)  # Create a splitter
        splitter_top.addWidget(self.data_gbox)
        splitter_top.addWidget(self.plot_options_gbox)
        splitter_top.addWidget(self.fft_options_gbox)
        self.m_layout.addWidget(splitter_top)

        float_validator = QDoubleValidator(0.0, 100.0, 4)
        self.fft_options_gbox.motion_freq.setValidator(float_validator)

        self.dock_wid_cont.setLayout(self.m_layout)
        self.post_dock_widget.setWidget(self.dock_wid_cont)
        self.m_layout.setContentsMargins(0, 0, 0, 0)
        self.dock_wid_cont.setContentsMargins(2, 2, 2, 2)

    @staticmethod
    def asymptotic_func(x, a: float, b: float):
        return a + b / x

    def fit_curve(self, data: csvReader):
        """ Fits asymptotic curve. """
        idx = np.where(np.asarray(data.dContact_length) > 1)

        time, val = np.asarray(data.time)[idx], np.asarray(data.dContact_length)[idx]
        popt, _ = curve_fit(self.asymptotic_func, time, val)  # noqa

        a_opt, b_opt = popt
        x_data = np.linspace(
            min(time),
            max(data.time[0:len(data.dContact_length)]),
            100)
        y_data = self.asymptotic_func(x_data, a_opt, b_opt)

        top_range = 200
        thresh = 0.9

        def line(x):
            return thresh * a_opt

        def diff_function(x, a, b):
            return self.asymptotic_func(x, a, b) - line(x)

        result = root_scalar(diff_function, args=(a_opt, b_opt), bracket=[0, top_range])

        x_intersection = 0
        y_intersection = 0
        if result.converged:
            x_intersection = result.root
            y_intersection = line(x_intersection)
            self.print_message(f"Intersection point found: ({x_intersection},{y_intersection})")
        else:
            self.print_message('WARNING: Intersection not found!')

        return a_opt, b_opt, x_data, y_data, x_intersection, y_intersection

    def plot(self, path: str) -> None:
        data = csvReader(path, self.plot_options_gbox.avg_scope.value())
        ax1, ax2, ax3 = self.pltWidget.axes

        # Clear data stored in axes
        for _ax in self.pltWidget.axes:
            _ax.clear()

        line_1, = ax1.plot(data.time, data.left_angle, label='Left angle', color='navy',
                           linewidth=self.plot_options_gbox.line_width.value())
        line_2, = ax2.plot(data.time, data.right_angle, label='Right angle', color='deepskyblue',
                           linewidth=self.plot_options_gbox.line_width.value())  # noqa

        line_3, = ax1.plot(data.time, [data.left_static_angle for x in data.left_angle],
                           color='navy', linestyle=(0, (5, 5)),
                           linewidth=self.plot_options_gbox.line_width.value(),
                           label=f'Static angle={data.left_static_angle}')  # noqa
        line_4, = ax2.plot(data.time, [data.right_static_angle for x in data.right_angle],
                           color='navy', linestyle=(0, (5, 5)),
                           linewidth=self.plot_options_gbox.line_width.value(),
                           label=f'Static angle={data.right_static_angle}')  # noqa

        a_opt, b_opt, x_asymptote, y_asymptote, expected_time, expected_val = self.fit_curve(data)

        line_5, = ax3.plot(
            data.time[0:len(data.dContact_length)], data.dContact_length, marker='.',
            label='Raw data', color='#5500ffff', markersize=0.1)  # noqa

        domain = np.asarray(data.time[0:len(data.dContact_length)])
        _data = np.asarray(data.dContact_length)

        # idx = argrelextrema(_data, np.greater)
        # local_maxima = _data[idx]
        # ax3.plot(domain[idx], local_maxima, 'o')

        line_6, = ax3.plot(
            x_asymptote, y_asymptote,
            label=f'asymptotic fun: y = a + b/x, '
                  f'(a={round(a_opt, 2)}, '
                  f'b={round(b_opt, 2)})',
            color='navy', linewidth=1)  # noqa
        line_7, = ax3.plot([min(data.time), max(data.time)], [a_opt, a_opt],
                           label=f'Lim value of target function (x->inf): {round(a_opt, 2)}',
                           linestyle='dashed', linewidth=1, color='black')

        text = f"Time to reach 90% of lim value: {round(expected_time, 3)} [s]"
        ax3.text(0, 5, text, fontsize=7,
                 bbox=dict(facecolor='yellow', edgecolor='black', boxstyle='round,pad=0.5'))

        ax1.legend(handles=[line_1, line_3])
        ax2.legend(handles=[line_2, line_4])
        ax3.legend(handles=[line_5, line_6, line_7], fontsize=7, loc='upper left')

        ax1.grid(visible=True, which='both', linestyle='--', linewidth='0.25')
        ax2.grid(visible=True, which='both', linestyle='--', linewidth='0.25')
        ax3.grid(visible=True, which='both', linestyle='--', linewidth='0.25')

        ax1.set(xlabel="time [s]", ylabel="Angle [degrees]")
        ax2.set(xlabel="time [s]", ylabel="Angle [degrees]")
        ax3.set(xlabel="time [s]", ylabel="dL [pixels]")

        ax3.set_ylim([self.plot_options_gbox.dl_min.value(),
                      self.plot_options_gbox.dl_max.value()])
        ax1.set_title(self.plot_options_gbox.title_line.text())

    def on_plot_clicked(self) -> None:
        """ Plotting raw data in 'Raw data' tab. """
        first_index = self.csv_file_model.index(0, 0, self.csv_list.rootIndex())
        first_file_path = self.csv_file_model.filePath(first_index)

        data_path = first_file_path
        selected_item = None
        if self.csv_list.selectedIndexes():
            for index in self.csv_list.selectedIndexes():
                selected_item = self.csv_file_model.filePath(index)
            data_path = selected_item

        _, extension = os.path.splitext(data_path)
        if extension.lower() != '.csv':
            QMessageBox.warning(
                self, src.PROJ_NAME,
                'First you have to select directory containing CSV data.\n' +
                'Operation aborted.')
            return

        self.print_message(f'CSV file path: {data_path}')

        try:
            self.switch_to_tab("Raw data")
            self.plot(data_path)
            self.pltWidget.canvas.draw()
            self.print_message('INFO: Plot has been generated.')
        except Exception as e:
            QMessageBox.warning(
                self, src.PROJ_NAME,
                'Error while generating plot.\n' +
                f'{e}')
            self.print_message(str(e))
            return

    def plot_fft_clicked(self) -> None:
        first_index = self.csv_file_model.index(0, 0, self.csv_list.rootIndex())
        first_file_path = self.csv_file_model.filePath(first_index)

        data_path = first_file_path
        selected_item = None
        if self.csv_list.selectedIndexes():
            for index in self.csv_list.selectedIndexes():
                selected_item = self.csv_file_model.filePath(index)
            data_path = selected_item

        _, extension = os.path.splitext(data_path)
        if extension.lower() != '.csv':
            QMessageBox.warning(
                self, src.PROJ_NAME,
                'First you have to select directory containing CSV data.\n' +
                'Operation aborted.')
            return

        self.print_message(f'CSV file path: {data_path}')

        try:
            self.switch_to_tab("FFT Analysis")
            self.plot_fft(data_path)
            self.fftWidget.canvas.draw()
            self.print_message('INFO: FFT plot has been generated.')

        except Exception as e:
            self.print_message(str(e))
            QMessageBox.warning(
                self, src.PROJ_NAME,
                'Error while generating plot.\n' +
                f'{e}')
            return

    def plot_fft(self, path: str) -> None:
        # Fixme: Bug with plotting already existing data
        data = FFTAnalysis(
            path, self.plot_options_gbox.avg_scope.value(),
            float(self.fft_options_gbox.motion_freq.text().replace(',', '.')))

        ax1, ax2 = self.fftWidget.axes

        if data.label in self._label_left:
            return

        if self.fft_options_gbox.common_graph.isChecked():
            if self._label_left and self._label_left[0] == 'Left Angle':
                self._label_left.pop(0)
                self._label_right.pop(0)

            line_1, = ax1.plot(data.frequencies[1:], data.left_fft_values[1:],
                               label=f'Left angle:{data.label}',
                               linewidth=self.fft_options_gbox.line_width.value())
            line_2, = ax2.plot(data.frequencies[1:], data.right_fft_values[1:],
                               label=f'Right angle: {data.label}',
                               linewidth=self.fft_options_gbox.line_width.value())  # noqa
            self._label_left.append(line_1)
            self._label_right.append(line_2)

        else:
            # Clear data stored in axes
            for _ax in self.fftWidget.axes:
                _ax.clear()

            if self._label_left:
                self._label_left.pop()
                self._label_right.pop()

            line_1, = ax1.plot(data.frequencies[1:], data.left_fft_values[1:], color='navy',
                               label='Left angle', linewidth=self.fft_options_gbox.line_width.value())
            line_2, = ax2.plot(data.frequencies[1:], data.right_fft_values[1:], color='navy',
                               label='Right angle', linewidth=self.fft_options_gbox.line_width.value())  # noqa
            self._label_left.append(line_1)
            self._label_right.append(line_2)

        ax1.legend(handles=self._label_left, fontsize=8)
        ax2.legend(handles=self._label_right, fontsize=8)

        ax1.grid(visible=True, which='both', linestyle='--', linewidth='0.25')
        ax2.grid(visible=True, which='both', linestyle='--', linewidth='0.25')

        ax1.set(xlabel="Normalised frequency", ylabel="Amplitude")
        ax2.set(xlabel="Normalised frequency", ylabel="Amplitude")

        ax1.minorticks_on()  # Enable minor x-axis ticks
        ax2.minorticks_on()  # Enable minor x-axis ticks

        ax1.set_xlim([
            self.fft_options_gbox.freq_min.value(),
            self.fft_options_gbox.freq_max.value()])
        ax2.set_xlim([
            self.fft_options_gbox.freq_min.value(),
            self.fft_options_gbox.freq_max.value()])

        ax1.set_title(self.fft_options_gbox.title_line.text())

    def switch_to_tab(self, tab_name: str) -> None:
        """ Find the index of the tab by its name. """
        if tab_name == "FFT Analysis":
            self.post_tabWidget.setCurrentIndex(1)
        else:
            self.post_tabWidget.setCurrentIndex(0)
        self.post_tabWidget.update()

    def on_clear_plot_clicked(self):
        self._label_left.clear()
        self._label_right.clear()
        try:
            # Clear data stored in axes
            for _ax in self.fftWidget.axes:
                _ax.clear()
            self.print_message('INFO: FFT plot cleared.')
        except Exception as e:
            self.print_message(str(e))


# -*- coding: UTF-8 -*-
import os

#--------------设置参数-----------------
CHOOSE_LIST = [0, 1]  # 设置要训练的集合 [NUMBER, ALPHABET, LOWER_ALPHABET] 下标
MAX_CAPTCHA = 4 # 设置验证码长度
#---------------------------------------

# 验证码中的字符
# string.digits + string.ascii_uppercase
NUMBER = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
ALPHABET = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U',
            'V', 'W', 'X', 'Y', 'Z']
LOWER_ALPHABET = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
                  'u', 'v', 'w', 'x', 'y', 'z']

ALL_SET = [NUMBER, ALPHABET, LOWER_ALPHABET]
ALL_CHAR_SET = []
for each in CHOOSE_LIST:
    ALL_CHAR_SET.append(ALL_SET[each])
ALL_CHAR_SET = sum(ALL_CHAR_SET, [])
ALL_CHAR_SET_LEN = len(ALL_CHAR_SET)

# 设置图像
IMAGE_HEIGHT = 60 # 设置图像高度（默认不动）
IMAGE_WIDTH = 160 # 设置图像宽度（默认不动）

# 保存路径
TRAIN_DATASET_PATH = 'dataset' + os.path.sep + 'train'
TEST_DATASET_PATH = 'dataset' + os.path.sep + 'test'
PREDICT_DATASET_PATH = 'dataset' + os.path.sep + 'predict'
CURRENT_PATH = os.path.split((os.path.realpath(__file__)))[0]


import os
import argparse
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from wordcloud import WordCloud
from utils import *

import gensim
import gensim.models.nmf
from gensim.models import CoherenceModel
from gensim.corpora.dictionary import Dictionary
from nltk.corpus import stopwords

import pickle

from gensim.topic_coherence import direct_confirmation_measure
from coherence_fix import custom_log_ratio_measure
direct_confirmation_measure.log_ratio_measure = custom_log_ratio_measure

parser = argparse.ArgumentParser()
parser.add_argument('--n_topics', type=int, default=15)
parser.add_argument('--topic_model', choices=['lda', 'nmf', 'ctm'])
parser.set_defaults(feature=False)

if __name__ == '__main__':
	args = parser.parse_args()

	comments_list = []
	for data_file in os.listdir('weekly_data'):
		loaded_comments = pd.read_csv('weekly_data/' + data_file)
		comments_list += list(loaded_comments['body'])

	if args.topic_model == 'lda':
		if not os.path.exists("results/lda_clouds"):
			os.mkdir('results/lda_clouds')
		report_file = open("results/lda_clouds/coherence.txt", 'w')

		stop_words = stopwords.words('english')
		stop_words.extend(['im','ive','dont','get','youre','would','thats',
			'really','one','also','something','even','thing','things','must',
			'cant','much','could','way','lot','got','get','go','like','th'])

		comments_words, bigram_model, trigram_model = tokenize_lda(data_cleaning(comments_list))
		comments_bow, dictionary = create_dictionary(comments_words)

		lda = gensim.models.LdaModel.load("results/LDA_model")

		cv = CoherenceModel(model=lda, texts=comments_words, dictionary=dictionary, coherence='c_v')
		report_file.write("Overall Coherence: {:.3f}\n".format(cv.get_coherence()))

		per_topic_coherence = cv.get_coherence_per_topic()
		topics_sorted_by_coherence = np.argsort(per_topic_coherence)[::-1]
		topics_sorted_by_coherence = list(topics_sorted_by_coherence)

		topics = lda.show_topics(num_topics=args.n_topics, formatted=False, num_words=20)

		cloud = WordCloud(stopwords=stop_words,background_color='white',width=800, height=400)
		for k in range(args.n_topics):
			fig = plt.figure(figsize=(20,10))
			for topic in topics:
				if topic[0] == k:
					topic_dict = dict(topic[1])
			report_file.write('Topic {} C_v: {:.3f}\n'.format(k, per_topic_coherence[k]))
			cloud.generate_from_frequencies(topic_dict, max_font_size=300)
			plt.imshow(cloud)
			plt.axis('off')
			plt.savefig("results/lda_clouds/lda_topic{}.png".format(k))
			plt.close()
			plt.clf()

		report_file.close()

	elif args.topic_model == 'nmf':
		if not os.path.exists("results/nmf_clouds"):
			os.mkdir('results/nmf_clouds')
		report_file = open("results/nmf_clouds/coherence.txt", 'w')

		stop_words = stopwords.words('english')
		stop_words.extend(['im','ive','dont','get','youre','would','thats',
			'really','one','also','something','even','thing','things','must',
			'cant','much','could','way','lot','got','get','go','like','th'])

		comments_words, bigram_model, trigram_model = tokenize_lda(data_cleaning(comments_list))
		comments_bow, dictionary = create_dictionary(comments_words)

		nmf = gensim.models.nmf.Nmf.load("results/NMF_Model/NMF_model")

		cv = CoherenceModel(model=nmf, texts=comments_words, dictionary=dictionary, coherence='c_v')
		report_file.write("Overall Coherence: {:.3f}\n".format(cv.get_coherence()))

		per_topic_coherence = cv.get_coherence_per_topic()
		topics_sorted_by_coherence = np.argsort(per_topic_coherence)[::-1]
		topics_sorted_by_coherence = list(topics_sorted_by_coherence)

		topics = nmf.show_topics(num_topics=args.n_topics, formatted=False, num_words=20)

		cloud = WordCloud(stopwords=stop_words,background_color='white',width=800, height=400)
		for k in range(args.n_topics):
			fig = plt.figure(figsize=(20,10))
			for topic in topics:
				if topic[0] == k:
					topic_dict = dict(topic[1])
			report_file.write('Topic {} C_v: {:.3f}\n'.format(k, per_topic_coherence[k]))
			cloud.generate_from_frequencies(topic_dict, max_font_size=300)
			plt.imshow(cloud)
			plt.axis('off')
			plt.savefig("results/nmf_clouds/nmf_topic{}.png".format(k))
			plt.close()
			plt.clf()

		report_file.close()

	elif args.topic_model == 'ctm':
		if not os.path.exists("results/ctm_clouds"):
			os.mkdir('results/ctm_clouds')
		report_file = open("results/ctm_clouds/coherence.txt", 'w')

		batch_size = 64
		documents = [line.strip() for line in comments_list]
		documents = documents[: len(documents) // batch_size * batch_size]
		sp = WhiteSpacePreprocessing(stopwords_language='english')
		preprocessed_documents, unpreprocessed_corpus, vocab = sp.preprocess(documents)

		with open("results/CTM_Model/training_dataset.pkl", "rb") as f:
			training_dataset = pickle.load(f)
		with open("results/CTM_Model/ctm.pkl", "rb") as f:
				ctm = pickle.load(f)

		texts = [doc.split() for doc in preprocessed_documents]

		dictionary = Dictionary()
		for key in training_dataset.idx2token.keys():
			dictionary.add_documents([[training_dataset.idx2token[key]]])

		cv = CoherenceModel(topics=ctm.get_topic_lists(20), texts=texts, dictionary=dictionary, coherence='c_v', topn=20)
		report_file.write("Overall Coherence: {:.3f}\n".format(cv.get_coherence()))

		per_topic_coherence = cv.get_coherence_per_topic()
		topics_sorted_by_coherence = np.argsort(per_topic_coherence)[::-1]
		topics_sorted_by_coherence = list(topics_sorted_by_coherence)

		stop_words = stopwords.words('english')

		topic_words = ctm.get_topics(20)
		topics = [(i, ctm.get_word_distribution_by_topic_id(i)[:20]) for i in range(len(topic_words))]

		cloud = WordCloud(stopwords=stop_words,background_color='white',width=800, height=400)
		for k in range(args.n_topics):
			fig = plt.figure(figsize=(20,10))
			for topic in topics:
				if topic[0] == k:
					topic_dict = dict(topic[1])
			report_file.write('Topic {} C_v: {:.3f}\n'.format(k, per_topic_coherence[k]))
			cloud.generate_from_frequencies(topic_dict, max_font_size=300)
			plt.imshow(cloud)
			plt.axis('off')
			plt.savefig("results/ctm_clouds/ctm_topic{}.png".format(k))
			plt.close()
			plt.clf()

		report_file.close()


def computepay(hours, rate):
    # print("In computepay", hours, rate)
    if hours > 40:
        reg = rate * hours    # regular pay
        overtp = (hours - 40.0) * (rate * 0.5) # overtime pay
        pay = reg + overtp
    else:
        pay = hours * rate
    # print("Returning", pay)
    return pay

shours = input('Enter Hours: ') # string hours
srate = input('Enter Rate: ')    # string rate
fhours = float(shours) # floating point hours
frate = float(srate)  # floating point rate

xp = computepay(fhours, frate)

print('Pay:', xp)


import time

from Salesforce.pages.LeadPage import LeadPage

class LeadAction:

    @staticmethod
    def create_new_lead():
        leadPage = LeadPage()
        leadPage.choose_leads()
        leadPage.open_new_leads()
        leadPage.open_continue_leads()
        username = leadPage.input_account_last_name()
        leadPage.input_center()
        leadPage.input_random_mobile()
        leadPage.select_marketing_channel_group()
        leadPage.select_marketing_channel()
        leadPage.click_save()
        print('lead created successfully,whose name is {0}'.format(username))
        time.sleep(5)

    @staticmethod
    def create_opptunity():
        leadPage = LeadPage()


# 최단 경로 알고리즘은 가장 짧은 경로를 찾는 알고리즘이다.
# 컴퓨터공학과에서 주로 사용하는 알고리즘은 다익스트라 최단 경로 알고리즘, 프로이드 워셜, 벨만 포드 알고리즘, 이렇게 3가지이다.
# 그리디 알고리즘과 다이나믹 프로그래밍 알고리즘이 최단 경로 알고리즘에 그대로 적용된다는 특징이 있다.

# 다익스트라(Dijkstra) 최단 경로 알고리즘은 그래프에서 여러 개의 노드가 있을 때, 특정한 노드에서 출발하여 다른 노드로 가는 각각의 최단 경로를 구해주는
# 알고리즘이다.
# 다익스트라 알고리즘은 음의 간선이 없을 때 정상적으로 동작한다.
# 다익스트라 알고리즘은 실제로 GPS 소프트웨어의 기본 알고리즘으로 채택되곤 한다.
# 다익스트라 최단 경로 알고리즘은 기본적으로 그리디 알고리즘으로 분류된다. 매번 '가장 비용이 적은 노드'를 선택해서 임의의 과정을 반복하기 때문이다.

# 알고리즘의 원리
# 1. 출발 노드를 설정한다.
# 2. 최단 거리 테이블을 초기화한다.
# 3. 방문하지 않은 노드 중에서 최단 거리가 가장 짧은 노드를 선택한다.
# 4. 해당 노드를 거쳐 다른 노드로 가는 비용을 계산하여 최단 거리 테이블을 갱신한다.
# 5. 위 과정에서 3과 4번을 반복한다.

# 다익스트라 알고리즘은 최단 경로를 구하는 과정에서 각 노드에 대한 현재까지의 '최단 거리'정보를 항상 1차원 리스트에 저장하며 리스트를 계속 갱신한다는
# 특징이 있다. 매번 현재 처리하고 있는 노드를 기준으로 주변 간선을 확인한다.

# 다익스트라 알고리즘이 진행되면서 한 단계당 하나의 노드에 대한 최단 거리를 확실히 찾는 것으로 이해할 수 있다.
# 다익스트라 최단 경로 알고리즘의 시간 복잡도는 O(V^2)이다.
# 단계마다 '방문하지 않은 노드 중에서 최단 거리가 가장 짧은 노드를 선택'하기 위해 매 단계마다 1차원 리스트의 모든 원소를 확인(순차 탐색)한다.

# 간단한 다익스트라 알고리즘 소스코드

import sys

input = sys.stdin.readline
INF = int(1e9)  # 무한을 의미하는 값으로 10억을 설정

# 노드의 개수, 간선의 개수를 입력받기
n, m = map(int, input().split())
# 시작 노드 번호를 입력받기
start = int(input())
# 각 노드에 연결되어 있는 노드에 대한 정보를 담는 리스트를 만들기
graph = [[] for i in range(n + 1)]
# 방문한 적이 있는지 체크하는 목적의 리스트를 만들기
visited = [False] * (n + 1)
# 최단 거리 테이블을 모두 무한으로 초기화
distance = [INF] * (n + 1)

# 모든 간선 정보를 입력받기
for _ in range(m):
    a, b, c = map(int, input().split())
    # a번 노드에서 b번 노드로 가는 비용이 c라는 의미
    graph[a].append((b, c))

# 방문하지 않은 노드 중에서, 가장 최단 거리가 짧은 노드의 번호를 반환
def get_smallest_node():
    min_value = INF
    index = 0  # 가장 최단 거리가 짧은 노드(인덱스)
    for i in range(1, n + 1):
        if distance[i] < min_value and not visited[i]:
            min_value = distance[i]
            index = i
    return index

def dijkstra(start):
    # 시작 노드에 대해서 초기화
    distance[start] = 0
    visited[start] = True
    for j in graph[start]:
        distance[j[0]] = j[1]
    # 시작 노드를 제외한 전체 n - 1개의 노드에 대해 반복
    for i in range(n - 1):
        # 현재 최단 거리가 가장 짧은 노들르 꺼내서, 방문 처리
        now = get_smallest_node()
        visited[now] = True
        # 현재 노드와 연결된 다른 노드를 확인
        for j in graph[now]:
            cost = distance[now] + j[1]
            # 현재 노드를 거쳐서 다른 노드로 이동하는 거리가 더 짧은 경우
            if cost < distance[j[0]]:
                distance[j[0]] = cost

# 다익스트라 알고리즘 수행
dijkstra(start)

# 모든 노드로 가기 위한 최단 거리를 출력
for i in range(1, n+1):
    # 도달할 수 없는 경우, 무한(INFINITY)이라고 출력
    if distance[i] == INF:
        print('INFINITY')
    # 도달할 수 있는 경우 거리를 출력
    else:
        print(distance[i])


from tkinter import *
from tkinter import Label
from tkinter import Text
from tkinter import messagebox

window = Tk()

# defining variables
Product_id = StringVar()
Product_name = StringVar()
Selling_price = StringVar()
Quantity = StringVar()

window.geometry("1000x400")
window.title("Inventory Management")

def insert():

    productid = Product_id.get()
    productname = Product_name.get()
    sellingprice = Selling_price.get()
    quantity = Quantity.get()
    file = open("list.txt", 'a')
    file = open("list.txt", "a")
    file.write("\t"+productid + "\t"+ "\t" +productname + "\t" + "\t"+sellingprice + "\t" + "\t"+quantity + "\n")
    messagebox.showinfo('successfull', "Data Inserted in the inventory successfully")

def show():
    file = open("list.txt", 'r')
    read = file.read()
    for a in read[::-1]:
        display.insert(0.0, a)

# label entities
IM = Label(master=window, text="Inventory Management\t", fg="black", bg="white", relief=RAISED, font=("calibry", 12))
IM.place(x=1, y=1)

Product_list = Label(master=window, text="Product List\t", fg="black", bg="white", relief=RAISED,
                     font=("arial", 12))
Product_list.place(x=230, y=1)

prod_id = Label(master=window, text="Product ID:", fg="white", bg="grey", relief=FLAT, font=("calibry", 8))
prod_id.place(x=1, y=40)
id = Entry(window, textvar=Product_id)
id.place(x=2, y=70)

prod_name = Label(master=window, text="Product Name:", fg="white", bg="grey", relief=FLAT, font=("calibry", 8))
prod_name.place(x=1, y=110)
pro_name = Entry(window, textvar=Product_name)
pro_name.place(x=2, y=140)

sell_price = Label(master=window, text="Selling Price:", fg="white", bg="grey", relief=FLAT, font=("calibry", 8))
sell_price.place(x=1, y=180)
sp = Entry(window, textvar=Selling_price)
sp.place(x=2, y=210)
quant = Label(master=window, text="Quantity:", fg="white", bg="grey", relief=FLAT, font=("calibry", 8))
quant.place(x=1, y=250)
quan = Entry(window, textvar=Quantity)
quan.place(x=2, y=280)

itemno = Label(master=window, text="Item No:\t", fg="white", bg="grey", relief=FLAT, font=("calibry", 8))
itemno.place(x=230, y=40)

prdid = Label(master=window, text="Product id:\t", fg="white", bg="grey", relief=FLAT, font=("calibry", 8))
prdid.place(x=300, y=40)

nameid = Label(master=window, text="Name:\t", fg="white", bg="grey", relief=FLAT, font=("calibry", 8))
nameid.place(x=410, y=40)

spid = Label(master=window, text="Selling Price:\t", fg="white", bg="grey", relief=FLAT, font=("calibry", 8))
spid.place(x=490, y=40)

quantid = Label(master=window, text="Quantity:\t", fg="white", bg="grey", relief=FLAT, font=("calibry", 8))
quantid.place(x=610, y=40)

# creating buttons
Insert = Button(window, relief=RAISED, text='Insert', width=8, bg="white", fg="black", command=insert)
Insert.place(x=2, y=320)

shw = Button(window, relief=RAISED, text="Show", width=8, bg="white", fg="black", command=show)
shw.place(x=70, y=320)

display = Text(window, width=58, height=20, bg='light grey')
display.place(x=230, y=70)
window.mainloop()


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

HOST = "localhost"
PORT = 4223
UID = "2hghdk" # Change XYZ to the UID of your CAN Bricklet

from pprint import pprint
import time

from tinkerforge.ip_connection import IPConnection
from tinkerforge.bricklet_can_v2 import BrickletCANV2

if __name__ == "__main__":
    ipcon = IPConnection() # Create IP connection
    can = BrickletCANV2(UID, ipcon) # Create device object

    ipcon.connect(HOST, PORT) # Connect to brickd
    # Don't use device before ipcon is connected

    #can.set_error_led_config(can.ERROR_LED_CONFIG_SHOW_ERROR)

    while True:
        try:
            print(time.time())

            for key, value in can.get_error_log()._asdict().items():
                print('{0}: {1}'.format(key, value))

            print('')

            time.sleep(2)
        except KeyboardInterrupt:
            break

    ipcon.disconnect()


import pytest
from source_amazon_seller_partner.streams import SellerFeedbackReports

def reports_stream(marketplace_id):
    stream = SellerFeedbackReports(
        url_base="https://test.url",
        replication_start_date="2010-01-25T00:00:00Z",
        replication_end_date="2017-02-25T00:00:00Z",
        marketplace_id=marketplace_id,
        authenticator=None,
        period_in_days=0,
        report_options=None,
        advanced_stream_options=None,
    )
    return stream

INPUT_DATES = {
    "YYYY-MM-DD": ["2017-01-13", "2017-12-12", "2017-12-17", "2011-12-13"],
    "D.M.YY": ["13.1.17", "12.12.17", "17.12.17", "13.12.11"],
    "YY/M/D": ["17/1/13", "17/12/12", "17/12/17", "11/12/13"],
    "D/M/YY": ["13/1/17", "12/12/17", "17/12/17", "13/12/11"],
    "M/D/YY": ["1/13/17", "12/12/17", "12/17/17", "12/13/11"],
}
EXPECTED_DATES = ["2017-01-13", "2017-12-12", "2017-12-17", "2011-12-13"]

def parametrize_seller_feedback():
    result = []
    for marketplace_id, date_format in SellerFeedbackReports.MARKETPLACE_DATE_FORMAT_MAP.items():
        for index, input_date in enumerate(INPUT_DATES.get(date_format)):
            expected_date = EXPECTED_DATES[index]
            result.append(
                (
                    marketplace_id,
                    {"date": input_date, "rating": 1, "comments": "c", "response": "r", "order_id": "1", "rater_email": "e"},
                    {"date": expected_date, "rating": 1, "comments": "c", "response": "r", "order_id": "1", "rater_email": "e"},
                )
            )

    return result

@pytest.mark.parametrize("marketplace_id,input_data,expected_data", parametrize_seller_feedback())
def test_transform_seller_feedback(marketplace_id, input_data, expected_data):
    stream = reports_stream(marketplace_id)
    transformer = stream.transformer
    schema = stream.get_json_schema()
    transformer.transform(input_data, schema)

    assert input_data == expected_data


from cv2 import cv2

class Camera:
    """Absolute path to image file"""
    filename = ""

    def __init__(self, filename):
        self.filename = filename

    def take_image(self):
        # Initialize the camera
        cam_port = 0
        cam = cv2.VideoCapture(cam_port)
        cam.set(cv2.CAP_PROP_FRAME_WIDTH, 1920)
        cam.set(cv2.CAP_PROP_FRAME_HEIGHT, 1080)
        cam.set(cv2.CAP_PROP_AUTOFOCUS, 0)  # turn the autofocus off
        cam.set(cv2.CAP_PROP_FOCUS, 5)

        # Reading the input using the camera
        result, image = cam.read()

        # Saving image in local storage
        cv2.imwrite(self.filename, image)

        # Return image object back
        return image

    def read_image(self):
        # Using cv2.imread() method
        image = cv2.imread(self.filename)

        # Return image object back
        return image


class TipoAluno: # referente ao exercício 4
    matricula = 0
    nome = ''

def Cadastrar(vetAluno):
    print('Cadastro de alunos.........................')
    for i in range(3):
        a = TipoAluno()
        a.matricula = int(input('Digite a matrícula: '))
        a.nome = input('Digite o nome: ')
        vetAluno.append(a)
    return vetAluno

def Consultar(vetAluno):
    print('Consulta por nome..........................')
    nomePesquisa = input('Qual nome quer pesquisar? ')
    for i in range(3):
        if nomePesquisa == vetAluno[i].nome:
            print('Matrícula: ',vetAluno[i].matricula,'\tNome: ',vetAluno[i].nome)

def Mostrar(vetAluno):
    print('Apresentaçao dos dados dos alunos..........')
    for i in range(3):
        print('Matrícula: ',vetAluno[i].matricula,'\tNome: ',vetAluno[i].nome)

def main():
    op = 1
    while op >=1 and op <= 3:
        print('Menu de Gerenciamento')
        print('1- Cadastrar')
        print('2- Consultar')
        print('3- Mostrar')
        print('4- Sair')
        op = int(input('Digite a opção: '))
        if op == 1:
            vetA=[]
            vetA = Cadastrar(vetA)
        elif op == 2:
            Consultar(vetA)
        elif op == 3:
            Mostrar(vetA)

main()


from flask import Flask, request, Response, jsonify;
from flask_restful import Resource, Api, reqparse;
from flask.ext.mysql import MySQL;
import json;

app = Flask(__name__);

#MySQL configurations
app.config['MYSQL_DATABASE_USER']       ='root';
app.config['MYSQL_DATABASE_PASSWORD']   ='root1234';
app.config['MYSQL_DATABASE_DB']         ='analysis_app_db';
app.config['MYSQL_DATABASE_HOST']       ='localhost';

mysql=MySQL();
mysql.init_app(app);

class Tag(Resource):
    def get(self):
        try:
            query_result = execute_query("SELECT * FROM tb_tag");
            data = json.dumps(query_result);
            resp = Response(data, status=200, mimetype='application/json');
            return resp;

        except Exception as e:
            return {'error':str(e)};

class Test(Resource):
    def get(self):
        try:
            jsonParams = request.get_json();
            jjson = json.loads(jsonParams);

            queryStr = "select * from tb_tag";

            for key in jjson:
                print(jjson[key]);

            return 'ok';
        except Exception as e:
            return {'error':str(e)};

def execute_query(query, one=False):
    cursor = mysql.connect().cursor();
    cursor.execute(query)
    rv = [dict((cursor.description[idx][0], value)
    for idx, value in enumerate(row)) for row in cursor.fetchall()]
    return (rv[0] if rv else None) if one else rv;


# -*- encoding: utf-8 -*-
# Copyright (c) Tomasz Krol tomek@kingu.pl
"""
Module to grab actual editions & versions of Mozilla Firefox
"""
import copy
import requests
import re
from datetime import datetime, date
from bs4 import BeautifulSoup

product = "Google Chrome"

def getEditions(template):
	result = []

	template.product = product
	template.ends = date.max
	template.stable = True

	#Looking for releases
	response = requests.get(url="https://omahaproxy.appspot.com/json")
	data = response.json()

	#Looking releases
	item = copy.copy(template)									#copy of Softver object

	for element in data:
		platform = element['os']
		if platform != 'win64':
			continue
		else:
			versions = element['versions']
			for version in versions:
				if version['channel'] != 'stable':
					continue
				else:
					#print(version['channel'])

					#find release date
					value = version['current_reldate']
					item.released = datetime.strptime(value, '%m/%d/%y').date()

					#find version
					value = version['version']
					item.version = value
					value = re.search('\d+\.\d+',value)
					if value == None:
						continue
					else:
						item.edition = value.group()

					item.latest = True

					result.append(item)

	return result

# if __name__ == "__main__":
    # print(getEditions(Softver()))


import torch
import torchvision
from torchsummary import summary

USE_CUDA = torch.cuda.is_available()
DEVICE = torch.device('cuda' if USE_CUDA else 'cpu')

def cnn_model(name='resnet18', pretrained=True, num_output=3):
    if name == 'resnet18':
        net = torchvision.models.resnet18(pretrained=pretrained).to(DEVICE)
        net.conv1 = torch.nn.Conv2d(1, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)
        net.fc = torch.nn.Sequential(
            torch.nn.Linear(512, 256),
            torch.nn.ReLU(),
            torch.nn.Linear(256, 128),
            torch.nn.ReLU(),
            torch.nn.Linear(128, num_output))
    elif name == 'vgg16':
        net = torchvision.models.vgg16(pretrained=pretrained).to(DEVICE)
        net.features[0] = torch.nn.Conv2d(1, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        net.classifier = torch.nn.Sequential(
            torch.nn.Linear(512 * 7 * 7, 256),
            torch.nn.ReLU(),
            torch.nn.Linear(256, 128),
            torch.nn.ReLU(),
            torch.nn.Linear(128, num_output))
    elif name == 'alexnet':
        net = torchvision.models.alexnet(pretrained=pretrained).to(DEVICE)
        net.features[0] = torch.nn.Conv2d(1, 64, kernel_size=(11, 11), stride=(4, 4), padding=(2, 2), bias=False)
        net.classifier = torch.nn.Sequential(
            torch.nn.Linear(256 * 6 * 6, 256),
            torch.nn.ReLU(),
            torch.nn.Linear(256, 128),
            torch.nn.ReLU(),
            torch.nn.Linear(128, num_output))
    elif name == 'mobilenet':
        net = torchvision.models.mobilenet_v2(pretrained=pretrained).to(DEVICE)
        net.features[0][0] = torch.nn.Conv2d(1, 32, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
        net.classifier = torch.nn.Sequential(
            torch.nn.Linear(1280, 256),
            torch.nn.ReLU(),
            torch.nn.Linear(256, 128),
            torch.nn.ReLU(),
            torch.nn.Linear(128, num_output))
    elif name == 'shufflenet':
        net = torchvision.models.shufflenet_v2_x0_5(pretrained=pretrained).to(DEVICE)
        net.conv1[0] = torch.nn.Conv2d(1, 24, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
        net.fc = torch.nn.Sequential(
            torch.nn.Linear(1024, 256),
            torch.nn.ReLU(),
            torch.nn.Linear(256, 128),
            torch.nn.ReLU(),
            torch.nn.Linear(128, num_output))

    else:
        print('wrong cnn model!')

    return net

def test():
    net = cnn_model(name='shufflenet')

    summary(net, (1, 480, 640))
    #y = net(torch.randn(1, 3, 480, 640))
    print(net)

if __name__ == "__main__":
    test()


from datetime import datetime as dtime
import os, time, random

# normal charge lasts about 1h 100%
# So it would be fair to report every 10mins = every 10%
# but it heats up quickly and we need data before it heats
# therefore report every 3mins
# time passed shown in report is total time it took
# to charge to 100%
# timer is reset if charger was disconnected
# as it will be inacurrate data

# current date/time
d   = dtime.now()
day = d.strftime("%d%m")
tim = d.strftime("%I:%M:%S %p %d/%m/%Y")

# ask for current code_name
c_n = input("What is code_name you are testing? : ")
if not c_n:
   c_n = f"beta_{day}_{random.randint(0, 100)}"
   print("\n[WARN] You didn't give code_name one of the existing logs may be overwritten")

# run shell commands
def cat(cmd, remove_new_lines=True):
    return os.popen(cmd).read().replace('\n','') if remove_new_lines else os.popen(cmd).read()

# New File
filename = f"vant_{c_n}.txt"
f = open(f"/sdcard/{filename}", "a")
print(f"\n[INFO] Created {filename}")

flavor = cat("getprop ro.build.flavor")
host   = cat("getprop ro.build.host")
id     = cat("getprop ro.build.id")
code   = cat("getprop ro.build.product")

start = f"""
########### BESS VANT ############
##### {tim} #####
######### Charging Report ########
Device Code : {code}
Rom ID      : {id}
Rom Host    : {host}
Rom Flavor  : {flavor}
Test Name   : {c_n} """

print(start, file=f)
f.flush()

def log(t, n):
    timen = timeinletters(int(t))
    temp  = int(cat("cat /sys/devices/virtual/thermal/thermal_zone79/temp"))/1000
    level = cat("cat /sys/class/power_supply/battery/capacity")
    dmesg = cat("su -c 'dmesg | tail -25'", remove_new_lines=False) # last 25 line of dmesg
    # calc watt by Average of volts*amp three times
    data = []
    for i in range(3):
        v = round(int(os.popen("cat /sys/devices/platform/soc/c440000.qcom,spmi/spmi-0/spmi0-00/c440000.qcom,spmi:qcom,pm6150@0:qcom,qpnp-smb5/power_supply/battery/voltage_now").read().replace("\n",''))/1000000, 2)
        a = round(int(os.popen("cat /sys/devices/platform/soc/c440000.qcom,spmi/spmi-0/spmi0-00/c440000.qcom,spmi:qcom,pm6150@0:qcom,qpnp-smb5/power_supply/battery/current_now").read().replace("\n",'').replace("-",''))/1000, 2)
        data.append(round((v*a)/1000,2))
    # calc avg
    watts  = round(sum(data)/len(data),2)
    report = f"""\n\n
####################################################################
########################## Report {n} ################################

Time Passed : {timen}
Charge level: {level}%
Temp        : {temp}°C
Watts       : {watts}w

###########################  DMESG  ################################
{dmesg}
####################################################################
####################################################################
    """
    printf(report)
    if int(level) >= 100:
       printf(f"\n#### CHARGING COMPLETE IN {timen} ####")
       exit()

# check if charging
def is_connected():
    a = int(cat("cat /sys/class/power_supply/usb/online"))
    return bool(a)

# duplicate logging to terminal/text file
def printf(s):
    print(s)
    print(s, file=f)
    f.flush()

# homan readable format
def timeinletters(unixt):
    h = 86400
    m = 3540
    s = 59
    t    = int(time.time())
    diff = abs(t - unixt)
    if   diff < s:  return str(diff) + "s"
    elif diff < m:  return str(round(diff/60)) + "m"
    elif diff < h:  return str(int(diff/3600)) + "h"
    else:           return str(int(diff/86400)) + "days"

# constants
m = 60*3 # 3mins
c = 0     # time passed
n = 0
t = time.time()

# Real Code
while 1:
  # if 10mins passed
  if int(time.time()) >= c + m:
     if not is_connected():
        while 1:
          if not is_connected():
             printf("\n### Please Connect Charger to start logging ###")
             time.sleep(5)
             continue
          else:
             printf("\n### Usb Connected Charging Timer reset ###")
             t = time.time() # reset timer
             break
     c = int(time.time())
     log(t, n)
     n+=1
     continue
  else:
     sleep = (c+m) - int(time.time())
     print(f"\n[INFO] sleeping for {sleep}s")
     time.sleep(sleep)
     continue

# this is part of ln8000_beta_reporting project on github.com/justxd22
# credits goes to the boss bantom for porting ln8000


import os

import pytest
import tempfile
import pandas as pd

import calliope
from calliope.test.common.util import check_error_or_warning

class TestModel:
    @pytest.fixture(scope="module")
    def national_scale_example(self):
        model = calliope.examples.national_scale(
            override_dict={"model.subset_time": ["2005-01-01", "2005-01-01"]}
        )
        model.run()
        return model

    def test_info(self, national_scale_example):
        model = national_scale_example

        model.info()

    def test_info_minimal_model(self):
        this_path = os.path.dirname(__file__)
        model_location = os.path.join(
            this_path, "common", "test_model", "model_minimal.yaml"
        )
        model = calliope.Model(model_location)

        model.info()


round = int(input())
money = int(input())
x2 = int(input())
status = str(input())

value0 = money
value1 = money

for i in range(round-1):
    if round % x2 == 0:
        money*=2
        print('table #',i,': ¢æ',value)


__author__ = 'andy17'

import theano
import theano.tensor as T
import models as M
import utils
import utils.theanoGeneral as utilsT
import utils.mathT as mathT
import numpy as np
import numpy.random as npr

'''
models, with batch evaluation
'''

class Banana(M.GraphModel):
    '''
    Graphical model

        (z1)    (z2)
          \     /
           \   /
           ( x )
                   p(z) = N( z ; 0, I )
                   p(x|z) = N( x ; z1*z2, std^2 )
    '''

    def __init__(self, name=None):
        super(Banana,self).__init__(name)

        self.dimx, self.dimz = 1, 2

        # true parameter of the function
        self.stdx_ztrue = 0.7

        # shared params, to be updated (learnt)
        self.stdx_z = utilsT.sharedf(1.)
        self.params = [ self.stdx_z ]

        # prior of z : wont change
        self.logP_z       = mathT.multiNormInit( mean=np.zeros(self.dimz), varmat=np.eye(self.dimz) )
        # ( x-z1*z2 ) ~ N( 0, sigma2 )
        self.logP_uninorm = mathT.normInit_sharedParams(mean=utilsT.sharedf(0), var=T.sqr(self.stdx_z), offset=None)

    def setX(self,x):  # x : B x dimX
        # x is a TheanoVariable
        self.x = x

    def setParamValues(self,values):
        self.stdx_z.set_value( np.asarray(values['std'],dtype=utils.floatX) )

    def setTrueParamValues(self,values):
        self.stdx_ztrue = values['std']

    def logPxz(self, x, z):
        # z : B x N x dimZ
        # x : B
        (B,N,dimZ) = z.shape.eval()

        zprods = T.prod( z,axis=2 )
        subs = zprods - x.dimshuffle(0,'x')
        logpx_zs = self.logP_uninorm(subs)   # p(x|z), B x N

        logpzlst = list()   # p(z), B x N
        for id in range(B):
            logpz = self.logP_z(z[id])      # N
            logpzlst.append(logpz)
        logpzs = T.concatenate(logpzlst).reshape( (B,N) )  # B x N

        return logpzs+logpx_zs, logpx_zs, logpzs

    def getParams(self):
        return self.params

    def generate(self,num,savepath):
        zs = npr.randn(num,self.dimz)
        xs = npr.randn(num)*self.stdx_ztrue + np.prod(zs,axis=1)
        np.savez(savepath,x=xs,z=zs,std=self.stdx_ztrue,size=num)


from math import sqrt
from sklearn import datasets
from sklearn.model_selection import train_test_split
import numpy as np
from sorting_algo.quick_sort import quick_sort

class knn:
    def __init__(self, x_train=0, y_train=0, classes=0, k=0):
        self.x_train = x_train
        self.y_train = y_train
        self.classes = classes
        self.point = None
        self.k = k

    def distances(self):
        summ = 0
        distance = []
        for i in range(len(self.x_train)):
            for j in range(len(self.x_train[0])):
                summ += (self.x_train[i][j] - self.point[j]) ** 2
            distance.append(sqrt(summ))
            summ = 0
        return distance

    def fit(self, x_train, y_train, classes, k=5):
        self.x_train = x_train
        self.y_train = y_train
        self.classes = classes
        self.k = k

    def predict(self, point):
        self.point = point
        dist = self.distances()
        pr = {}
        for i in range(len(self.x_train)):
            pr[dist[i]] = self.y_train[i]
        sort_dist = quick_sort(list(pr.keys()))
        result = []
        for i in sort_dist[:self.k]:
            result.append(pr[i])
        print(result)
        sum = 0
        for i in result:
            sum += i
        return sum/len(result)

def main():
    data = datasets.load_iris()

    X = np.array(data["data"])
    y = np.array(data["target"])
    classes = data["target_names"]

    X_train, X_test, y_train, y_test = train_test_split(X, y)

    model = knn()
    model.fit(X_train, y_train, classes)
    p = model.predict(X_test[3])
    print('predict : ', p)
    print(classes[int(round(p))])
    print(y_test[3])

if __name__ == '__main__':
    main()
# расстояние как оценка модификация


import os
import typing as t

import pygame

class AssetLoader:
    def __init__(
            self,
            path: t.Union[str, bytes, os.PathLike],
            scale: bool = False,
            new_size: t.Union[int, t.Tuple[int, int]] = None,
            transparent_color: t.Union[pygame.Color, t.Tuple[int, int, int]] = (255, 255, 255),
            row_color: t.Union[pygame.Color, t.Tuple[int, int, int, int]] = (255, 255, 0, 255),
            col_color: t.Union[pygame.Color, t.Tuple[int, int, int, int]] = (0, 0, 255, 255),
            converter: t.Union[pygame.Surface.convert,
                               pygame.Surface.convert_alpha] = pygame.Surface.convert
    ) -> None:
        """Creates a 2D tuple of surfaces from the given sprite sheet.
        Each inner tuple will contain all sprites on the according row.

        :param path: path to the sprite sheet
        :param scale: determines whether each surface will be scaled
        :param new_size: scale of the surface, if a single integer is provided
                         the surface size will be multiplied by that number when scaling,
                         if a two element tuple is provided, it will scale to that size
        :param transparent_color: the color to set as transparent on the surfaces,
                                  use None to disable
        :param row_color: marker color to indicate rows
        :param col_color: marker color to indicate columns
        :param converter: specify to `convert` or to `convert_alpha`, doesn't convert
                          if None is provided, default is `convert`
        """
        self.sprites = []
        sprite_sheet = pygame.image.load(path)

        row_start = None
        col_start = 0
        sprite_sheet_width = sprite_sheet.get_width()

        for y in range(sprite_sheet.get_height()):
            color = sprite_sheet.get_at((0, y))
            if color == row_color:
                if row_start is None:
                    row_start = y
                    continue
                _sprites = []
                height = y - row_start - 1
                for x in range(sprite_sheet_width):
                    color = sprite_sheet.get_at((x, row_start))
                    if color == col_color:
                        width = x - col_start
                        rect = pygame.Rect(col_start, row_start + 1, width, height)
                        sprite = sprite_sheet.subsurface(rect)
                        if scale and new_size is not None:
                            if isinstance(new_size, int):
                                _w, _h = sprite.get_size()
                                sprite = pygame.transform.scale(sprite, (_w * new_size, _h * new_size))
                            elif isinstance(new_size, tuple) and len(new_size) == 2:
                                sprite = pygame.transform.scale(sprite, new_size)
                        if converter is not None:
                            sprite = converter(sprite)
                        if transparent_color is not None:
                            sprite.set_colorkey(transparent_color)
                        _sprites.append(sprite)
                        col_start = x
                self.sprites.append(tuple(_sprites))
                col_start = 0
                row_start = y
        self.sprites = tuple(self.sprites)

    def get_row(self, row) -> t.Tuple[pygame.Surface]:
        """Returns a tuple of all surfaces in the requested row."""

        return self.sprites[row]

    @staticmethod
    def flip_y(surfaces: t.Iterable[pygame.Surface], reverse: bool = True
               ) -> t.Tuple[t.Union[pygame.Surface, pygame.SurfaceType], ...]:
        """Returns a tuple of flipped surfaces on the y axis."""
        if reverse:
            return tuple(reversed([pygame.transform.flip(s, True, False) for s in surfaces]))
        elif not reverse:
            return tuple(pygame.transform.flip(s, True, False) for s in surfaces)

    @staticmethod
    def flip_x(surfaces: t.Iterable[pygame.Surface]
               ) -> t.Tuple[t.Union[pygame.Surface, pygame.SurfaceType], ...]:
        """Returns a tuple of flipped surfaces on the x axis."""

        return tuple(pygame.transform.flip(s, False, True) for s in surfaces)

    def get_combined(self
                     ) -> t.Tuple[t.Union[pygame.Surface, pygame.SurfaceType], ...]:
        """Returns all surfaces in a single tuple."""

        lst = []
        for tpl in self.sprites:
            lst.extend(tpl)
        return tuple(lst)


class Solution:
    def __init__(self):
        self.root = {}

    def complement(self, number):
        bin_rep = bin(number)[2:]
        return int(''.join(['1' if bit == '0' else '0' for bit in bin_rep]), 2)

    def to_32_bit(self, number):
        return '{:032b}'.format(number)

    def insert(self, number):
        curr_node = self.root
        binary = self.to_32_bit(number)
        for bit in binary:
            if bit not in curr_node:
                curr_node[bit] = {}
            curr_node = curr_node[bit]

        curr_node['value'] = number

    def switch(self, bit):
        if bit == '0':
            return '1'
        return '0'

    def max_xor(self, list_numbers):
        curr_max = 0
        for number in list_numbers:
            target = self.to_32_bit(self.complement(number))
            curr_node = self.root
            for bit in target:
                if bit not in curr_node:
                    curr_node = curr_node[self.switch(bit)]
                else:
                    curr_node = curr_node[bit]
            curr_max = max(curr_node['value'] ^ number, curr_max)
        return curr_max

    def findMaximumXOR(self, nums: List[int]) -> int:
        for number in nums:
            self.insert(number)
        return self.max_xor(nums)