import sys
import vtk
import numpy as np
import cv2
import py_ct_reg as ct
import os
import HandEyeCalLogic as he
import pydicom as dicom
from eval_dereflection_cl import Evaluator
from PyQt5 import QtCore, QtGui, QtWidgets
from vtkMainWindow_ui import Ui_MainWindow
from skimage import measure
from pycpd import AffineRegistration
#import matplotlib.pyplot as plt
import csv
import matlab.engine
from vtk.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor
from sksurgerynditracker.nditracker import NDITracker

POSITIONER_PRIMARY_ANGLE_INCREMENT = 1
POSITIONER_SECONDARY_ANGLE_INCREMENT = 1

# Change thresholds based on trial and error with extracted fiducial images
THRESHOLD_VALUE_1 = 0.3
THRESHOLD_VALUE_2 = 0.25
REORDER_INDEX = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 10]

FRAME_INTERVAL_MS = 1000

# Might need to change this based on how many COM ports show up on in device manager
NUM_PORTS = 2
SPHERE_RADIUS = 5

class DeepDecompositionViewer(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super().__init__()
        ckptsdir = "C:/Users/iahmedf/Documents/em-fluoro-artifact-removal/checkpoints"

        # Output directory for image files and tracking data
        self.outdir = "C:/Users/iahmedf/Documents/em-fluoro-artifact-removal/image_files"
        os.mkdir(f"{self.outdir}/preprocessed")
        os.mkdir(f"{self.outdir}/fiducials")
        os.mkdir(f"{self.outdir}/removed")
        self.trackingFile = open(f'{self.outdir}/trackingdata.txt', 'w')
        self.carmFile = open(f'{self.outdir}/carmdata.txt', 'w')

        self.eval = Evaluator(ckptsdir)
        self.setupUi(self)

        # Tracker widget setup
        self.ren = vtk.vtkRenderer()
        self.qvtkwin = QVTKRenderWindowInteractor(self.vtkWidget)
        self.qvtkwin.GetRenderWindow().AddRenderer(self.ren)
        self.ren.SetBackground(0.1, 0.2, 0.4)
        self.iren = self.qvtkwin.GetRenderWindow().GetInteractor()
        self.vtkGridLayout.addWidget(self.qvtkwin, 0, 0)
        self.updateTimer = QtCore.QTimer()

        # 3D overlay on fluoro stream

        # Tracker setup
        self.tracker = None
        self.isTrackerInitialized = False
        self.trackerSettings = {
            "tracker type": "aurora",
            "ports to probe": NUM_PORTS,
            "verbose": True
        }
        self.trackedTipSource = vtk.vtkSphereSource()
        self.trackedTipActor = vtk.vtkActor()
        self.trackedTipMapper = vtk.vtkPolyDataMapper()
        self.trackedTipTransform = vtk.vtkTransform()

        self.centers_original_ref = np.zeros((12, 2))
        self.fiducialWorldPts = []
        self.intCalMat = np.eye(3)
        self.trackerCTRegMat = np.eye(4)

        # Transformations between CT and tracker (loaded as CSV)
        self.trackerCTRegTransform = vtk.vtkTransform()
        self.CTTrackerRegTransform = vtk.vtkTransform()

        # Transformation from CT to fluoro (calculated per frame)
        self.fluoroCTRegTransform = vtk.vtkTransform()

        self.fluoroTransform = vtk.vtkTransform()
        self.fluoroCubeSource = vtk.vtkCubeSource()
        self.fluoroCubeActor = vtk.vtkActor()
        self.fluoroCubeMapper = vtk.vtkPolyDataMapper()

        self.connectSignalsSlots()
        self.setupVtkObjects()

        # Fluoro stream
        self.fluoroStream = None
        self.isStreaming = False
        self.fluoroFrameCtr = 0

        self.eng = matlab.engine.start_matlab()

        self.updateTimer.timeout.connect(self.updateScene)
        self.updateTimer.start(FRAME_INTERVAL_MS)

    def __del__(self):
        # Closes file with tracking data (which was opened in constructor)
        self.trackingFile.close()

    def setupVtkObjects(self):
        """Initializes and connects VTK objects"""
        self.fluoroCubeSource.SetCenter(0, 0, 0)
        self.fluoroCubeSource.SetXLength(100)
        self.fluoroCubeSource.SetYLength(100)
        self.fluoroCubeSource.SetZLength(100)

        self.trackedTipTransform.Identity()
        self.trackedTipSource.SetCenter(0, 0, 0)
        self.trackedTipSource.SetRadius(SPHERE_RADIUS)
        self.trackedTipMapper.SetInputConnection(self.trackedTipSource.GetOutputPort())
        self.trackedTipActor.SetMapper(self.trackedTipMapper)

        # Initialize all transforms to identity
        self.trackerCTRegTransform.Identity()
        self.CTTrackerRegTransform.Identity()
        self.fluoroCTRegTransform.Identity()
        self.fluoroTransform.Identity()

        # Mapper/actor for fluoro camera cube
        self.fluoroCubeMapper.SetInputConnection(self.fluoroCubeSource.GetOutputPort())
        self.fluoroCubeActor.SetMapper(self.fluoroCubeMapper)

        # Transformation chain for fluoro camera cube
        # If I set this up correctly, this transforms the fluoro into EM space
        self.fluoroTransform.PostMultiply()
        self.fluoroTransform.Concatenate(self.fluoroCTRegTransform)
        self.fluoroTransform.Concatenate(self.CTTrackerRegTransform)

    def connectSignalsSlots(self):
        """Connects QT buttons/toggles with functions"""
        self.browseFiducialFileButton.clicked.connect(self.browseFiducialFile)
        self.browseIntCalButton.clicked.connect(self.browseIntCal)
        self.browseCarmCalDicom1Button.clicked.connect(self.browseCarmCalDicom1)
        self.browseCarmCalDicom2Button.clicked.connect(self.browseCarmCalDicom2)
        self.browseTrackerCTRegButton.clicked.connect(self.browseTrackerCTReg)
        self.browseSimDicomButton.clicked.connect(self.browseSimDicom)
        self.browseRefCentroidsButton.clicked.connect(self.browseRefCentroids)

        self.trackerToggle.toggled.connect(self.startTracker)
        self.streamToggle.toggled.connect(self.handleStreamToggle)
        self.confirmParametersButton.clicked.connect(self.confirmParameters)
        self.runCarmCalButton.clicked.connect(self.runCarmCal)
        self.runSimButton.clicked.connect(self.runSimSingleImg)
    def browseRefCentroids(self):
        """Browsing window for CSV file containing reference centroids"""
        fname, d = QtWidgets.QFileDialog.getOpenFileName()
        self.refCentroidsField.setText(fname)
    def browseImage(self):
        """Browsing window for preprocessed image"""
        fname, d = QtWidgets.QFileDialog.getOpenFileName()
        self.imageField.setText(fname)
        self.preImageLabel.setPixmap(QtGui.QPixmap(fname))
    def browseFiducialFile(self):
        """Browsing window for fiducial world points (predetermined from CT)"""
        fname, d = QtWidgets.QFileDialog.getOpenFileName()
        self.fiducialFileField.setText(fname)
    def browseIntCal(self):
        """Browsing window for file containing intrinsic calibration matrix"""
        fname, d = QtWidgets.QFileDialog.getOpenFileName()
        self.intCalFileField.setText(fname)
    def browseCarmCalDicom1(self):
        """Browsing window for Axis 1 DICOM file for C-arm calibration"""
        fname, d = QtWidgets.QFileDialog.getOpenFileName()
        self.carmCalDicom1Field.setText(fname)
    def browseCarmCalDicom2(self):
        """Browsing window for Axis 2 DICOM file for C-arm calibration"""
        fname, d = QtWidgets.QFileDialog.getOpenFileName()
        self.carmCalDicom2Field.setText(fname)
    def browseTrackerCTReg(self):
        """Browsing window for CT-Tracking registration extrinsic matrix"""
        fname, d = QtWidgets.QFileDialog.getOpenFileName()
        self.trackerCTRegFileField.setText(fname)
    def browseSimDicom(self):
        """Browsing window for DICOM file for simulated workflow"""
        fname, d = QtWidgets.QFileDialog.getOpenFileName()
        self.simDicomField.setText(fname)
    def processImage(self):
        """Calls eval_dereflection algorithm"""
        outfile_fiducials, outfile_removed = self.eval.run_eval(self.imageField.text())
        self.postImageLabel.setPixmap(QtGui.QPixmap(outfile_removed))
        #self.getCarmPose()

    def startTracker(self):
        """ Starts NDI Aurora (magnetic) or Polaris (optical) tracker and sets up VTK tracked objects"""
        if self.trackerToggle.isChecked():
            if not self.isTrackerInitialized:
                try:
                    self.tracker = NDITracker(self.trackerSettings)
                    self.isTrackerInitialized = True
                    self.tracker.use_quaternions = False

                except:
                    print("Unable to connect to NDI Tracked device")
                    self.isTrackerInitialized = False
                    self.trackerToggle.setChecked(False)
            if self.isTrackerInitialized:
                self.tracker.start_tracking()
                self.trackedTipActor.SetUserTransform(self.trackedTipTransform)
                self.ren.AddActor(self.trackedTipActor)
                self.qvtkwin.GetRenderWindow().Render()

        else:
            if self.isTrackerInitialized:
                self.isTrackerInitialized = False
                self.tracker.stop_tracking()
                self.ren.RemoveActor(self.trackedTipActor)
                self.qvtkwin.GetRenderWindow().Render()
                print("Tracking Stopped")

    def confirmParameters(self):
        """Add fiducials to VTK widget scene"""
        self.readFiducialFile()
        self.readRefCentroidsFile()
        self.addFiducialsToScene()
        self.readIntCalFromFile()
        self.readTrackerCtRegFromFile()

    def readRefCentroidsFile(self):
        """Reads reference pixel centroids from file"""
        refcentroids_fname = self.refCentroidsField.text()
        with open(refcentroids_fname, 'r') as f:
            lines = f.readlines()
            for i in range(12):
                line_arr = lines[i].split(',')
                self.centers_original_ref[i, 0] = float(line_arr[0].strip())
                self.centers_original_ref[i, 1] = float(line_arr[1].strip())

    def readIntCalFromFile(self):
        """Reads fluoro intrinsic calibration from file"""

        intcal_fname = self.intCalFileField.text()

        with open(intcal_fname, 'r') as f:
            lines = f.readlines()
            for i in range(3):
                line_arr = lines[i].split(',')
                for j in range(3):
                    self.intCalMat[i, j] = float(line_arr[j].strip())

    def readTrackerCtRegFromFile(self):
        """Reads registration between CT and tracker from file"""
        extcal_fname = self.trackerCTRegFileField.text()
        with open(extcal_fname, 'r') as f:
            lines = f.readlines()
            for i in range(4):
                line_arr = lines[i].split(',')
                for j in range(4):
                    self.trackerCTRegMat[i, j] = float(line_arr[j].strip())

        # Saves transformations in both directions
        # Choose based on whether you want 3D visualization to be in EM or CT space
        self.trackerCTRegTransform.SetMatrix(np.reshape(self.trackerCTRegMat, 16))
        CTTrackerRegMat = np.linalg.inv(self.trackerCTRegMat)
        self.CTTrackerRegTransform.SetMatrix(np.reshape(CTTrackerRegMat, 16))

    def addFiducialsToScene(self):
        """Reads fiducials from CSV file, transforms them to EM space, and adds them to scene"""
        sphSrc = vtk.vtkSphereSource()
        sphSrc.SetRadius(5)
        sphSrc.SetCenter(0, 0, 0)
        for pt in self.fiducialWorldPts:
            tfrm = vtk.vtkTransform()
            tfrm.PostMultiply()
            ptMat = np.eye(4)
            ptMat[0:3, 3] = pt
            tfrm.Concatenate(np.reshape(ptMat, 16))

            # Applies transformation to put each fiducial into EM tracking space
            tfrm.Concatenate(self.CTTrackerRegTransform)
            sphAct = vtk.vtkActor()
            sphMap = vtk.vtkPolyDataMapper()

            sphMap.SetInputConnection(sphSrc.GetOutputPort())
            sphAct.SetMapper(sphMap)
            sphAct.SetUserTransform(tfrm)
            self.ren.AddActor(sphAct)

    def getCarmPose(self, img):

        """Gets C-arm pose from fiducial image
        Uses reference centroids provided from CSV file"""

        img_float = img/float(np.amax(img))
        img_float = img_float.astype(np.float32)

        # Threshold Segmentation

        # Change threshold based on
        bw = img_float < 0.35
        L = measure.label(bw, connectivity=2)
        S = measure.regionprops(L)
        S_area = [S_i.area for S_i in S]
        S_area_arr = np.array(S_area)
        S_area_idx = np.where((S_area_arr >= 200) & (S_area_arr <= 600))
        S_area_idx += np.ones(len(S_area_idx))
        bw2 = np.isin(L, S_area_idx)
        bw2flt = bw2.astype(np.float32)
        cv2.imshow("bw2flt", bw2flt)
        cv2.waitKey(0)
        L2 = measure.label(bw2, connectivity=2)

        C = measure.regionprops(L2)
        centers_original = np.array([[C_i.centroid[1], C_i.centroid[0]] for C_i in C])

        # Registration with reference centroids
        reg = AffineRegistration(X=self.centers_original_ref, Y=centers_original)
        TY, (B_reg, t_reg) = reg.register()
        delta = (self.centers_original_ref - TY)
        delta_rmse = delta[:, 0] * delta[:, 0] + delta[:, 1] * delta[:, 1]
        reorderIndex = []
        if delta_rmse.all() < 1:
            reorderIndex = np.arange(len(self.centers_original_ref))
        else:
            for i in range(len(self.centers_original_ref)):
                delta_temp = TY - self.centers_original_ref[i, :]
                delta_temp_rmse = delta_temp[:, 0] * delta_temp[:, 0] + delta_temp[:, 1] * delta_temp[:, 1]
                I = np.argmin(delta_temp_rmse)
                reorderIndex.append(I)

        centers = centers_original[reorderIndex, :]

        worldPt_T = np.transpose(np.array(self.fiducialWorldPts))
        imgPt = np.transpose(np.array(centers))
        radialDistortion = np.array([0.0, 0.0])
        tangentialDistortion = np.array([0.0, 0.0])
        worldPts2 = np.array(self.fiducialWorldPts[:, 0:2], dtype=float)
        cameraParams = self.eng.cameraParameters('IntrinsicMatrix', np.transpose(self.intCalMat), 'RadialDistortion', radialDistortion, 'TangentialDistortion', tangentialDistortion, 'WorldPoints', worldPts2);

        # MATLAB function calls
        [rotationMatrix, translationVector] = self.eng.extrinsics(np.array(centers, dtype=float), worldPts2, cameraParams, nargout=2)
        [orientation, location] = self.eng.extrinsicsToCameraPose(rotationMatrix, translationVector, nargout=2)

        # Assigns MATLAB results to VTK transforms
        xfrmMat = np.empty((4, 4))
        xfrmMat[0:3, 0:3] = orientation
        xfrmMat[0:3, 3] = location

        self.fluoroCTRegTransform.SetMatrix(np.reshape(xfrmMat, 16))

        # Writes C-arm pose (calculated from fiducials - so I believe this pose is in CT space) to text file
        self.trackingFile.write(f"Frame: {self.fluoroFrameCtr}\n")
        self.trackingFile.write(f"Matrix:\n[[{xfrmMat[0][0, 0]}, {xfrmMat[0][0, 1]}, {xfrmMat[0][0, 2]}, {xfrmMat[0][0, 3]}]\n[{xfrmMat[0][1, 0]}, {xfrmMat[0][1, 1]}, {xfrmMat[0][1, 2]}, {xfrmMat[0][1, 3]}]\n[{xfrmMat[0][2, 0]}, {xfrmMat[0][2, 1]}, {xfrmMat[0][2, 2]}, {xfrmMat[0][2, 3]}]\n[{xfrmMat[0][3, 0]}, {xfrmMat[0][3, 1]}, {xfrmMat[0][3, 2]}, {xfrmMat[0][3, 3]}]]\n\n")

        # If I set up the transforms right, this is the pose of the C-arm in EM tracking space
        self.fluoroTransform.Update()

        return xfrmMat

    def updateScene(self):
        """Full workflow (streaming, artifact removal, pose calculation)"""
        if self.isStreaming:
            # Read frame
            #_, img_pre = self.fluoroStream.read()
            img_pre = cv2.imread("C:/Users/iahmedf/Documents/em-fluoro-artifact-removal/datasets_old/Syn3/val/defocused/C/7822.png")
            img_pre = cv2.cvtColor(img_pre, cv2.COLOR_BGR2RGB)
            self.fluoroFrameCtr += 1

            # Show frame in Qt
            #qimg_pre = self.cv2ToQPixmap(img_pre, QtGui.QImage.Format.Format_RGB888)
            #self.preImageLabel.setPixmap(QtGui.QPixmap.fromImage(qimg_pre))

            # Save frame
            cv2.imwrite(f"{self.outdir}/preprocessed/{self.fluoroFrameCtr}.png", img_pre)

            # Artifact removal
            img_fiducials, img_removed = self.eval.run_eval(img_pre, self.outdir, self.fluoroFrameCtr)

            img_removed = cv2.cvtColor(img_removed, cv2.COLOR_RGB2BGR)
            img_fiducials = cv2.cvtColor(img_fiducials, cv2.COLOR_RGB2BGR)

            #qimg_fiducials = self.cv2ToQPixmap(img_fiducials, QtGui.QImage.Format.Format_RGB888)
            qimg_removed = self.cv2ToQPixmap(img_pre, QtGui.QImage.Format.Format_RGB888)
            self.fluoroImgLabel.setPixmap(QtGui.QPixmap.fromImage(qimg_removed))
            #self.fiducialsImageLabel.setPixmap(QtGui.QPixmap.fromImage(qimg_fiducials))

            # Calculate C-arm pose
            self.getCarmPose(img_fiducials)
            #print(self.fluoroCubeActor.GetUserMatrix())
        if self.isTrackerInitialized:
            port_handles, time_stamps, frame_numbers, tracking, tracking_quality = self.tracker.get_frame()
            print("read frame")
            self.trackedTipTransform.SetMatrix(np.reshape(tracking[0], 16))
            self.trackedTipTransform.Update()
            self.ToolTxLCD.display(tracking[0][0, 3])
            self.ToolTyLCD.display(tracking[0][1, 3])
            self.ToolTzLCD.display(tracking[0][2, 3])

            # Frame column of CSV shows -1 if not video streaming; shows the fluoro frame number if streaming
            if self.isStreaming:
                curFrame = self.fluoroFrameCtr
            else:
                curFrame = -1
            self.trackingFile.write(f"Frame: {curFrame}\n")
            self.trackingFile.write(f"Matrix:\n[[{tracking[0][0, 0]}, {tracking[0][0, 1]}, {tracking[0][0, 2]}, {tracking[0][0, 3]}]\n[{tracking[0][1, 0]}, {tracking[0][1, 1]}, {tracking[0][1, 2]}, {tracking[0][1, 3]}]\n[{tracking[0][2, 0]}, {tracking[0][2, 1]}, {tracking[0][2, 2]}, {tracking[0][2, 3]}]\n[{tracking[0][3, 0]}, {tracking[0][3, 1]}, {tracking[0][3, 2]}, {tracking[0][3, 3]}]]\n\n")
        self.ren.ResetCameraClippingRange()
        self.qvtkwin.GetRenderWindow().Render()

    def cv2ToQPixmap(self, cv2img, format):
        """Converts cv2 image to QPixmap format"""
        height, width, bytesPerComponent = cv2img.shape
        bytesPerLine = bytesPerComponent * width
        return QtGui.QImage(cv2img.data, width, height, bytesPerLine, format)

    def readFiducialFile(self):
        """Reads list of fiducial positions from CSV file"""
        fname = self.fiducialFileField.text()

        with open(fname, 'r') as f:
            lines = f.readlines()
            for line in lines:
                line_arr = line.split(',')
                self.fiducialWorldPts.append([float(line_arr[1].strip()), float(line_arr[2].strip()), float(line_arr[3].strip())])
        self.fiducialWorldPts = np.array(self.fiducialWorldPts, dtype=np.float32)

    def handleStreamToggle(self):
        """Starts/stops video stream"""
        if self.streamToggle.isChecked():
            self.isStreaming = True
            self.fluoroStream = cv2.VideoCapture(0)
            self.fluoroCubeActor.SetUserTransform(self.fluoroCTRegTransform)
            self.ren.AddActor(self.fluoroCubeActor)
            #self.updateTimer.timeout.connect(self.updateScene)

        else:
            self.isStreaming = False
            self.fluoroStream = None

    # The following 3 functions are not used in the actual workflow - they were just used to simulate/test parts of the workflow
    def runCarmCal(self):

        fname1 = self.carmCalDicom1Field.text()
        fname2 = self.carmCalDicom2Field.text()
        fiducial_fname = ct.extractFiducials(fname1, fname2)
        worldpts_fname = self.fiducialFileField.text()
        print(self.intCalMat)
        ct.computeCarmPose(self.intCalMat, fiducial_fname, worldpts_fname)

    def runSimSingleImg(self):
        imgname = self.simDicomField.text()
        img = cv2.imread(imgname)

        inv = self.getCarmPose(img)
        print(inv)
    def updateScene_streamingtest(self):
        """Just tests streaming and artifact removal (no C-arm pose calculation)"""
        if self.isStreaming:
            _, img_pre = self.fluoroStream.read()
            img_pre = cv2.cvtColor(img_pre, cv2.COLOR_BGR2RGB)
            self.fluoroFrameCtr += 1
            qimg_pre = self.cv2ToQPixmap(img_pre, QtGui.QImage.Format.Format_RGB888)
            self.preImageLabel.setPixmap(QtGui.QPixmap.fromImage(qimg_pre))
            cv2.imwrite(f"{self.outdir}/preprocessed/{self.fluoroFrameCtr}.png", img_pre)

            img_fiducials, img_removed = self.eval.run_eval(img_pre, self.outdir, self.fluoroFrameCtr)
            cv2.imshow("removed rgb", img_removed)
            cv2.waitKey(0)
            img_removed = cv2.cvtColor(img_removed, cv2.COLOR_RGB2BGR)
            img_fiducials = cv2.cvtColor(img_fiducials, cv2.COLOR_RGB2BGR)

            img_removed = cv2.cvtColor(img_removed, cv2.COLOR_BGR2RGB)
            img_fiducials = cv2.cvtColor(img_fiducials, cv2.COLOR_BGR2RGB)
            qimg_fiducials = self.cv2ToQPixmap(img_fiducials, QtGui.QImage.Format.Format_RGB888)
            qimg_removed = self.cv2ToQPixmap(img_removed, QtGui.QImage.Format.Format_RGB888)
            self.removedImageLabel.setPixmap(QtGui.QPixmap.fromImage(qimg_removed))
            self.fiducialsImageLabel.setPixmap(QtGui.QPixmap.fromImage(qimg_fiducials))
        self.ren.ResetCameraClippingRange()
        self.qvtkwin.GetRenderWindow().Render()
    def runSimNoRemoval(self):
        # Takes in a DICOM file and calculates the C-arm pose for every frame, then creates visualization

        # Reads in DICOM and parameters
        dcmname = self.simDicomField.text()
        info = dicom.dcmread(dcmname)
        angleIncrement = info.PositionerSecondaryAngleIncrement
        uniqueAngles = np.unique(angleIncrement)
        numUniqueAngles = len(uniqueAngles)

        # Sets up visualization
        self.fluoroCubeActor.SetUserTransform(self.fluoroCTRegTransform)
        self.ren.AddActor(self.fluoroCubeActor)

        # Saves all C-arm positions
        translationVectorTotal = np.zeros((3, numUniqueAngles-20))

        # Calculates reference centroids
        indexRef = int(np.ceil(numUniqueAngles/2.0)) - 1
        framesIndex = np.where(angleIncrement == uniqueAngles[indexRef])
        frameIndex = int(np.ceil(np.median(framesIndex)))
        refimg = info.pixel_array[frameIndex]

        img_float = refimg/float(np.amax(refimg))
        img_float = img_float.astype(np.float32)

        # Threshold Segmentation
        bw = img_float < 0.3
        bwint = bw.astype(np.float32)
        L = measure.label(bw, connectivity=2)
        S = measure.regionprops(L)
        S_area = [S_i.area for S_i in S]
        S_area_arr = np.array(S_area)
        S_area_idx = np.where((S_area_arr >= 200) & (S_area_arr <= 2000))
        S_area_idx += np.ones(len(S_area_idx))
        bw2 = np.isin(L, S_area_idx)
        bw2flt = bw2.astype(np.float32)
        L2 = measure.label(bw2flt, connectivity=2)

        C = measure.regionprops(L2)
        self.centers_original_ref = np.array([[C_i.centroid[1], C_i.centroid[0]] for C_i in C])

        # Finds centroids and calculates pose for each frame
        for indexRef in range(numUniqueAngles - 20):
            framesIndex = np.where(angleIncrement == uniqueAngles[indexRef])
            frameIndex = int(np.ceil(np.median(framesIndex)))
            print(f"--frameIndex {frameIndex}--")
            img = info.pixel_array[frameIndex]

            inv = self.getCarmPose(img)
            translationVectorTotal[:, indexRef] = inv[0:3, 3]
            self.ren.ResetCameraClippingRange()
            self.qvtkwin.GetRenderWindow().Render()
        # fig = plt.figure()
        # ax = fig.add_subplot(projection='3d')
        # ax.scatter(translationVectorTotal[0, :], translationVectorTotal[1, :], translationVectorTotal[2, :], s=10, c='b', marker='s')
        # ax.set_xlim3d(-100, 100)
        with open('translationVectorTotal.csv', 'w', newline='') as f:
            writer = csv.writer(f)
            for t in np.transpose(translationVectorTotal):
                writer.writerow(t)

        #plt.show()

if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    window = DeepDecompositionViewer()
    window.show()
    window.iren.Initialize()
    sys.exit(app.exec())


import pylab
import streamlit as st
import numpy as np
import pyaudio
import wave
import librosa
import librosa.display
import PIL.Image
from matplotlib import pyplot as plt
from tensorflow import keras
import tensorflow as tf
CHUNK = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 2
RATE = 44100

def record_audio(duration):
    p = pyaudio.PyAudio()
    stream = p.open(format=FORMAT,
                    channels=CHANNELS,
                    rate=RATE,
                    input=True,
                    frames_per_buffer=CHUNK)

    frames = []
    for i in range(0, int(RATE / CHUNK * duration)):
        data = stream.read(CHUNK)
        frames.append(data)

    stream.stop_stream()
    stream.close()
    p.terminate()
    return np.frombuffer(b''.join(frames), dtype=np.int16)

p = pyaudio.PyAudio()

def play_audio(data):
    stream = p.open(format=FORMAT,
                    channels=CHANNELS,
                    rate=RATE,
                    output=True)
    stream.write(data.tobytes())
    stream.stop_stream()
    stream.close()
    p.terminate()

def get_wav_info(wav_file):
    wav = wave.open(wav_file, 'r')
    frames = wav.readframes(-1)
    sound_info = pylab.frombuffer(frames, 'int16')
    frame_rate = wav.getframerate()
    wav.close()
    return sound_info, frame_rate

def plot_spectrogram(rec_name):
    y, sr = librosa.load(rec_name)
    fig = plt.figure(figsize=(10, 4))
    S = librosa.feature.melspectrogram(y=y, sr=sr,n_mels=256,hop_length=256)
    spec_db = librosa.power_to_db(S, ref=np.max)
    librosa.display.specshow(spec_db,
                             y_axis='mel', fmax=8000, x_axis='time')
    plt.tight_layout()
    # scaling
    spec_scaled = (spec_db + 80) / 80
    cur = rec_name.split('/')[1]
    print(cur)
    plt.savefig(f"{cur.split('.')[0]}.png")
    return spec_db,fig

st.title("Audio Calculator")
# model = keras.models.load_model('trained_model.h5')
def predict_word(spect_path):
    model = keras.models.load_model('trained_model.h5')
    image = PIL.Image.open(spect_path).convert('RGB')
    resized_image = image.resize((256, 256))
    input_image = tf.image.convert_image_dtype(resized_image, tf.float32)
    input_image = tf.expand_dims(input_image, axis=0)
    prediction = model.predict(input_image)
    print(prediction)
    max_value = max(prediction)
    st.write(max_value)
    return np.argmax(prediction)

if "load_state" not in st.session_state:
     st.session_state.load_state = False

if st.button("Record") and not st.session_state.load_state:
        recordings = []

        # Recording three times
#         for i in range(3):
#             st.write(f"Recording {i + 1}...")
#             data = record_audio(duration=5)
#             st.write("Finished recording.")

#             # Save the recording to a WAV file
#             filename = f"recording_{i + 1}.wav"
#             with wave.open(filename, 'wb') as wf:
#                 wf.setnchannels(CHANNELS)
#                 wf.setsampwidth(p.get_sample_size(FORMAT))
#                 wf.setframerate(RATE)
#                 wf.writeframes(data.tobytes())

#             # Append the recording to the list
#             recordings.append(data)

#
        # recorded once, and therefore updating the state
        st.session_state.load_state = True

c1, c2, c3 = st.columns(3)

if "load_state" in st.session_state and st.session_state.load_state:

    with c1:
        st.header("Play the first digit")
        data, sr = librosa.load('./recording_1.wav')
        st.audio(data, sample_rate=RATE)
        if st.button('Present spectrogram 1 and output'):
            spectrogram,fig = plot_spectrogram('./recording_1.wav')
            st.pyplot(fig)
            st.write(predict_word('./recording_1.png'))
            #st.write(predict_word(spectrogram))

    # Record the operation
    with c2:
        st.header("Play the operation (+, -, *, /)")
        data, sr = librosa.load('./recording_2.wav')
        st.audio(data, sample_rate=sr)
        if st.button('Present spectrogram 2 and output'):
            spectrogram,fig = plot_spectrogram('./recording_2.wav')
            st.pyplot(fig)
            st.write(predict_word('./recording_1.png'))
            #st.write(predict_word(spectrogram))
    # Record the second number
    with c3:
        st.header("Play the second digit")
        data, sr = librosa.load('./recording_3.wav')
        st.audio(data, sample_rate=RATE)
        if st.button('Present spectrogram 3 and output'):
            spectrogram,fig = plot_spectrogram('./recording_3.wav')
            st.pyplot(fig)
            st.write(predict_word('./recording_1.png'))

    # Play back the recordings
    if st.button("Calulation"):
        first_num = predict_word('./recording_1.png')
        opreation = predict_word('./recording_2.png')
        second_num =predict_word('./recording_3.png')
        if opreation == 'plus':
            print(f"{first_num} + {second_num} = {first_num + second_num}")
        elif opreation == 'times':
            print(f"{first_num} * {second_num} = {first_num * second_num}")
        elif opreation == 'divided_by':
            print(f"{first_num} / {second_num} = {first_num / second_num}")
        elif opreation == 'minus':
            print(f"{first_num} - {second_num} = {first_num - second_num}")


from dataclasses import dataclass

'''
Constants used across the microservice
'''

@dataclass
class Face:
    left = None
    right = None
    letter: str

@dataclass
class Panel:
    position: int
    left = None
    right = None
    up = None
    down = None

#-----------------------------------
#  Mapping of cube element positions to mnemonic names
#  Each mnemonic is a three-character pattern, frc, where
#       f indicates the face and is one of F, R, B, L, U, D
#       r indicates the row and is one of T, M, B (for top, middle, bottom, respectively)
#       c indicates the column and is one of L, M, R (for left, middle, right, repectively)
#  The regex for the pattern is r'[FRBLUD][TMB][LMR]'
#
# Front face
FTL = 0
FTM = 1
FTR = 2
FML = 3
FMM = 4
FMR = 5
FBL = 6
FBM = 7
FBR = 8

# Right face
RTL = 9
RTM = 10
RTR = 11
RML = 12
RMM = 13
RMR = 14
RBL = 15
RBM = 16
RBR = 17

# Back face
BTL = 18
BTM = 19
BTR = 20
BML = 21
BMM = 22
BMR = 23
BBL = 24
BBM = 25
BBR = 26

# Left face
LTL = 27
LTM = 28
LTR = 29
LML = 30
LMM = 31
LMR = 32
LBL = 33
LBM = 34
LBR = 35

# Up face
UTL = 36
UTM = 37
UTR = 38
UML = 39
UMM = 40
UMR = 41
UBL = 42
UBM = 43
UBR = 44

#Down face
DTL = 45
DTM = 46
DTR = 47
DML = 48
DMM = 49
DMR = 50
DBL = 51
DBM = 52
DBR = 53

# Cube Params
NUM_ELEMENTS = 54
NUM_FACES = 6
VALID_DIRECTIONS = "FfBbLlRrUu"

# Triggers
FRONT = Face('f')
RIGHT = Face('r')
LEFT = Face('l')
BACK = Face('b')

FRONT.right = RIGHT
FRONT.left = LEFT

RIGHT.right = BACK
RIGHT.left = FRONT

LEFT.right = FRONT
LEFT.left = BACK

BACK.right = LEFT
BACK.left = RIGHT

# Panels
FTL_PANEL = Panel(FTL)
FTM_PANEL = Panel(FTM)
FTR_PANEL = Panel(FTR)
FML_PANEL = Panel(FML)
FMM_PANEL = Panel(FMM)
FMR_PANEL = Panel(FMR)
FBL_PANEL = Panel(FBL)
FBM_PANEL = Panel(FBM)
FBR_PANEL = Panel(FBR)

RTL_PANEL = Panel(RTL)
RTM_PANEL = Panel(RTM)
RTR_PANEL = Panel(RTR)
RML_PANEL = Panel(RML)
RMM_PANEL = Panel(RMM)
RMR_PANEL = Panel(RMR)
RBL_PANEL = Panel(RBL)
RBM_PANEL = Panel(RBM)
RBR_PANEL = Panel(RBR)

BTL_PANEL = Panel(BTL)
BTM_PANEL = Panel(BTM)
BTR_PANEL = Panel(BTR)
BML_PANEL = Panel(BML)
BMM_PANEL = Panel(BMM)
BMR_PANEL = Panel(BMR)
BBL_PANEL = Panel(BBL)
BBM_PANEL = Panel(BBM)
BBR_PANEL = Panel(BBR)

LTL_PANEL = Panel(LTL)
LTM_PANEL = Panel(LTM)
LTR_PANEL = Panel(LTR)
LML_PANEL = Panel(LML)
LMM_PANEL = Panel(LMM)
LMR_PANEL = Panel(LMR)
LBL_PANEL = Panel(LBL)
LBM_PANEL = Panel(LBM)
LBR_PANEL = Panel(LBR)

UTL_PANEL = Panel(UTL)
UTM_PANEL = Panel(UTM)
UTR_PANEL = Panel(UTR)
UML_PANEL = Panel(UML)
UMM_PANEL = Panel(UMM)
UMR_PANEL = Panel(UMR)
UBL_PANEL = Panel(UBL)
UBM_PANEL = Panel(UBM)
UBR_PANEL = Panel(UBR)

DTL_PANEL = Panel(DTL)
DTM_PANEL = Panel(DTM)
DTR_PANEL = Panel(DTR)
DML_PANEL = Panel(DML)
DMM_PANEL = Panel(DMM)
DMR_PANEL = Panel(DMR)
DBL_PANEL = Panel(DBL)
DBM_PANEL = Panel(DBM)
DBR_PANEL = Panel(DBR)

# FRONT
FTL_PANEL.left = LTR_PANEL
FTL_PANEL.up = UBL_PANEL

FTM_PANEL.up = UBM_PANEL

FTR_PANEL.up = UBR_PANEL
FTR_PANEL.right = RTL_PANEL

FML_PANEL.left = LMR_PANEL

FMR_PANEL.right = RML_PANEL

FBL_PANEL.left = LBR_PANEL
FBL_PANEL.down = DTL_PANEL

FBM_PANEL.down = DTM_PANEL

FBR_PANEL.down = DTR_PANEL
FBR_PANEL.right = RBL_PANEL

# RIGHT
RTL_PANEL.left = FTR_PANEL
RTL_PANEL.up = UBR_PANEL

RTM_PANEL.up = UMR_PANEL

RTR_PANEL.up = UTR_PANEL
RTR_PANEL.right = BTL_PANEL

RML_PANEL.left = FMR_PANEL

RMR_PANEL.right = BML_PANEL

RBL_PANEL.left = FBR_PANEL
RBL_PANEL.down = DTR_PANEL

RBM_PANEL.down = DMR_PANEL

RBR_PANEL.down = DBR_PANEL
RBR_PANEL.right = BBL_PANEL

# BACK
BTL_PANEL.left = RTR_PANEL
BTL_PANEL.up = UTR_PANEL

BTM_PANEL.up = UTM_PANEL

BTR_PANEL.up = UTL_PANEL
BTR_PANEL.right = LTL_PANEL

BML_PANEL.left = RMR_PANEL

BMR_PANEL.right = LML_PANEL

BBL_PANEL.left = RBR_PANEL
BBL_PANEL.down = DBR_PANEL

BBM_PANEL.down = DBM_PANEL

BBR_PANEL.down = DBL_PANEL
BBR_PANEL.right = LBL_PANEL

# LEFT
LTL_PANEL.left = BTR_PANEL
LTL_PANEL.up = UTL_PANEL

LTM_PANEL.up = UML_PANEL

LTR_PANEL.up = UBL_PANEL
LTR_PANEL.right = FTL_PANEL

LML_PANEL.left = BMR_PANEL

LMR_PANEL.right = FML_PANEL

LBL_PANEL.left = BBR_PANEL
LBL_PANEL.down = DBL_PANEL

LBM_PANEL.down = DML_PANEL

LBR_PANEL.down = DTL_PANEL
LBR_PANEL.right = FBL_PANEL

# UP
UTL_PANEL.left = LTL_PANEL
UTL_PANEL.up = BTR_PANEL

UTM_PANEL.up = BTM_PANEL

UTR_PANEL.up = BTL_PANEL
UTR_PANEL.right = RTR_PANEL

UML_PANEL.left = LTM_PANEL

UMR_PANEL.right = RTM_PANEL

UBL_PANEL.left = LTR_PANEL
UBL_PANEL.down = FTL_PANEL

UBM_PANEL.down = FTM_PANEL

UBR_PANEL.down = FTR_PANEL
UBR_PANEL.right = RTL_PANEL

# DOWN
DTL_PANEL.left = LBR_PANEL
DTL_PANEL.up = FBL_PANEL

DTM_PANEL.up = FBM_PANEL

DTR_PANEL.up = FBR_PANEL
DTR_PANEL.right = RBL_PANEL

DML_PANEL.left = LBM_PANEL

DMR_PANEL.right = RBM_PANEL

DBL_PANEL.left = LBL_PANEL
DBL_PANEL.down = BBR_PANEL

DBM_PANEL.down = BBM_PANEL

DBR_PANEL.down = BBL_PANEL
DBR_PANEL.right = RBR_PANEL

PANEL_LIST = [FTL_PANEL, FTM_PANEL, FTR_PANEL, FML_PANEL, FMM_PANEL, FMR_PANEL, FBL_PANEL, FBM_PANEL, FBR_PANEL,
              RTL_PANEL, RTM_PANEL, RTR_PANEL, RML_PANEL, RMM_PANEL, RMR_PANEL, RBL_PANEL, RBM_PANEL, RBR_PANEL,
              BTL_PANEL, BTM_PANEL, BTR_PANEL, BML_PANEL, BMM_PANEL, BMR_PANEL, BBL_PANEL, BBM_PANEL, BBR_PANEL,
              LTL_PANEL, LTM_PANEL, LTR_PANEL, LML_PANEL, LMM_PANEL, LMR_PANEL, LBL_PANEL, LBM_PANEL, LBR_PANEL,
              UTL_PANEL, UTM_PANEL, UTR_PANEL, UML_PANEL, UMM_PANEL, UMR_PANEL, UBL_PANEL, UBM_PANEL, UBR_PANEL,
              DTL_PANEL, DTM_PANEL, DTR_PANEL, DML_PANEL, DMM_PANEL, DMR_PANEL, DBL_PANEL, DBM_PANEL, DBR_PANEL]


import math
import matplotlib.pyplot as plt

n= 100
def cal_aprox_pi(n):

    pi= 0

    for i in range(n):
        numerador = (2**i)*(math.factorial(i)**2)
        denomidador = math.factorial(2*i+1)
        fraction = numerador/denomidador

        pi += fraction
    pi = 2*pi

    return pi
list_euler = []
Err_list_euler = []

for i in range(1, n):
    aprox_pi = cal_aprox_pi(i)
    list_euler.append(aprox_pi)

    Err_real = math.pi - aprox_pi
    Err_abs = abs(Err_real)
    Err_relativ = abs(Err_real/math.pi)

    Err_list_euler.append(Err_relativ)
    print("%d \t %f \t %f \t %f \t %.4f " % (i, aprox_pi, Err_real, Err_abs,Err_relativ*100 ))

plt.figure("Serie de Euler")
plt.plot([0, n], [math.pi, math.pi], "g-")
plt.plot(list_euler , "bo-", label="Serie de Euler")
plt.xlabel("n")
plt.ylabel(u"$\pi$")
plt.grid(ls="dashed")
plt.legend()

plt.figure("Gráfica del Error")
plt.plot(Err_list_euler, "bo-", label=" Serie de Euler")
plt.xlabel("n")
plt.ylabel(u"$\% error$")
plt.grid(ls="dashed")
plt.legend()

plt.show()


# https://leetcode.com/problems/linked-list-cycle/

class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None

class Solution:
    def hasCycle(self, head: ListNode) -> bool:
        myHash = {}

        pointer = head

        while pointer:
            if pointer in myHash:
                return True
            else:
                myHash[pointer] = 1
            pointer = pointer.next
        return False

root = ListNode(3)
node2 = ListNode(2)
node0 = ListNode(0)
node4 = ListNode(4)

root.next = node2
node2.next = node0
node0.next = node4
node4.next = node2

print(Solution().hasCycle(root))


# -*- coding: utf-8 -*-
"""
Created on Tue Jun 29 19:53:53 2021

@author: hosam
"""

import requests
import pandas as pd
statesList=requests.get('https://chanakyya.com/Chanakya/states.json').json()
state=[]
for stateName in statesList:
    state.append(stateName['stateName'])

state.remove('Jammu&Kashmir') #Data Not AVailable
FinalWeakAndStrong=pd.DataFrame()
booth=[]
for stateName in state:

    a=requests.get('https://chanakyya.com/Chanakya/'+stateName+'/'+stateName+'.json?isNewDataFormat=true').json()
    b=pd.DataFrame.from_dict(a['STRONG_WEAK_BOOTH_DATA'].items())
    b['State']=stateName
    FinalWeakAndStrong=FinalWeakAndStrong.append(b)

    c=pd.DataFrame.from_dict(a['ASSEMBLY_NAME_DATA'].items())
    for x in c[1]:
        assembly=requests.get('https://chanakyya.com/Chanakya/'+stateName+'/AssemblyData/'+x).json()
        print(assembly['ELECTION_DATA']['boothFileName'])
        booth.append([stateName, x,assembly['ELECTION_DATA']['boothFileName']])

FinalBooth=pd.DataFrame(booth,columns=['State', 'Assembly','Booth File'])
FinalBooth.to_csv('C:/Users/hosam/Documents/Project/Election Data/Programs/Booth Files Data.csv')
FinalWeakAndStrong.to_csv('C:/Users/hosam/Documents/Project/Election Data/Programs/StrongAndWeakData.csv')


from flask import jsonify, abort, make_response, request, Blueprint
from .models import parcels

NOT_FOUND = 'data NOT found'
BAD_REQUEST = 'Bad request'

v1_blueprint = Blueprint(
    'v1', __name__
)

def _get_order(id):
    return [parcel for parcel in parcels if parcel['id'] == id]

def _entry_exists_for_delivery_order(item_name):
    return [parcel for parcel in parcels if parcel["item_name"] == item_name]

@v1_blueprint.errorhandler(404)
def not_found(error):
    return make_response(jsonify({'error': NOT_FOUND}), 404)

@v1_blueprint.errorhandler(400)
def bad_request(error):
    return make_response(jsonify({'error': BAD_REQUEST}), 400)

@v1_blueprint.route('/api/v1')
def index():
    return jsonify({"welcome": "crackers ni wale wase"})

@v1_blueprint.route('/api/v1/parcels', methods=['POST'])
def post_delivery_order():
    item_id = 0
    if not request.json or 'item_name' not in request.json:
        abort(400)
    orders = parcels
    if len(orders) == 0:
        item_id = 1
    else:
        item_id = parcels[-1].get("id") + 1

    owner_id = request.json.get('owner_id')
    item_name = request.json.get('item_name')
    origin = request.json.get('origin')
    pickup_location = request.json.get('pickup_location')
    price = request.json.get('price')
    status = request.json.get('status')

    if _entry_exists_for_delivery_order(item_name):
        return jsonify({'message': "entry exists"})
    parcel = {
        "id": item_id,
        "owner_id": owner_id,
        "item_name": item_name,
        "origin": origin,
        "pickup_location": pickup_location,
        "price": price,
        "status": status
    }
    parcels.append(parcel)
    return jsonify({'parcel': parcel}), 201

@v1_blueprint.route('/api/v1/parcels', methods=['GET'])
def get_all_parcel_orders():
    orders = parcels
    if len(orders) == 0:
        return jsonify({'message': 'no orders have been posted'})
    return jsonify({'all orders': parcels})

# get a particular parcel delivery order
@v1_blueprint.route('/api/v1/parcels/<int:id>', methods=['GET'])
def get_particular_parcel_order(id):
    order = _get_order(id)
    if not order:
        abort(404)
    return jsonify({'order': order})

# get parcel orders belonging to a particular user
@v1_blueprint.route('/api/v1/users/<int:id>/parcels', methods=['GET'])
def get_user_parcel_delivery_orders(id):
    parcel = [parcel for parcel in parcels if parcel['owner_id'] == id]
    if not parcel:
        abort(404)
    return jsonify({"parcels": parcel})

@v1_blueprint.route('/api/v1/parcels/<int:id>/cancel', methods=['PUT'])
def cancel_delivery_order(id):
    if not request.json:
        abort(400)
    orders = _get_order(id)
    if not orders:
        abort(404)
    elif orders[0]['status'] == "delivered":
        return jsonify({"error": "order has already been delivered!!"})
    elif orders[0]['status'] == "cancelled":
        return jsonify({"error": "order has already been cancelled!!"})
    orders[0]['status'] = "cancelled"
    return jsonify({'delivery order': orders})


from pyhanlp import HanLP
from tqdm import tqdm
import os

def segmentKey():
    input_dir = "../../dataset/result/2-extract/queries.result"
    output_dir_prefix = "../dataset/result/3-segment/hanlp/normal_segmented_"
    keywords = []
    output_dirs = []
    with open("../../keyword.txt", "r", encoding="utf8") as keyword_file, open(input_dir, "r", encoding="utf8") as input_file:
        for line in keyword_file:
            keyword = line.strip()
            HanLP.Config.CustomDictionary.add(keyword)  # 添加用户自定义词汇
            keywords.append(keyword)
            output_dirs.append(output_dir_prefix + keyword + ".result")

        # 检查文件是否存在或不为空
        for output_file in output_dirs:
            if os.path.exists(output_file) and os.path.getsize(output_file) > 0:
                with open(output_file, 'w', encoding="utf8") as output_file:
                    # 清空文件内容
                    output_file.truncate()

        # 寻找关键字并分词
        for line in tqdm(input_file, desc="Processing", ncols=100):
            for keyword in keywords:
                if keyword in line.strip():
                    word_list = HanLP.segment(line.strip())  # 使用HanLP进行分词
                    word_list = [term.word for term in word_list]  # 获取分词结果中的词语部分
                    with open(output_dir_prefix + keyword + ".result", "a", encoding="utf8") as output_file:
                        output_file.write(" ".join(word_list) + "\n")  # 写入换行符保持原始行结构

if __name__ == '__main__':
    segmentKey()


#!/usr/bin/env python
# -*- coding: utf-8 -*-
import cv2
if __name__ == '__main__':
    # KCF
    tracker = cv2.TrackerKCF_create()
    # Boosting
    #tracker = cv2.TrackerBoosting_create()
    # MedianFlow
    # tracker = cv2.TrackerMedianFlow_create()

    cap = cv2.VideoCapture(2)
    while True:
        ret, frame = cap.read()
        if not ret:
            continue
        bbox = cv2.selectROI(frame, False)
        ok = tracker.init(frame, bbox)
        cv2.destroyAllWindows()
        break
    while True:
        ret, frame = cap.read()
        # トラッカーをアップデートする
        track, bbox = tracker.update(frame)
        if track:
            # Tracking success
            p1 = (int(bbox[0]), int(bbox[1]))
            p2 = (int(bbox[0] + bbox[2]), int(bbox[1] + bbox[3]))
            cv2.rectangle(frame, p1, p2, (0,255,0), 2, 1)
        else :
            cv2.putText(frame, "Failure", (10,50), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0,255,0), 1, cv2.LINE_AA);
        # 加工済の画像を表示する
        cv2.imshow("Tracking", frame)

        # キー入力を1ms待って、k が27（ESC）だったらBreakする
        k = cv2.waitKey(1)
        if k == 27 :
            break

