from typing import List

import cirq
import numpy as np

from mitiq import QPROGRAM, Observable, PauliString
from mitiq.interface import convert_to_mitiq
from mitiq.interface.mitiq_cirq import compute_density_matrix
from mitiq.qse import (
    execute_with_qse,
    get_projector,
    mitigate_executor,
    qse_decorator,
)
from mitiq.qse.qse_utils import (
    _compute_hamiltonian_overlap_matrix,
    _compute_overlap_matrix,
)

def execute_with_depolarized_noise(circuit: QPROGRAM) -> np.ndarray:
    return compute_density_matrix(
        convert_to_mitiq(circuit)[0],
        noise_model_function=cirq.depolarize,
        noise_level=(0.01,),
    )

def batched_execute_with_depolarized_noise(circuits) -> List[np.ndarray]:
    return [execute_with_depolarized_noise(circuit) for circuit in circuits]

def execute_no_noise(circuit: QPROGRAM) -> np.ndarray:
    return compute_density_matrix(
        convert_to_mitiq(circuit)[0], noise_level=(0,)
    )

def test_execute_with_qse_no_noise():
    qc = prepare_logical_0_state_for_5_1_3_code()
    (
        check_operators,
        code_hamiltonian,
    ) = get_5_1_3_code_check_operators_and_code_hamiltonian()
    observable = get_observable_in_code_space(PauliString("ZZZZZ"))
    mitigated_value = execute_with_qse(
        qc, execute_no_noise, check_operators, code_hamiltonian, observable
    )
    assert np.isclose(mitigated_value.real, 1)

    observable = get_observable_in_code_space(PauliString("XXXXX"))
    mitigated_value = execute_with_qse(
        qc, execute_no_noise, check_operators, code_hamiltonian, observable
    )
    assert np.isclose(mitigated_value.real, 0.5)

def test_execute_with_qse():
    qc = prepare_logical_0_state_for_5_1_3_code()
    (
        check_operators,
        code_hamiltonian,
    ) = get_5_1_3_code_check_operators_and_code_hamiltonian()
    observable = get_observable_in_code_space(PauliString("ZZZZZ"))
    unmitigated_value = observable.expectation(
        qc, execute_with_depolarized_noise
    )
    mitigated_value = execute_with_qse(
        qc,
        execute_with_depolarized_noise,
        check_operators,
        code_hamiltonian,
        observable,
    )
    assert abs(mitigated_value.real - 1) < abs(unmitigated_value.real - 1)

    observable = get_observable_in_code_space(PauliString("XXXXX"))
    unmitigated_value = observable.expectation(
        qc, execute_with_depolarized_noise
    )
    mitigated_value = execute_with_qse(
        qc,
        execute_with_depolarized_noise,
        check_operators,
        code_hamiltonian,
        observable,
    )
    assert abs(mitigated_value.real - 0.5) < abs(unmitigated_value.real - 0.5)

def test_mitigate_executor_batched():
    qc = prepare_logical_0_state_for_5_1_3_code()
    (
        check_operators,
        code_hamiltonian,
    ) = get_5_1_3_code_check_operators_and_code_hamiltonian()

    observable = get_observable_in_code_space(PauliString("XXXXX"))
    batched_mitigated_executor = mitigate_executor(
        batched_execute_with_depolarized_noise,
        check_operators,
        code_hamiltonian,
        observable,
    )
    unmitigated_value = observable.expectation(
        qc, execute_with_depolarized_noise
    )

    batched_mitigated_values = batched_mitigated_executor([qc] * 3)
    assert all(
        abs(mitigated_value.real - 0.5) < abs(unmitigated_value.real - 0.5)
        for mitigated_value in batched_mitigated_values
    )

def test_qse_decorator():
    qc = prepare_logical_0_state_for_5_1_3_code()
    (
        check_operators,
        code_hamiltonian,
    ) = get_5_1_3_code_check_operators_and_code_hamiltonian()
    observable = get_observable_in_code_space(PauliString("ZZZZZ"))

    @qse_decorator(
        check_operators=check_operators,
        code_hamiltonian=code_hamiltonian,
        observable=observable,
    )
    def decorated_executor(circuit: QPROGRAM) -> np.ndarray:
        return compute_density_matrix(
            convert_to_mitiq(circuit)[0],
            noise_model_function=cirq.depolarize,
            noise_level=(0.01,),
        )

    unmitigated_value = observable.expectation(
        qc, execute_with_depolarized_noise
    )
    mitigated_value = decorated_executor(qc)
    assert abs(mitigated_value.real - 1) < abs(unmitigated_value.real - 1)

    observable = get_observable_in_code_space(PauliString("XXXXX"))

    @qse_decorator(
        check_operators=check_operators,
        code_hamiltonian=code_hamiltonian,
        observable=observable,
    )
    def decorated_executor(circuit: QPROGRAM) -> np.ndarray:
        return compute_density_matrix(
            convert_to_mitiq(circuit)[0],
            noise_model_function=cirq.depolarize,
            noise_level=(0.01,),
        )

    unmitigated_value = observable.expectation(
        qc, execute_with_depolarized_noise
    )
    mitigated_value = decorated_executor(qc)
    assert abs(mitigated_value.real - 0.5) < abs(unmitigated_value.real - 0.5)

def test_get_projector():
    qc = prepare_logical_0_state_for_5_1_3_code()
    (
        check_operators,
        code_hamiltonian,
    ) = get_5_1_3_code_check_operators_and_code_hamiltonian()
    P = get_projector(qc, execute_no_noise, check_operators, code_hamiltonian)
    uniform_projector = Observable(*[-0.25 * c for c in check_operators])
    assert P == uniform_projector

def test_compute_overlap_matrix():
    qc = prepare_logical_0_state_for_5_1_3_code()
    (
        check_operators,
        _,
    ) = get_5_1_3_code_check_operators_and_code_hamiltonian()
    S = _compute_overlap_matrix(qc, execute_no_noise, check_operators, {})
    assert np.allclose(S, np.ones(16))

    S = _compute_overlap_matrix(
        qc, execute_with_depolarized_noise, check_operators, {}
    )
    # assert that S's diagonal is all ones but the off-diagonal elements
    #  are less than 1.
    # Diagonal terms are all 1's because we are computing
    # <Ψ|C_i C_i|Ψ> = <Ψ|Ψ> = 1
    assert np.allclose(np.diag(np.diag(S)), np.eye(16))
    # Check that all off diagonal entries of S are the same and less than 1
    # Off diagonal terms are less than 1 because we are computing <Ψ|C_i C_j|Ψ>
    # = <Ψ|C_k|Ψ> < 1 (since |Ψ> was rotated a bit from the logical subspace)
    # All off diagonal terms are the same because of the symmetry of the
    # total depolarizing noise.
    off_diag_elements = S[np.where(~np.eye(16, dtype=bool))]
    np.allclose(off_diag_elements, off_diag_elements[0])
    assert off_diag_elements[0] < 1