# キャプチャをリリースして、ウィンドウをすべて閉じる
cap.release()
cv2.destroyAllWindows()


def longest_unique_substring(s: str) -> int:
    s_len = len(s)
    if s_len <= 1:
        return s_len
    longest_len = temp_len = 0
    start = end = 0
    visited = dict()
    while start < s_len and end < s_len:
        while end < s_len and s[end] not in visited:
            temp_len += 1
            visited[s[end]] = end
            end += 1
        longest_len = max(longest_len, temp_len)
        if end == s_len:
            break
        end = start = (visited.pop(s[end]) + 1)
        visited = dict()
        temp_len = 0
    return longest_len


import json
import re
import pandas as pd

with open('new_output2.csv', 'r') as f:
     reader = pd.read_csv(f)
     for story in reader.values.tolist():
          story_id = story[0]
          # Make Answer list
          ans = story[2].split("|")
          ans_list = []
          for elem in ans:
               if "," in elem:
                    split_elem = elem.split(",")
                    for elem2 in split_elem:
                         ans_list.append(elem2)
               elif ":" in elem:
                    ans_list.append(elem)
          # Make story word list
          count = 0
          story_word_list = re.sub("\s+", " ", story[6]).split(" ")
          # # Output sample
          # print(story[6])
          # print("Question:", story[1])
          # print("Answer:", ans)
          # for elem in ans_list:
          #      split_elem = elem.split(":")
          #      print("\t", story[6][int(split_elem[0]):int(split_elem[1])])
          # Search word index number
          answer_list = []
          for elem in ans_list:
               split_elem = elem.split(":")
               start_index = re.sub("\s+", " ", story[6][:int(split_elem[0])]).count(" ")
               end_index = re.sub("\s+", " ", story[6][:int(split_elem[1])]).count(" ")
               answer_list.append(str(start_index)+":"+str(end_index))
               # for elem in range(start_index, end_index):
               #      print(story_word_list[elem], end=" ")
               # print()
          print(story_id+';'+str(answer_list))


# LAST WEEK'S PROVE ASSIGNMENT HELP #

word = 'cat'

guess = 'bat'

i = 0

solved = ''

0 < 3

#SOLUTION USING A WHILE LOOP
while i < len(word):
    if word[i] == guess[i]:
        solved += f' {guess[i].upper()}'
    elif guess[i] in word:
        solved += f' {guess[i].lower()}'
    else:
        solved += ' _ '
    i += 1

print(solved)

#SOLUTION USING A FOR LOOP; for [index], [var] in enumerate ([list]/[str])
for char in enumerate(word):
    if char == guess[i]:
        solved += f' {guess[i].upper()}'
    elif guess[i] in word:
        solved += f' {guess[i].lower()}'
    else:
        solved += ' _ '

print(solved)


import pygame
pygame.init()

FPS = 60
clock = pygame.time.Clock()

WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
BLACK = (0, 0, 0)
YELLOW = (255, 255, 0)

W, H = 400, 600
sc = pygame.display.set_mode((W, H))
sc.fill(WHITE)
pygame.display.set_caption("PAINT")

color = BLACK
shape = 'line'
width = 10
startPos, endPos = 0, 0
run = True

while run:
    for event in pygame.event.get():

        pressed = pygame.key.get_pressed()
        ctrl_pressed = pressed[pygame.K_RCTRL] or pressed[pygame.K_LCTRL]

        if event.type == pygame.QUIT:
            run = False

        if event.type == pygame.KEYDOWN:
            if pressed[pygame.K_DOWN] and width > 1:
                width -= 1
            if pressed[pygame.K_UP]:
                width += 1
            if pressed[pygame.K_b]:
                color = BLUE
            if pressed[pygame.K_r]:
                color = RED
            if pressed[pygame.K_g]:
                color = GREEN
            if ctrl_pressed and pressed[pygame.K_l]:
                shape = 'line'
            if ctrl_pressed and pressed[pygame.K_e]:
                shape = 'eraser'
            if ctrl_pressed and pressed[pygame.K_c]:
                shape = 'circle'
            if ctrl_pressed and pressed[pygame.K_r]:
                shape = 'rectangle'

        if shape == 'line' or shape == 'eraser':
            if event.type == pygame.MOUSEBUTTONDOWN:
                startPos = pygame.mouse.get_pos()
            if event.type == pygame.MOUSEMOTION:
                endPos = pygame.mouse.get_pos()
                if startPos:
                    if shape == 'line':
                        pygame.draw.line(sc, color, startPos, endPos, width)
                    if shape == 'eraser':
                        pygame.draw.line(sc, WHITE, startPos, endPos, width)
                    startPos = endPos
            if event.type == pygame.MOUSEBUTTONUP:
                startPos = None
        else:
            if event.type == pygame.MOUSEBUTTONDOWN:
                startPos = pygame.mouse.get_pos()
            if event.type == pygame.MOUSEBUTTONUP:
                endPos = pygame.mouse.get_pos()
                if shape == 'rectangle':
                    x = min(startPos[0], endPos[0])
                    y = min(startPos[1], endPos[1])
                    lx = abs(startPos[0]-endPos[0])
                    ly = abs(startPos[1]-endPos[1])
                    pygame.draw.rect(sc, color, (x, y, lx, ly), width)
                if shape == 'circle':
                    x = (startPos[0]+endPos[0])/2
                    y = (startPos[1]+endPos[1])/2
                    rx = abs(startPos[0]-endPos[0])/2
                    ry = abs(startPos[1]-endPos[1])/2
                    r = (rx + ry)/2
                    pygame.draw.circle(sc, color, (x, y), r, width)

    pygame.display.update()
    clock.tick(FPS)