def test_compute_hamiltonian_overlap_matrix():
    qc = prepare_logical_0_state_for_5_1_3_code()
    (
        check_operators,
        code_hamiltonian,
    ) = get_5_1_3_code_check_operators_and_code_hamiltonian()

    # If we have a full set of check operators that form a group then all
    # entries of the H matrix should be the same.
    # H_jk = sum over all i's <Ψ|C_i|Ψ>

    H = _compute_hamiltonian_overlap_matrix(
        qc, execute_no_noise, check_operators, code_hamiltonian, {}
    )
    assert np.allclose(H, -16 * np.ones(16))

    H = _compute_hamiltonian_overlap_matrix(
        qc,
        execute_with_depolarized_noise,
        check_operators,
        code_hamiltonian,
        {},
    )
    assert np.allclose(H, H[0][0])
    assert H[0][0].real > -16

def get_observable_in_code_space(observable: List[cirq.PauliString]):
    FIVE_I = PauliString("IIIII")
    projector_onto_code_space = [
        PauliString("XZZXI"),
        PauliString("IXZZX"),
        PauliString("XIXZZ"),
        PauliString("ZXIXZ"),
    ]

    observable_in_code_space = Observable(FIVE_I)
    all_paulis = projector_onto_code_space + [observable]
    for g in all_paulis:
        observable_in_code_space *= 0.5 * Observable(FIVE_I, g)
    return observable_in_code_space

def get_5_1_3_code_check_operators_and_code_hamiltonian() -> tuple:
    """
    Returns the check operators and code Hamiltonian for the [[5,1,3]] code
    The check operators are computed from the stabilizer generators:
    (1+G1)(1+G2)(1+G3)(1+G4)  G = [XZZXI, IXZZX, XIXZZ, ZXIXZ]
    source: https://en.wikipedia.org/wiki/Five-qubit_error_correcting_code
    """
    Ms = [
        "YIYXX",
        "ZIZYY",
        "IXZZX",
        "ZXIXZ",
        "YYZIZ",
        "XYIYX",
        "YZIZY",
        "ZZXIX",
        "XZZXI",
        "ZYYZI",
        "IYXXY",
        "IZYYZ",
        "YXXYI",
        "XXYIY",
        "XIXZZ",
        "IIIII",
    ]
    Ms_as_pauliStrings = [
        PauliString(M, coeff=1, support=range(5)) for M in Ms
    ]
    negative_Ms_as_pauliStrings = [
        PauliString(M, coeff=-1, support=range(5)) for M in Ms
    ]
    Hc = Observable(*negative_Ms_as_pauliStrings)
    return Ms_as_pauliStrings, Hc

def prepare_logical_0_state_for_5_1_3_code():
    """
    To simplify the testing logic. We hardcode the the logical 0 and logical 1
    states of the [[5,1,3]] code, copied from:
    https://en.wikipedia.org/wiki/Five-qubit_error_correcting_code
    We then use Gram-Schmidt orthogonalization to fill up the rest of the
    matrix with orthonormal vectors.
    Following this we construct a circuit that has this matrix as its gate.
    """

    def gram_schmidt(
        orthogonal_vecs: List[np.ndarray],
    ) -> np.ndarray:
        # normalize input
        orthonormalVecs = [
            vec / np.sqrt(np.vdot(vec, vec)) for vec in orthogonal_vecs
        ]
        dim = np.shape(orthogonal_vecs[0])[0]  # get dim of vector space
        for i in range(dim - len(orthogonal_vecs)):
            new_vec = np.zeros(dim)
            new_vec[i] = 1  # construct ith basis vector
            projs = sum(
                [
                    np.vdot(new_vec, cached_vec) * cached_vec
                    for cached_vec in orthonormalVecs
                ]
            )  # sum of projections of new vec with all existing vecs
            new_vec -= projs
            orthonormalVecs.append(
                new_vec / np.sqrt(np.vdot(new_vec, new_vec))
            )
        return np.reshape(orthonormalVecs, (32, 32)).T

    logical_0_state = np.zeros(32)

    # bitstrings ["00000", "10010", "01001", "10100", "01010", "00101"]
    np.put(logical_0_state, [0, 18, 9, 20, 10, 5], 1 / 4)

    # bitstrings: [
    #  "11011", "00110", "11000", "11101", "00011",
    #  "11110", "01111", "10001", "01100", "10111"
    # ]
    np.put(logical_0_state, [27, 6, 24, 29, 3, 30, 15, 17, 12, 23], -1 / 4)

    logical_1_state = np.zeros(32)

    # bitstrings ["11111", "01101", "10110", "01011", "10101", "11010"]
    np.put(logical_1_state, [31, 13, 22, 11, 21, 26], 1 / 4)

    # bitstrings: [
    #  "00100", "11001", "00111", "00010", "11100",
    #  "00001", "10000", "01110", "10011", "01000"
    # ]
    np.put(logical_1_state, [4, 25, 7, 2, 28, 1, 16, 14, 19, 8], -1 / 4)

    # Fill up the rest of the matrix with orthonormal vectors
    matrix = gram_schmidt([logical_0_state, logical_1_state])
    circuit = cirq.Circuit()
    g = cirq.MatrixGate(matrix)
    qubits = cirq.LineQubit.range(5)
    circuit.append(g(*qubits))

    return circuit


from flask import request
from flask_restx import Resource

from app.modules.auth.auth_controller import AuthController
from app.modules.auth.auth_dto import AuthDto
from app.modules.auth.decorator import token_required
from app.modules.user.user_dto import UserDto

api = AuthDto.api
_auth_login = AuthDto.model_login
_user_info = UserDto.model_response

@api.route('/login')
class Login(Resource):
    '''
    API login
    '''

    # @api.expect(_auth)
    @api.expect(_auth_login)
    @api.response(code=200, model=_user_info, description='Model for user response on login.')
    def post(self):
        """
        Login user to the system.
        -------------
        :param email: the email of the user.

        :param password: the password of the user.

        :return: All information of user if he logged in and None if he did not log in.
        """
        post_data = request.json
        controller = AuthController()
        return controller.login_user(data=post_data)

@api.route('/logout')
class Logout(Resource):
    '''
    API logout
    '''

    @token_required
    def get(self):
        """
        Logout the user from the system.
        -------------

        :return:
        """
        # auth_header = request.headers.get('Authorization')
        # return ControllerAuth.logout_user(data=auth_header)
        # post_data = request.json
        controller = AuthController()
        return controller.logout_user(req=request)

@api.route('/info')
class UserInfor(Resource):
    '''
    API to get user information.

    After user logging in successfully, user will get token, and this token will be used to get information.
    '''

    @token_required
    @api.response(code=200, model=_user_info, description='Model for user information.')
    def get(self):
        """
        Get all user's information.

        :return: User's information.
        """
        controller = AuthController()
        return controller.get_user_info(request)
        # return AuthController.get_logged_user(request)


import sqlite3

__dbfile__ = 'data/cache.db'

# defines default order of selection
orders = {
    'engines': ['name', 'mass', 'impulse', 'exhaust', 'thrust', 'propellant'],
    'planets': ['name', 'distance', 'ra', 'dec'],
    'queries': ['origin','method','destination','engine']
}

class CacheError(Exception):
    pass

def INIT(replace=0):
    db = sqlite3.connect(__dbfile__)

    with open('utl/db_schema.txt','r') as schemaf:
        schema = schemaf.read().split('\n')
    if replace:
        for cmd in schema[2:]:
            try:
                db.execute(cmd)
            except sqlite3.OperationalError as ex:
                print(ex)
    for cmd in schema[:2]:
        db.execute(cmd)
    db.commit()
    db.close()

def search(query): # searches db for query

    def search_item(*args, **kwargs):
        table = kwargs['table']
        name = kwargs['name']

        order = ','.join(orders[table])
        db = sqlite3.connect(__dbfile__)
        result = db.execute('select %s from %s where name=?;' % (order, table), (name,))
        result = [item for item in result]
        if len(result):
            return dict(zip(orders[table], result[0])) # converts result to dictionary
        else:
            return False

    db = sqlite3.connect(__dbfile__)

    result = {}
    result['origin'] = search_item(table='planets',name=query['origin'])
    result['destination'] = search_item(table='planets',name=query['destination'])
    result['engine'] = search_item(table='engines',name=query['engine'])

    return result

def insert(*args, **kwargs):
    db = sqlite3.connect(__dbfile__)
    table = kwargs['table']
    values = kwargs['values'].items()

    # forms an ordering between columns and values
    # removes necessity for correctly ordering entries in values
    cols = '(%s)' % ','.join([item[0] for item in values]) # generates "(col1,col2,...)"
    contents = tuple([item[1] for item in values]) # argument tuple for insertion
    argfs = '(%s)' % ','.join(['?' for item in contents]) # generates "(?,?,...)"

    cmd = 'insert or ignore into %s %s values %s;' % (table, cols, argfs)
    db.execute(cmd, contents)
    db.commit()
    db.close()


import tensorflow as tf
from tensorflow import keras
from keras import backend as K

def f1(y_true, y_pred):  # Creacion de Pr, Re y F1
    y_true_f = K.flatten(y_true)
    y_pred_f = K.flatten(y_pred)
    tp = K.sum(y_true_f * y_pred_f)  # suma de una AND   son los True Points
    fp = K.sum(K.clip(K.clip(y_pred_f + y_true_f, 0, 1) - y_true_f, 0,1))  # k.clip (argumento, min, max) el argumento le da un minimo y un maximo
    fn = K.sum(K.clip(K.clip(y_pred_f + y_true_f, 0, 1) - y_pred_f, 0, 1))
    Pr = tp / (tp + fp)
    Re = tp / (tp + fn)
    f1t = 2 * (Pr * Re) / (Pr + Re)
    return f1t


from argparse import ArgumentParser

from hexeditlyylli import *

parser = ArgumentParser()
parser.add_argument("-f", "--file", action="store", dest="filename")
parser.add_argument("-l", "--no_of_line", action="store", type=int, dest="no_of_line", default=16)
parser.add_argument("-b", "--bytes_per_line", action="store", type=int, dest="bytes_per_line", default=16)

args = parser.parse_args()

view.main(args.filename, args.bytes_per_line, args.no_of_line)


from selenium import webdriver
from time import sleep

link = "https://www.google.com/"
browser = webdriver.Chrome()

try:
    browser.get(link)
    sleep(1)
    input_field = browser.find_element_by_css_selector('input[name="q"]')
    input_field.send_keys('курс доллара')
    input_field.click()
    sleep(1)
    button = browser.find_element_by_css_selector('input[name="btnK"]')
    button.click()
    sleep(2)
    num_field = browser.find_element_by_css_selector('div.H07hi > table > tbody > tr:nth-child(3) > td:nth-child(1) > input')
    num = num_field.get_attribute('value')
    print(f"Курс доллара: {num} грн за дол")

finally:
    sleep(3)
    browser.quit()


# importing required Libraries
import RPi.GPIO as GPIO
import time
import datetime
import serial
from gtts import gTTS
import pyttsx3
import os
import sys

# connection of hardwares with GPIO pin of Raspberry Pi
GPIO.setmode(GPIO.BOARD)