pygame.quit()


# 4. Wykorzystując moduł time i funkcję time obliczyć ile trwa pętla
#    składająca się z 100000 iteracji dla listy i dla typu tuple (np. sumowanie).
import time

if __name__ == '__main__':
    lista = list(range(10000000))
    mytuple = tuple(range(10000000))
    i = 0;
    t1 = time.time()
    for x in lista:
        i += 1
    t2 = time.time() - t1
    print(t2)

    for x in mytuple:
        i += 1
    t3 = time.time() - t1 - t2
    print(t3)


def is_prime(x):
    if x < 2:
        return False
    i = 2
    while i * i <= x:
        if x % i == 0:
            return False
        i += 1
    return True

n = int(input())
nums = [int(i) for i in input().split(" ")]
result = 0
for x in nums:
    if is_prime(x):
        result += 1
print(result)


from data_structures.binaryTree import Node

def traverse(root):
    nodes = [root]
    result = []

    while len(nodes) > 0:
        node = nodes.pop()
        result.append(node.data)

        if node.right != None:
            nodes.append(node.right)

        if node.left != None:
            nodes.append(node.left)

    return result

tree = Node(5)
tree.left = Node(4)
tree.left.left = Node(11)
tree.left.left.left = Node(7)
tree.left.left.right = Node(2)
tree.right = Node(8)
tree.right.left = Node(13)
tree.right.right = Node(4)
tree.right.right.right = Node(1)

print(traverse(tree)) # [5,4,11,7,2,8,13,4,1]