GPIO_TRIGGER = 18
GPIO_ECHO = 24
buzzer = 16
button_date = 22
button_sms = 13
GPIO.setup(buzzer, GPIO.OUT, initial=GPIO.LOW)
GPIO.setup(button_date, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(GPIO_TRIGGER, GPIO.OUT)
GPIO.setup(GPIO_ECHO, GPIO.IN)

# code for obstactle ditection
def distance():
    GPIO.output(GPIO_TRIGGER, True)
    time.sleep(0.00001)
    GPIO.output(GPIO_TRIGGER, False)
    StartTime = time.time()
    StopTime = time.time()

    while GPIO.input(GPIO_ECHO) == 0:
        StartTime = time.time()
    while GPIO.input(GPIO_ECHO) == 1:
        StopTime = time.time()
    TimeElapsed = StopTime - StartTime
    distance = (TimeElapsed * 34300) / 2
    return distance

# code for sending message
def sms():
    serial_port = "/dev/serial0"
    mob_num = "9804089456"

    # Enable Serial Communication
    ser = serial.Serial(serial_port, baudrate = 9600, timeout = 5)

    # Transmitting AT Commands to the Modem
    # '\r' indicates the Enter key
    ser.write(('AT'+'\r').encode())

    # Disable the Echo
    ser.write(('ATE0'+'\r').encode())
    #  Select Message format as Text mode
    ser.write(("AT+CMGF=1"+"\r").encode())
    print ("Text mode enabled....")
    time.sleep(1)
    # Sending a message to a particular Number
    ser.write(('AT+CMGS='+mob_num+'\r').encode())
    msg = "Pannic button integration testing1"
    print ("sending message")
    time.sleep(2)
    ser.write((msg+chr(50)).encode())

# code for alerting about the object and the distance in the form of sound
try:
    while True:
        button_state_date= GPIO.input(button_date)
        button_state_sms= GPIO.input(button_sms)
        dist = distance()
        distt = round(dist, 2)
        dis = str(distt)
        now = datetime.datetime.now()
        current_date = now.strftime("%Y-%m-%d")
        current_time = now.strftime("%H:%M:%S")
        engine = pyttsx3.init()

        # Button for Current date (Buton-1)
        if button_state_date == False:
            print('Button for date Pressed...')
            engine.say('The Current Date and Time is ' + current_date +'and'+ current_time)
            engine.runAndWait()
            engine.stop()
            # tts_en = gTTS('The Current Date and Time is ' + current_date_time , lang='hi')
            # tts_en.save("CurrentDateTime.mp3")
            # os.system("mpg321 -q CurrentDateTime.mp3")
            time.sleep(0.1)

        # Button for SMS Alert (Buton-2)
        elif button_state_sms == False:
            print('Button For SMS Pressed...')
            sms()

        elif (dist < 15):
            GPIO.output(buzzer, GPIO.HIGH)
            time.sleep(0.1)
            GPIO.output(buzzer, GPIO.LOW)
            print("Measured Distance = "+dis + " cm")
            print("Soo near")
            time.sleep(0.1)

        elif (dist > 15.0 and dist <= 25) :
            GPIO.output(buzzer, GPIO.HIGH)
            time.sleep(0.5)
            GPIO.output(buzzer, GPIO.LOW)
            print("Measured Distance = "+dis + " cm")
            print("near")
            time.sleep(0.1)

        elif(dist > 25 and dist <=100):
            print("Measured Distance = "+dis + " cm")
            print("Far")
            engine.say('the object is ' + dis + 'cm ahead ! be alert!')
            engine.runAndWait()
            engine.stop()
            #tts_en = gTTS('the object is ' + dis + 'cm ahead ! be alert!!', lang='hi')
            #tts_en.save("distance.mp3")
            #os.system("mpg321 -q distance.mp3")
            time.sleep(0.1)

except KeyboardInterrupt:
    GPIO.cleanup()


from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework_api_key.permissions import HasAPIKey
from rest_framework.response import Response
from core.response import HttpRes
from quotes.models import Quote
from quotes.serializers import QuoteSerializer
from core.utils import fetch_quotes, parse_key
from django.shortcuts import get_object_or_404

response_format = HttpRes().response

class QuoteView(APIView):
    permission_classes = [HasAPIKey]
    serializer_class = QuoteSerializer

    def post(self, request):
        # Fetch result from alphavantage
        response = fetch_quotes()

        # Clean up data
        currency_quote = response['Realtime Currency Exchange Rate']
        for key in list(currency_quote):
            new_key_name = parse_key(key)
            currency_quote[new_key_name] = currency_quote.pop(key)

        # Update datastore
        quotes_serializer = self.serializer_class(
            data=currency_quote)
        if quotes_serializer.is_valid():
            # We can move this operation to a redis server
            quotes_serializer.save()

        response_format['data'] = currency_quote
        response_format['message'] = 'Operation was successful'
        return Response(response_format)

    def get(self, request):

        quote = get_object_or_404(Quote, from_currency_code='BTC')
        quote_serializer = self.serializer_class(quote)

        response_format['data'] = quote_serializer.data
        response_format['message'] = 'Operation was successful'
        return Response(response_format)


#!/usr/bin/env python

import json
import urllib
from http.server import BaseHTTPRequestHandler, HTTPServer
from textwrap import dedent

#path to json library with device ID and friendly name
with open("IDdict.json") as f:
    ID2NAME = json.load(f)

class OsmAndHandler(BaseHTTPRequestHandler):
    def __init__(self, devices, *args):
        self.devices = devices
        BaseHTTPRequestHandler.__init__(self, *args)

    def do_GET(self):
        if not self.path.startswith("/id"):
            return

        data = urllib.parse.parse_qs(self.path)
        device_ip = self.client_address[0]
        device_id = (
            ID2NAME.get(data.get("/id", [None])[0]) or data.get("/id", [device_ip])[0]
        )
        device = {
            device_id: {
                "lat": data["lat"][0],  #latitude
                "lon": data["lon"][0],  #longitude
                "alt": data["alt"][0],  #altitude
                            }
        }
        self.devices.update(device)

        # Updated location, now write KML with ALL objects
        # Test script for browser: http://localhost:9000/id=111&lat=30&lon=-95&alt=0
        with open("tracker.kml", "w") as f:
            header = """\
            <?xml version="1.0" encoding="UTF-8"?>
            <kml xmlns="http://www.opengis.net/kml/2.2" xmlns:kml="http://www.opengis.net/kml/2.2">
            <Document>
                <Folder>
                    <name>GPS Tracker</name>
            """
            entry = """\
                    <Placemark>
                        <name>{device}</name>
                        <Point>
                            <coordinates>{lon},{lat},{alt}</coordinates>
                            <altitudeMode>relativeToGround</altitudeMode>
                        </Point>
                    </Placemark>
            """
            footer = """\
                </Folder>
            </Document>
            </kml>
            """

            f.write(dedent(header))
            for device in self.devices:
                lat = self.devices[device]["lat"]
                lon = self.devices[device]["lon"]
                alt = self.devices[device]["alt"]
                lines = dedent(
                    (entry.format(device=device, lat=lat, lon=lon, alt=alt))
                ).splitlines()
                for line in lines:
                    f.write(f"{' ' * 8}{line}\n")
            f.write(dedent(footer))

        # Send response status code
        self.send_response(200)

        # Send headers
        self.send_header("Content-type", "text/html")
        self.end_headers()

        # Send message back to client
        message = "Location received!"
        # Write content as utf-8 data
        self.wfile.write(bytes(message, "utf8"))

def osmand2kml_server(devices):
    def handler(*args):
        OsmAndHandler(devices, *args)

    server = HTTPServer(("localhost", 9000), handler)
    print("Server is running!")
    server.serve_forever()

def main():
    devices = {}
    osmand2kml_server(devices)

if __name__ == "__main__":
    print("Starting server...")
    main()


import random
from abc import ABC
from collections import defaultdict
from pathlib import Path

import numpy as np
from enum import Enum
from torch.utils.data import Dataset, DataLoader

import lib.transforms as t
from lib.dataloader import InfSampler
from lib.pc_utils import read_plyfile, get_bbox
from lib.transforms import cfl_collate_fn_factory, cflt_collate_fn_factory, elastic_distortion
from lib.voxelizer import Voxelizer

class DatasetPhase(Enum):
  Train = 0
  Val = 1
  Val2 = 2
  TrainVal = 3
  Test = 4

def datasetphase_2str(arg):
  if arg == DatasetPhase.Train:
    return 'train'
  elif arg == DatasetPhase.Val:
    return 'val'
  elif arg == DatasetPhase.Val2:
    return 'val2'
  elif arg == DatasetPhase.TrainVal:
    return 'trainval'
  elif arg == DatasetPhase.Test:
    return 'test'
  else:
    raise ValueError('phase must be one of dataset enum.')

def str2datasetphase_type(arg):
  if arg.upper() == 'TRAIN':
    return DatasetPhase.Train
  elif arg.upper() == 'VAL':
    return DatasetPhase.Val
  elif arg.upper() == 'VAL2':
    return DatasetPhase.Val2
  elif arg.upper() == 'TRAINVAL':
    return DatasetPhase.TrainVal
  elif arg.upper() == 'TEST':
    return DatasetPhase.Test
  else:
    raise ValueError('phase must be one of train/val/test')

def cache(func):

  def wrapper(self, *args, **kwargs):
    # Assume that args[0] is index
    index = args[0]
    if self.cache:
      if index not in self.cache_dict[func.__name__]:
        results = func(self, *args, **kwargs)
        self.cache_dict[func.__name__][index] = results
      return self.cache_dict[func.__name__][index]
    else:
      return func(self, *args, **kwargs)

  return wrapper

class DictDataset(Dataset, ABC):

  def __init__(self,
               data_paths,
               input_transform=None,
               target_transform=None,
               cache=False,
               data_root='/'):
    """
    data_paths: list of lists, [[str_path_to_input, str_path_to_label], [...]]
    """
    super().__init__()

    # Allows easier path concatenation
    if not isinstance(data_root, Path):
      data_root = Path(data_root)

    self.data_root = data_root
    self.data_paths = sorted(data_paths)
    self.input_transform = input_transform
    self.target_transform = target_transform

    # dictionary of input
    self.data_loader_dict = {
        'input': (self.load_input, self.input_transform),
        'target': (self.load_target, self.target_transform)
    }

    # For large dataset, do not cache
    self.cache = cache
    self.cache_dict = defaultdict(dict)
    self.loading_key_order = ['input', 'target']

  def load_input(self, index):
    raise NotImplementedError

  def load_target(self, index):
    raise NotImplementedError

  def get_classnames(self):
    pass

  def reorder_result(self, result):
    return result

  def __getitem__(self, index):
    out_array = []
    for k in self.loading_key_order:
      loader, transformer = self.data_loader_dict[k]
      v = loader(index)
      if transformer:
        v = transformer(v)
      out_array.append(v)
    return out_array

  def __len__(self):
    return len(self.data_paths)

class VoxelizationDatasetBase(DictDataset, ABC):
  USE_RGB = True
  IS_TEMPORAL = False
  CLIP_BOUND = None
  ROTATION_AXIS = None
  LOCFEAT_IDX = None
  NUM_IN_CHANNEL = 3
  NUM_LABELS = -1  # Number of labels in the dataset, including all ignore classes
  IGNORE_LABELS = None  # labels that are not evaluated

  # Target bounging box normalization
  BBOX_NORMALIZE_MEAN = np.array((0., 0., 0., 0., 0., 0.))
  BBOX_NORMALIZE_STD = np.array((1., 1., 1., 1., 1., 1.))

  def __init__(self,
               data_paths,
               input_transform=None,
               target_transform=None,
               cache=False,
               data_root='/',
               explicit_rotation=-1,
               ignore_mask=255,
               return_transformation=False,
               **kwargs):
    """
    ignore_mask: label value for ignore class. It will not be used as a class in the loss or
                 evaluation.
    explicit_rotation: # of discretization of 360 degree. # data would be
                       num_data * explicit_rotation
    """
    super().__init__(
        data_paths,
        input_transform=input_transform,
        target_transform=target_transform,
        cache=cache,
        data_root=data_root)

    self.ignore_mask = ignore_mask
    self.explicit_rotation = explicit_rotation
    self.return_transformation = return_transformation

  def _augment_locfeat(self, coords, feats):
    if self.LOCFEAT_IDX is not None:
      height = coords[:, self.LOCFEAT_IDX].copy()
      height -= np.percentile(height, 0.99)
      return np.hstack((feats, height[:, None]))
    return feats

  def get_instance_mask(self, semantic_labels, instance_labels):
    raise NotImplementedError

  def __getitem__(self, index):
    raise NotImplementedError

  def load_datafile(self, index):
    filepath = self.data_root / self.data_paths[index]
    return read_plyfile(filepath), None, None

  def test_pointcloud(self, pred_dir):
    raise NotImplementedError

  def __len__(self):
    num_data = len(self.data_paths)
    if self.explicit_rotation > 1:
      return num_data * self.explicit_rotation
    return num_data

class SparseVoxelizationDataset(VoxelizationDatasetBase):
  """This dataset loads RGB point clouds and their labels as a list of points
  and voxelizes the pointcloud with sufficient data augmentation.
  """

  IS_ROTATION_BBOX = False
  HAS_GT_BBOX = False

  # Voxelization arguments
  VOXEL_SIZE = 0.05  # 5cm

  # Augmentation arguments
  SCALE_AUGMENTATION_BOUND = (0.9, 1.1)
  ROTATION_AUGMENTATION_BOUND = ((-np.pi / 6, np.pi / 6), (-np.pi, np.pi), (-np.pi / 6, np.pi / 6))
  TRANSLATION_AUGMENTATION_RATIO_BOUND = ((-0.2, 0.2), (-0.05, 0.05), (-0.2, 0.2))
  ELASTIC_DISTORT_PARAMS = None

  def __init__(self,
               data_paths,
               input_transform=None,
               target_transform=None,
               data_root='/',
               explicit_rotation=-1,
               ignore_label=255,
               return_transformation=False,
               augment_data=False,
               config=None,
               **kwargs):
    if explicit_rotation > 0:
      raise NotImplementedError

    self.augment_data = augment_data
    self.config = config
    super().__init__(
        data_paths,
        input_transform=input_transform,
        target_transform=target_transform,
        cache=cache,
        data_root=data_root,
        explicit_rotation=explicit_rotation,
        ignore_mask=ignore_label,
        return_transformation=return_transformation)

    self.sparse_voxelizer = Voxelizer(
        voxel_size=self.VOXEL_SIZE,
        clip_bound=self.CLIP_BOUND,
        use_augmentation=augment_data,
        scale_augmentation_bound=self.SCALE_AUGMENTATION_BOUND,
        rotation_augmentation_bound=self.ROTATION_AUGMENTATION_BOUND,
        translation_augmentation_ratio_bound=self.TRANSLATION_AUGMENTATION_RATIO_BOUND,
        ignore_label=ignore_label)

    # map labels not evaluated to ignore_label
    if self.IGNORE_LABELS is not None:
      label_map = {}
      n_used = 0
      for l in range(self.NUM_LABELS):
        if l in self.IGNORE_LABELS:
          label_map[l] = self.ignore_mask
        elif l not in self.INSTANCE_LABELS:
          label_map[l] = n_used
          n_used += 1
      for l in self.INSTANCE_LABELS:
        label_map[l] = n_used
        n_used += 1
      label_map[self.ignore_mask] = self.ignore_mask
      self.label_map = label_map
      self.NUM_LABELS -= len(self.IGNORE_LABELS)

  def convert_mat2cfl(self, mat):
    # Generally, xyz, rgb, label
    return mat[:, :3], mat[:, 3:-2], mat[:, -2:]

  def _augment_elastic_distortion(self, pointcloud):
    if self.ELASTIC_DISTORT_PARAMS is not None:
      if random.random() < 0.95:
        for granularity, magnitude in self.ELASTIC_DISTORT_PARAMS:
          pointcloud = elastic_distortion(pointcloud, granularity, magnitude)
    return pointcloud

  def __getitem__(self, index):
    pointcloud, bboxes, center = self.load_datafile(index)
    if self.augment_data and self.config.elastic_distortion:
      pointcloud = self._augment_elastic_distortion(pointcloud)
    coords, feats, labels = self.convert_mat2cfl(pointcloud)
    feats = self._augment_locfeat(coords, feats)
    coords, feats, labels, transformation = self.sparse_voxelizer.voxelize(
        coords, feats, labels, center=center)

    # transform bboxes to match the voxelization transformation.
    # TODO(jgwak): Support rotation augmentation.
    if self.HAS_GT_BBOX:
      bboxes_xyz = np.hstack((bboxes[:, :6].reshape(-1, 3), np.ones((bboxes.shape[0] * 2, 1))))
      bboxes_xyz = bboxes_xyz @ transformation.reshape(4, 4).T
      bboxes_xyz = (bboxes_xyz[:, :3] / bboxes_xyz[:, 3, None]).reshape(-1, 2, 3)
      bboxes_xyz = np.hstack((bboxes_xyz.min(1), bboxes_xyz.max(1)))
      bboxes = np.hstack((bboxes_xyz, bboxes[:, 6:]))

    if labels is None:
      semantic_labels = np.ones(coords.shape[0]) * self.config.ignore_label
      instance_labels = np.ones(coords.shape[0]) * self.config.ignore_label
    else:
      semantic_labels, instance_labels = labels.T

    # map labels not used for evaluation to ignore_label
    if self.input_transform is not None:
      coords, feats, bboxes = self.input_transform(coords, feats, bboxes)
    if self.target_transform is not None:
      coords, feats, bboxes = self.target_transform(coords, feats, bboxes)
    if self.IGNORE_LABELS is not None:
      semantic_labels = np.array([self.label_map[x] for x in semantic_labels], dtype=np.int)
      if self.HAS_GT_BBOX:
        bboxes[:, -1] = np.array([self.label_map[int(x)] for x in bboxes[:, -1]])

    # Normalize rotation.
    if self.augment_data and self.HAS_GT_BBOX and self.IS_ROTATION_BBOX:
      if self.config.normalize_rotation:
        rot_bin = np.floor((bboxes[:, 6] + np.pi / 4) / (np.pi / 2))
        idxs = list(range(3))
        idxs.remove(self.LOCFEAT_IDX)
        assert len(idxs) == 2
        bbox_size = (bboxes[:, 3:6] - bboxes[:, :3]) / 2
        bbox_center = (bboxes[:, 3:6] + bboxes[:, :3]) / 2
        bboxes[:, 6] = bboxes[:, 6] - rot_bin * np.pi / 2
        is_rotated = np.where(rot_bin % 2)[0]
        bbox_size[np.ix_(is_rotated, idxs)] = bbox_size[np.ix_(is_rotated, list(reversed(idxs)))]
        bboxes = np.hstack((bbox_center - bbox_size, bbox_center + bbox_size, bboxes[:, 6:]))
      elif self.config.normalize_rotation2:
        bboxes[:, 6] = (bboxes[:, 6] % np.pi - np.pi / 2) * 2

    if not self.HAS_GT_BBOX:
      instance_mask = self.get_instance_mask(semantic_labels, instance_labels)
      bboxes, instance_labels = get_bbox(
          coords, semantic_labels, instance_labels, instance_mask, self.ignore_mask)
    labels = np.hstack((np.expand_dims(semantic_labels, 1), np.expand_dims(instance_labels, 1)))

    return_args = [coords, feats, labels, bboxes]
    if self.return_transformation:
      transformation = np.expand_dims(transformation, 0)
      return_args.extend([pointcloud.astype(np.float32), transformation.astype(np.float32)])
    return tuple(return_args)

def initialize_data_loader(DatasetClass,
                           config,
                           phase,
                           threads,
                           shuffle,
                           repeat,
                           augment_data,
                           batch_size,
                           limit_numpoints,
                           input_transform=None,
                           target_transform=None):
  if isinstance(phase, str):
    phase = str2datasetphase_type(phase)

  if config.return_transformation:
    collate_fn = cflt_collate_fn_factory(DatasetClass.IS_ROTATION_BBOX, limit_numpoints, config)
  else:
    collate_fn = cfl_collate_fn_factory(DatasetClass.IS_ROTATION_BBOX, limit_numpoints, config)

  input_transforms = []
  if input_transform is not None:
    input_transforms += input_transform

  if augment_data:
    input_transforms += [
        t.RandomHorizontalFlip(DatasetClass.ROTATION_AXIS, DatasetClass.IS_TEMPORAL),
        t.HeightTranslation(config.data_aug_height_trans_std),
        t.HeightJitter(config.data_aug_height_jitter_std),
    ]
    if DatasetClass.USE_RGB:
      input_transforms += [
          t.ChromaticTranslation(config.data_aug_color_trans_ratio),
          t.ChromaticJitter(config.data_aug_color_jitter_std),
      ]

  if len(input_transforms) > 0:
    input_transforms = t.Compose(input_transforms)
  else:
    input_transforms = None

  dataset = DatasetClass(
      config,
      input_transform=input_transforms,
      target_transform=target_transform,
      cache=config.cache_data,
      augment_data=augment_data,
      phase=phase)

  if repeat:
    # Use the inf random sampler
    data_loader = DataLoader(
        dataset=dataset,
        num_workers=threads,
        batch_size=batch_size,
        collate_fn=collate_fn,
        sampler=InfSampler(dataset, shuffle))
  else:
    # Default shuffle=False
    data_loader = DataLoader(
        dataset=dataset,
        num_workers=threads,
        batch_size=batch_size,
        collate_fn=collate_fn,
        shuffle=shuffle)

  return data_loader


import pygame
from random import randint
from shapes import BlackBird
from shapes import BlueBird
from shapes import Plain
from shapes import Bullet
from shapes import Button
import sys
import os
from game_loop import my_function

pygame.init()
# Set up an assets folders, so the game could run on any computer
Angry_Birds_Game_folder = os.path.dirname(__file__)
img_folder = os.path.join(Angry_Birds_Game_folder, "img")
sound_folder = os.path.join(Angry_Birds_Game_folder, "sound")

# Some constant var
WINDOW_WIDTH = 802
WINDOW_HEIGHT = 466
user = "Tamar oling"
size = (WINDOW_WIDTH, WINDOW_HEIGHT)
PINK_BACKGROUND = (255, 20, 147)
LIGHT_PINK = (255, 174, 201)
LIFES = 0
FPS = 60 # frames per sec
SOUND_FILE = "Angry Birds Theme Song.mp3"

# setting of mouse movement:
LEFT = 1
SCROLL = 2
RIGHT = 3

## initialzing pygame and creating a window

# Init screen
pygame.init()
size = (WINDOW_WIDTH, WINDOW_HEIGHT)
screen = pygame.display.set_mode(size)
pygame.display.set_caption("Angry Birds Game")
img_background = pygame.image.load(os.path.join(img_folder, 'clouds background.jpg')).convert()
screen.blit(img_background, (0, 0)) # loading the image to coordinates (0,0)
# if we load to (150,0) the image will move more to the right on the screen
# so the bottom rightest pixel on the screen will be (801, 465)

# init player- the plain
pygame.mouse.set_visible(False) # in order to not see the mouse arrow

player_image = pygame.image.load(os.path.join(img_folder, 'plain.png')).convert()
player_image.set_colorkey(PINK_BACKGROUND)
screen.blit(player_image, [220, 300]) #the size of the plain
pygame.display.flip()

# refreshing screen rate for moving objects
clock = pygame.time.Clock()

# init music
pygame.mixer.init()
pygame.mixer.music.load('sound\Angry Birds Theme Song.mp3')
pygame.mixer.music.play(-1)

crash_sound = pygame.mixer.Sound("sound\Bomb Explosion 1-SoundBible.com-980698079.wav")
winning_sound = pygame.mixer.Sound("sound\Ta Da-SoundBible.com-1884170640.wav")
loser_sound = pygame.mixer.Sound("sound\Smashing-Yuri_Santana-1233262689.wav")
gunshot_sound = pygame.mixer.Sound("sound\gunshot_single-mike-koenig.wav")
#pygame.mixer.music.load(os.path.join(sound_folder, "Angry Birds Theme Song.mp3"))
#pygame.mixer.music.play(loops=-1)

all_bullets = pygame.sprite.Group()
all_birds = pygame.sprite.Group()
player = Plain()
pygame.time.set_timer(pygame.USEREVENT, 500)

score = 0 # player score
life_score = 0 # How many times the player can touch the birds before loosing
myfont = pygame.font.SysFont("monospace", 16)

# to play I need to call the game_loop function
# I need to do the start over button

life_score = my_function(clock, FPS, screen, all_birds, player, all_bullets, LEFT, score, life_score, myfont, gunshot_sound, crash_sound,  img_background, loser_sound)
if life_score < 0:
    # img_background = pygame.image.load(os.path.join(img_folder, 'the game you just lost it.jpg')).convert()
    # screen.blit(img_background, (0, 0))
    finish = False
    while not finish and life_score < 0:
        clock.tick(FPS)
        pygame.display.update()
        img_background = pygame.image.load(os.path.join(img_folder, 'the game you just lost it.jpg')).convert()
        screen.blit(img_background, (100, 50))
        pygame.mouse.set_visible(True)  # in order to see the mouse arrow
        # making the button
        start_over_button = Button(LIGHT_PINK, 335, 401, 150, 50, 'Start Over :)')
        # drawing and adding a frame in the color specified
        start_over_button.draw(screen, (0, 0, 0))
        for event in pygame.event.get():
            mouse_point = pygame.mouse.get_pos()
            if event.type == pygame.QUIT:
                finish = True
            if event.type == pygame.MOUSEMOTION:
                if start_over_button.isOver(mouse_point):
                    start_over_button.color = (255, 34, 106)
                else:
                    start_over_button.color = LIGHT_PINK

            if event.type == pygame.MOUSEBUTTONDOWN:
                if start_over_button.isOver(mouse_point):
                    score = 0
                    life_score = 0

                    # Init screen for restart the game
                    size = (WINDOW_WIDTH, WINDOW_HEIGHT)
                    screen = pygame.display.set_mode(size)
                    pygame.display.set_caption("Angry Birds Game")
                    img_background = pygame.image.load(os.path.join(img_folder, 'clouds background.jpg')).convert()
                    screen.blit(img_background, (0, 0))  # loading the image to coordinates (0,0)
                    # if we load to (150,0) the image will move more to the right on the screen
                    # so the bottom rightest pixel on the screen will be (801, 465)

                    #init the birds and bullets and the player
                    all_bullets = pygame.sprite.Group()
                    all_birds = pygame.sprite.Group()
                    player = Plain()

                    life_score = my_function(clock, FPS, screen, all_birds, player, all_bullets, LEFT, score,
                                             life_score, myfont, gunshot_sound, crash_sound, img_background,
                                             loser_sound)

pygame.quit()


import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import os, sys

#### Primeira parte ####
notas_filmes = pd.read_csv("C:/Users/Tha/DataScience-Curso/ml-latest-small/ml-latest-small/ratings.csv")
print('notas_filmes', notas_filmes)
print('colunas_notas', notas_filmes.columns)
'''
notas_filmes['rating'].head().plot(kind = 'hist')
plt.show()

filmes = pd.read_csv("C:/Users/Tha/DataScience-Curso/ml-latest-small/ml-latest-small/movies.csv")
print('filmes', filmes.head(10))

media_notas_filme_especifico = notas_filmes.loc[notas_filmes['movieId'] == 1]['rating'].mean()

print('media_notas_filme_especifico', media_notas_filme_especifico)

medias_por_filme = notas_filmes.groupby("movieId").mean()["rating"]
print(medias_por_filme.describe())
medias_por_filme.plot(kind = 'hist', title="Histograma das médias dos filmes")
plt.show()
'''
#### Segunda parte ####

filmes_tmdb = pd.read_csv("C:/Users/Tha/DataScience-Curso/archive/tmdb_5000_movies.csv")
print('filmes_tmdb', filmes_tmdb.head())
print('nomes das variaveis', filmes_tmdb.columns)

linguas_tmdb = filmes_tmdb["original_language"].unique()
# Nesse caso a lingua original é uma variavel categorica nominal
print('Linguas Originais ', linguas_tmdb)

numero_vezes_por_lingua_original = filmes_tmdb["original_language"].value_counts()

numero_vezes_por_lingua_original = numero_vezes_por_lingua_original.to_frame().reset_index()

numero_vezes_por_lingua_original.columns = ["Língua original","Quantidade de filmes"]

print('Quantidade de filmes por língua original', numero_vezes_por_lingua_original)

#sns.barplot(x = "Língua original", y = "Quantidade de filmes", data = numero_vezes_por_lingua_original )
# OU Simplesmente
#sns.catplot(x = "original_language", kind = "count", data = filmes_tmdb)

### Gráfico de pizza
'''
plt.pie(numero_vezes_por_lingua_original["Quantidade de filmes"], labels = numero_vezes_por_lingua_original["Língua original"])
plt.show()
'''
total_por_lingua = filmes_tmdb["original_language"].value_counts()
total_geral = total_por_lingua.sum()
print('total geral', total_geral)
total_filmes_ingles = total_por_lingua.loc["en"]
print('total_filmes_ingles', total_filmes_ingles)
total_resto = total_geral - total_filmes_ingles
print('total_resto', total_resto)

dados = {'lingua':['ingles','outros'], 'total': [total_filmes_ingles,total_resto]}
dados = pd.DataFrame(dados)

'''
plt.pie(dados["total"], labels = dados["lingua"])
plt.show()

sns.barplot(x='lingua', y='total', data= dados)
plt.show()
'''

exceto_ingles = filmes_tmdb.query("original_language != 'en'")
qtde_exceto_ingles = exceto_ingles["original_language"].value_counts()
print('qtde_exceto_ingles', qtde_exceto_ingles)

#sns.catplot(x="original_language", kind= "count", data = exceto_ingles, aspect = 2, order = qtde_exceto_ingles.index, palette = "GnBu_d")
#plt.show()

notas_toy_story = notas_filmes.query("movieId == 1")
notas_jumanji = notas_filmes.query("movieId == 2")

media_notas_toy_story = notas_toy_story["rating"].mean()
media_notas_jumanji = notas_jumanji["rating"].mean()

mediana_notas_toy_story = notas_toy_story["rating"].median()
mediana_notas_jumanji = notas_jumanji["rating"].median()

print('media_notas_toy_story %.2f' % media_notas_toy_story)
print('media_notas_jumanji %.2f' % media_notas_jumanji)
print('mediana_notas_toy_story %.2f' % mediana_notas_toy_story)
print('mediana_notas_jumanji %.2f' % mediana_notas_jumanji)

notas_toy_story = notas_toy_story["rating"]
notas_jumanji = notas_jumanji["rating"]

#plt.hist(notas_toy_story)
#plt.hist(notas_jumanji)

print('desvio padrão Toy Story ', notas_toy_story.std())
print('desvio padrão Jumanji ', notas_jumanji.std())

plt.boxplot([notas_toy_story, notas_jumanji])
plt.show()


import cv2
import depthai
import uvicorn
import numpy as np
from fastapi import FastAPI, Response, Request
from fastapi.responses import StreamingResponse

global streaming
streaming = False
pipeline = depthai.Pipeline()

cam_rgb = pipeline.create(depthai.node.ColorCamera)
cam_rgb.setPreviewSize(640, 640)
cam_rgb.setInterleaved(False)

#create output
xout_rgb = pipeline.create(depthai.node.XLinkOut)
xout_rgb.setStreamName("rgb")
cam_rgb.preview.link(xout_rgb.input)

app = FastAPI()
streaming = False

def generate_frames():
    # if pipeline:
    streaming = True
    global device
    with depthai.Device(pipeline) as device:
        q_rgb = device.getOutputQueue("rgb")
        frame = None
        while streaming:
            in_rgb = q_rgb.tryGet()
            if in_rgb is not None:
                frame = in_rgb.getCvFrame()
            if frame is not None:
                global img
                img = frame.copy()
                ret, buffer = cv2.imencode('.jpg', frame)
                frame_encoded = buffer.tobytes()
                yield (b'--frame\r\n'
                        b'Content-Type: image/jpeg\r\n\r\n' + frame_encoded + b'\r\n')
            # yield img

@app.get('/')
async def index():
    return {"message": "Welcome to the webcam streaming application!"}

@app.get('/video_feed')
async def video_feed():
    global streaming
    streaming = True
    return StreamingResponse(generate_frames(),
                             media_type='multipart/x-mixed-replace; boundary=frame')

@app.get('/stop_stream')
async def stop_stream():
    global streaming, device
    streaming = False
    if device:
        device.close()
        device = None
    return {"message": "Streaming stopped successfully."}

@app.get('/restart_stream')
async def restart_stream():
    global streaming
    streaming = True
    return {"message": "Streaming restarted successfully."}

import os
@app.get('/save_frame')
async def save_frame(filename: str):

    # Specify the file path to save the image
    file_path = os.path.join("your_path", filename)

    # Save the image to the specified file path
    cv2.imwrite(file_path, img)

    return {"message": f"Image saved to {file_path}"}

####demo using @app.post to receive request from client(web browser)
@app.post('/demo')
async def demo_getvalue(value:str):
    global demo_value
    demo_value = value
    return demo_value

@app.get('/rundemo')
async def rundemo():
    return {"message": "the value was received as value = {}".format(demo_value)}

if __name__ == '__main__':
    uvicorn.run(app, host='localhost', port=8000)