import logging
import socket
import sys
import ssl
import urllib.parse

def retrieve_url(url):
    """
    implement your client code here
    """
    parsed = urllib.parse.urlparse(url)
    scheme = parsed.scheme
    port = parsed.port
    host = parsed.netloc
    path = parsed.path

    if (scheme == 'http'):
        if path == '':
            request = 'GET / HTTP/1.1\r\nHost: ' + host +  "\r\nConnection: close"+ "\r\n\r\n"
        else:
            request = "GET " + path +" HTTP/1.1\r\nHost: " + host + "\r\nConnection: close"+ "\r\n\r\n"

        if port is None:
            try:
                s = socket.create_connection ((host, 80))
            except OSError:
                return None
        else:
            try:
                s = socket.create_connection ((host.split(':')[0], port))
            except OSError:
                return None

        request_as_bytes = bytearray (request, 'utf-8')

        s.send(request_as_bytes)

        ack_msg = s.recv(1024)
        data = ack_msg

        while True:
            if len(ack_msg) == 0:
                break
            ack_msg = s.recv(1024)
            data = data + ack_msg

    elif (scheme == 'https'):
        if path == '':
            request = 'GET / HTTP/1.1\r\nHost: ' + host +  "\r\nConnection: close"+ "\r\n\r\n"
        else:
            request = "GET " + path +" HTTP/1.1\r\nHost: " + host + "\r\nConnection: close"+ "\r\n\r\n"

        if port is None:
            try:
                context = ssl.create_default_context()
                context = ssl.SSLContext(ssl.PROTOCOL_TLS)
                context.verify_mode = ssl.CERT_REQUIRED
                context.check_hostname = True
                context.load_verify_locations("/etc/ssl/certs/ca-bundle.crt")
                s = context.wrap_socket(socket.socket(socket.AF_INET), server_hostname=host)

                s.connect ((host, 443))
            except OSError:
                return None
        else:
            try:
                context = ssl.create_default_context()
                context = ssl.SSLContext(ssl.PROTOCOL_TLS)
                context.verify_mode = ssl.CERT_REQUIRED
                context.check_hostname = True
                context.load_verify_locations("/etc/ssl/certs/ca-bundle.crt")
                s = context.wrap_socket(socket.socket(socket.AF_INET), server_hostname=host)

                s.connect ((host, port))
            except OSError:
                return None

#            cert = s.getpeercert()
#            print (cert)
#            if not cert:
#                return None

#            print (cert['notAfter']);

        request_as_bytes = bytearray (request, 'utf-8')

        s.send(request_as_bytes)

        ack_msg = s.recv(1024)
        data = ack_msg

        while True:
            if len(ack_msg) == 0:
                break
            ack_msg = s.recv(1024)
            data = data + ack_msg

#start of data parsing
    status = data.partition(bytearray('\r\n\r\n', 'utf-8'))[0]
    data = data.partition(bytearray('\r\n\r\n', 'utf-8'))[2]#parse out header
    code = status.partition(bytearray('\r\n', 'utf-8'))[0]
    code = code.partition(b' ')[2]
    code = code.partition(b' ')[0]

    if (code == b'200'):
        try:
            #check if chunked encoded
            is_chunked = status.index(bytearray('chunked','utf-8'))

            #parsing body of data
            temp = data.partition(bytearray('\r\n0\r\n\r\n', 'utf-8'))[0]#parse footer, body is left, data = body
            temp = temp.partition(bytearray('\r\n', 'utf-8'))[2]#take out the first length
            temp = temp.partition(bytearray('\r\n', 'utf-8'))#take out the first length

            data = temp[0]
            temp = temp[2]
            count = 0
            while (temp != b''):
                temp = temp.partition(bytearray('\r\n', 'utf-8'))
                if isinstance(temp[0], int):
                    continue
                data = data + temp[0]
                temp = temp[2]
        except ValueError:
            data = data
#data = data.partition(bytearray('\r\n\r\n', 'utf-8'))[2]
    elif (code == b'404'):
        return None
    return data
#print (retrieve_url ('http://www.example.com'))
#print (retrieve_url ('http://www.google.com'))
#print (retrieve_url('http://accc.uic.edu/contact'))
#retrieve_url('http://accc.uic.edu/contact')
#print(retrieve_url('https://www.google.com'))
#print (retrieve_url('http://www.google.com'))
#print (retrieve_url ('https://expired.badssl.com/'))
#print (retrieve_url ('https://www.example.com'))
print (retrieve_url ('http://i.imgur.com/fyxDric.jpg'))


class Read(object):
    """This class takes a single line of a .sam format file and parses it. Every line represents a DNA read aligned
    to a reference. A read instance stores all information about how the read is aligned to the reference,
    for analysis purposes.
    ...

    Attributes
    ----------
    id : str
        String with read identification information
    flag : int
        0, 4 or 16, flag information of the read indicating forward, reverse or non-aligned read
    leftmost_position : int
        Position of the reference alignment to which the read's first nucleotide is aligned
    quality : int
        Integer that reflects quality of the read
    cigar_lst : list
        Every character and digit in the cigar string separated as items in a list
    sequence : str
        Genomic sequence of the read
    parsed_cigar : lst
        List of cigar operators as list separating cigar alphabetic signs and consumed positions per operator
    aligned_sequence : lst
        Genomic sequence of the read including gaps as stated by cigar string,
        so it is aligned to the reference alignment
    rightmost_position : int
        Position of the reference alignment to which the read's last nucleotide is aligned

    Methods
    -------
    parse_cigar
        Reads cigar_lst and returns a parsed_cigar list. It separates every cigar operator
        with its correspondent consumed positions, in different items
    get_aligned_sequence
        Combines the parsed_cigar list and read sequence to return the aligned (to reference) sequence with gaps
        and deletions/insertions
        Returns rightmost position based on alignment
    is_aligned_to
        Returns true or false if read is aligned to a given range of positions corresponding to the reference alignment
    """

    def __init__(self, sam_line):
        """Gets the relevant SAM characters in the line by splitting them by tabs and selecting their indexes
        Parameters
        ----------
        sam_line : str
            Single line of a SAM file, can be obtained by iterating through the file using self.readlines()
        """

        sam_line = sam_line.split("\t")
        self.id = sam_line[0]
        self.flag = int(sam_line[1])
        self.leftmost_position = int(sam_line[3]) - 1  # -1 fixes index from NGSengine, which starts in 1 instead of 0
        self.quality = int(sam_line[4])
        self.cigar_lst = list(sam_line[5])
        self.sequence = sam_line[9]
        self.parsed_cigar = []
        self.aligned_sequence = []
        self.rightmost_position = None

    def parse_cigar(self):
        """Parses cigar list with separate digits/operators as items
        and returns a parsed cigar list of operator combined with consumed positions as sublists

        Items in the cigar list: M is a match, D a deletion and I is an insertion
        """

        cigar_sublist = []
        for i in range(len(self.cigar_lst)):
            if self.cigar_lst[i] == "M" or self.cigar_lst[i] == "D" or self.cigar_lst[i] == "I":
                new_str = ""
                for digit in cigar_sublist:
                    new_str += digit
                cigar_sublist = [new_str]
                cigar_sublist.append(self.cigar_lst[i])
                self.parsed_cigar.append(cigar_sublist)
                cigar_sublist = []
            else:
                cigar_sublist.append(self.cigar_lst[i])
        return self.parsed_cigar

    def get_aligned_sequence(self):
        """Iterates over parsed cigar list and read sequence, returns sequence aligned to reference with indicated gaps,
        insertions and deletions
        Returns rightmost position to which the read is aligned based on length of the aligned read sequence

        Raises
        ------
        If no cigar string is present, warning is printed and no aligned sequence or rightmost position are given
        """

        sequence_lst = list(self.sequence)
        if self.parsed_cigar is []:
            return "WARNING: no cigar string found for this read"
        else:
            last_position = 0
            for sub_cigar in self.parsed_cigar:
                consumed_positions = int(sub_cigar[0])
                operator = sub_cigar[-1]
                if operator == "M":
                    for i in range(last_position, consumed_positions + last_position):
                        self.aligned_sequence += sequence_lst[i]
                    last_position += consumed_positions
                elif operator == "D":
                    for i in range(consumed_positions):
                        self.aligned_sequence += "."
                elif operator == "I":
                    last_position += consumed_positions
            self.rightmost_position = self.leftmost_position + len(self.aligned_sequence)
            return self.aligned_sequence, self.rightmost_position

    def is_aligned_to(self, region_range):
        """Returns true or false depending on whether the read is aligned/overlaps within a given range of positions

        Parameters
        ----------
        region_range : tuple/list
            Range (first two items are taken) of nucleotide positions in the reference alignment, to which the read
            is going to be checked whether aligns or not
            Can be a tuple in reference.exons_index_list or reference.introns_index_list so reads can be checked to
            align to a specific region in the reference
        """

        for i in range(self.leftmost_position, self.rightmost_position):
            if i in range(region_range[0], region_range[1]):
                return True
        return False


import math
class Student():
    school = "Rashtrothana"
    def __init__(self,name,height,weight):
        self.name = name
        self.height = height
        self.weight = weight

    def bmi(self):
        bmi = (self.weight/math.pow(self.height,2))
        if bmi < 25:
            return ("Slim")
        else:
            return ("Overweight")

shiva = Student("shiva",1.64,75)
print(shiva.name,shiva.height,shiva.weight)
print ("and BMI says: you are "+shiva.bmi())


from ase.utils import StringIO
from ase.io import read

# Made from NWChem interface

def read_geom_orcainp(filename):
    """Method to read geometry from an ORCA input file."""
    f = filename
    if isinstance(filename, str):
        f = open(filename)
    lines = f.readlines()
    if type(filename) == str:
        f.close()

    # Find geometry region of input file.
    stopline = 0
    for index, line in enumerate(lines):
        if line[1:].startswith('xyz '):
            startline = index + 1
            stopline = -1
        elif (line.startswith('end') and stopline == -1):
            stopline = index
        elif (line.startswith('*') and stopline == -1):
            stopline = index
    # Format and send to read_xyz.
    xyz_text = '%i\n' % (stopline - startline)
    xyz_text += ' geometry\n'
    for line in lines[startline:stopline]:
        xyz_text += line
    atoms = read(StringIO(xyz_text), format='xyz')
    atoms.set_cell((0., 0., 0.))  # no unit cell defined

    return atoms

def write_orca(atoms, **params):
    """Function to write ORCA input file
    """
    charge = params['charge']
    mult = params['mult']
    label = params['label']

    if 'pcpot' in params.keys():
        pcpot = params['pcpot']
        pcstring = '% pointcharges \"' +\
                   label + '.pc\"\n\n'
        params['orcablocks'] += pcstring
        pcpot.write_mmcharges(label)

    with open(label + '.inp', 'w') as f:
        f.write("! engrad %s \n" % params['orcasimpleinput'])
        f.write("%s \n" % params['orcablocks'])

        f.write('*xyz')
        f.write(" %d" % charge)
        f.write(" %d \n" % mult)
        for atom in atoms:
            if atom.tag == 71:  # 71 is ascii G (Ghost)
                symbol = atom.symbol + ' : '
            else:
                symbol = atom.symbol + '   '
            f.write(symbol +
                    str(atom.position[0]) + ' ' +
                    str(atom.position[1]) + ' ' +
                    str(atom.position[2]) + '\n')
        f.write('*\n')


import jwt
from rest_framework.authentication import BaseAuthentication
from rest_framework import exceptions
from django.conf import settings

from user.models import User

class SafeJWTAuthentication(BaseAuthentication):
    """
        custom authentication class for DRF and JWT
       https://www.django-rest-framework.org/api-guide/authentication/#custom-authentication
    """

    def authenticate(self, request):
        access_token = request.headers.get('Authorization')

        if not access_token:
            return None
        try:
            payload = jwt.decode(
                access_token, settings.SECRET_KEY, algorithms=['HS256'])

        except jwt.ExpiredSignatureError:
            raise exceptions.AuthenticationFailed('access_token expired')
        except IndexError:
            raise exceptions.AuthenticationFailed('Token prefix missing')

        user = User.objects.filter(id=payload['user_id']).first()

        if user is None:
            raise exceptions.AuthenticationFailed('User not found')
        return user, None


from QPOEstimation.stabilisation import bar_lev
from QPOEstimation.smoothing import two_sided_exponential_smoothing

import numpy as np

import matplotlib.pyplot as plt
# import matplotlib
# matplotlib.use("Qt5Agg")

alpha = 0.04
sampling_frequency = 128
data = np.loadtxt(f"data/sgr1806_{sampling_frequency}Hz.dat")
print(data)
times = data[:, 0]
counts = data[:, 1]
ys = bar_lev(counts)
ys_smoothed = two_sided_exponential_smoothing(ys, alpha=alpha)
ys_residual = ys - ys_smoothed
plt.plot(times, ys)
plt.plot(times, ys_smoothed)
plt.show()

plt.plot(times, ys_residual)
plt.show()

smoothed_data = np.array([times, ys_smoothed]).T
residual_data = np.array([times, ys_residual]).T
np.savetxt(f"data/sgr1806_{sampling_frequency}Hz_exp_smoothed_alpha_{alpha}.dat", smoothed_data)

res_data = np.array([times, ys_residual]).T
np.savetxt(f"data/sgr1806_{sampling_frequency}Hz_exp_residual_alpha_{alpha}.dat", residual_data)

print(times)


# 5. В массиве найти максимальный отрицательный элемент.
# Вывести на экран его значение и позицию в массиве.

import random

list_len = int(input('Введите длину массива: '))
rand_list = [random.randint(-100, 100) for _ in range(list_len)]
print(f'Исходный массив:\n{rand_list}')

max_negative = 0
max_neg_pos = -1

for pos, item in enumerate(rand_list):
    if max_negative == 0 and item < 0:
        max_negative = item
        max_neg_pos = pos
    if item < 0 and item > max_negative:
        max_negative = item
        max_neg_pos = pos

print(f"Максимальный отрицательный элемент '{max_negative}', индекс - {max_neg_pos}")


import unittest
import responses
from dataclasses import dataclass
from typing import List, Dict, Union
from api import SwagUpApiClient

@dataclass
class CreateDesignResponse:
    design_id: str
    designer_id: str
    design_name: str
    design_description: str
    categories: List[str]
    tags: List[str]
    price: float
    design_url: str

@dataclass
class UploadImageResponse:
    image_id: str
    image_url: str

@dataclass
class GetDesignDetailsResponse:
    design_id: str
    designer_id: str
    design_name: str
    design_description: str
    categories: List[str]
    tags: List[str]
    price: float
    design_url: str
    image_id: str
    image_url: str
    image_upload_timestamp: str
    image_size: str
    image_format: str

@dataclass
class ChooseLogoColorResponse:
    design_id: str
    color: Dict[str, Union[str, List[int]]]
    design_url: str

@dataclass
class SelectSizeAndQuantityResponse:
    design_id: str
    items: List[Dict[str, Union[str, int]]]
    design_url: str

@dataclass
class SetShippingDestinationResponse:
    design_id: str
    address: Dict[str, str]
    design_url: str

@dataclass
class ManagePaymentMethodsResponse:
    payment_method_id: str
    design_url: str

@dataclass
class PlaceOrderResponse:
    order_id: str
    design_url: str

@dataclass
class TrackOrderResponse:
    order_id: str
    design_url: str

@dataclass
class CancelOrderResponse:
    order_id: str
    design_url: str

class SwagUpApiClientTests(unittest.TestCase):
    def setUp(self):
        # Create an instance of SwagUpApiClient
        self.client = SwagUpApiClient(base_url="https://api.example.com", api_key="your_api_key")

    @responses.activate
    def test_create_design(self):
        expected_payload = {
            "designerId": "designer123",
            "designName": "Cool Cat",
            "designDescription": "Cat wearing sunglasses",
            "categories": ["Animals", "Humor"],
            "tags": ["cat", "cool", "sunglasses"],
            "price": 19.99
        }
        response_data = {
            "status": "success",
            "message": "Design created successfully",
            "data": {
                "designId": "123",
                "designerId": "designer123",
                "designName": "Cool Cat",
                "designDescription": "Cat wearing sunglasses",
                "categories": ["Animals", "Humor"],
                "tags": ["cat", "cool", "sunglasses"],
                "price": 19.99,
                "timestamp": "2023-07-10T15:00:00Z"
            }
        }

        responses.add(responses.POST, "https://api.example.com/designs", json=response_data, status=200)

        response = self.client.create_design(
            designer_id=expected_payload["designerId"],
            design_name=expected_payload["designName"],
            design_description=expected_payload["designDescription"],
            categories=expected_payload["categories"],
            tags=expected_payload["tags"],
            price=expected_payload["price"]
        )

        self.assertIsInstance(response, CreateDesignResponse)
        self.assertEqual(response.design_id, response_data["data"]["designId"])
        self.assertEqual(response.designer_id, response_data["data"]["designerId"])
        self.assertEqual(response.design_name, response_data["data"]["designName"])
        self.assertEqual(response.design_description, response_data["data"]["designDescription"])
        self.assertEqual(response.categories, response_data["data"]["categories"])
        self.assertEqual(response.tags, response_data["data"]["tags"])
        self.assertEqual(response.price, response_data["data"]["price"])
        self.assertEqual(response.design_url, response_data["data"]["timestamp"])

        self.assertEqual(len(responses.calls), 1)
        self.assertEqual(responses.calls[0].request.url, "https://api.example.com/designs")
        self.assertEqual(responses.calls[0].request.method, "POST")
        self.assertDictEqual(responses.calls[0].request.json(), expected_payload)

    @responses.activate
    def test_upload_image(self):
        expected_image_file = "/path/to/image.png"
        response_data = {
            "status": "success",
            "message": "Image uploaded successfully",
            "data": {
                "imageId": "456",
                "imageUrl": "https://your-api.com/images/456",
                "uploadTimestamp": "2023-07-10T15:05:00Z",
                "imageSize": "1.5MB",
                "imageFormat": "png"
            }
        }

        responses.add(responses.POST, "https://api.example.com/images", json=response_data, status=200)

        response = self.client.upload_image(image=expected_image_file)

        self.assertIsInstance(response, UploadImageResponse)
        self.assertEqual(response.image_id, response_data["data"]["imageId"])
        self.assertEqual(response.image_url, response_data["data"]["imageUrl"])

        self.assertEqual(len(responses.calls), 1)
        self.assertEqual(responses.calls[0].request.url, "https://api.example.com/images")
        self.assertEqual(responses.calls[0].request.method, "POST")
        self.assertIn("multipart/form-data", responses.calls[0].request.headers["Content-Type"])

    @responses.activate
    def test_get_design_details(self):
        design_id = "123"
        response_data = {
            "status": "success",
            "message": "Design details fetched successfully",
            "data": {
                "designId": "123",
                "designerId": "designer123",
                "designName": "Cool Cat",
                "designDescription": "Cat wearing sunglasses",
                "categories": ["Animals", "Humor"],
                "tags": ["cat", "cool", "sunglasses"],
                "price": 19.99,
                "creationTimestamp": "2023-07-10T15:00:00Z",
                "imageId": "456",
                "imageUrl": "https://your-api.com/images/456",
                "imageUploadTimestamp": "2023-07-10T15:05:00Z",
                "imageSize": "1.5MB",
                "imageFormat": "png"
            }
        }

        responses.add(responses.GET, f"https://api.example.com/designs/{design_id}", json=response_data, status=200)

        response = self.client.get_design_details(design_id)

        self.assertIsInstance(response, GetDesignDetailsResponse)
        self.assertEqual(response.design_id, response_data["data"]["designId"])
        self.assertEqual(response.designer_id, response_data["data"]["designerId"])
        self.assertEqual(response.design_name, response_data["data"]["designName"])
        self.assertEqual(response.design_description, response_data["data"]["designDescription"])
        self.assertEqual(response.categories, response_data["data"]["categories"])
        self.assertEqual(response.tags, response_data["data"]["tags"])
        self.assertEqual(response.price, response_data["data"]["price"])
        self.assertEqual(response.design_url, response_data["data"]["creationTimestamp"])
        self.assertEqual(response.image_id, response_data["data"]["imageId"])
        self.assertEqual(response.image_url, response_data["data"]["imageUrl"])
        self.assertEqual(response.image_upload_timestamp, response_data["data"]["imageUploadTimestamp"])
        self.assertEqual(response.image_size, response_data["data"]["imageSize"])
        self.assertEqual(response.image_format, response_data["data"]["imageFormat"])

        self.assertEqual(len(responses.calls), 1)
        self.assertEqual(responses.calls[0].request.url, f"https://api.example.com/designs/{design_id}")
        self.assertEqual(responses.calls[0].request.method, "GET")

    @responses.activate
    def test_choose_logo_color(self):
        design_id = "123"
        expected_payload = {
            "color": {
                "name": "Red",
                "hex": "#FF0000",
                "rgb": [255, 0, 0]
            },
            "designId": design_id
        }
        response_data = {
            "status": "success",
            "message": "Logo color set successfully",
            "data": {
                "designId": design_id,
                "logoColor": {
                    "name": "Red",
                    "hex": "#FF0000",
                    "rgb": [255, 0, 0]
                }
            }
        }

        responses.add(responses.POST, "https://api.example.com/logo-color", json=response_data, status=200)

        response = self.client.choose_logo_color(design_id=design_id, color=expected_payload["color"])

        self.assertIsInstance(response, ChooseLogoColorResponse)
        self.assertEqual(response.design_id, response_data["data"]["designId"])
        self.assertEqual(response.color, response_data["data"]["logoColor"])

        self.assertEqual(len(responses.calls), 1)
        self.assertEqual(responses.calls[0].request.url, "https://api.example.com/logo-color")
        self.assertEqual(responses.calls[0].request.method, "POST")
        self.assertDictEqual(responses.calls[0].request.json(), expected_payload)

    @responses.activate
    def test_select_size_and_quantity(self):
        design_id = "123"
        expected_payload = {
            "designId": design_id,
            "items": [
                {"size": "S", "quantity": 50},
                {"size": "M", "quantity": 100},
                {"size": "L", "quantity": 50}
            ]
        }
        response_data = {
            "status": "success",
            "message": "Sizes and quantities set successfully",
            "data": {
                "designId": design_id,
                "items": [
                    {"size": "S", "quantity": 50},
                    {"size": "M", "quantity": 100},
                    {"size": "L", "quantity": 50}
                ]
            }
        }

        responses.add(responses.POST, "https://api.example.com/orders/sizes-quantity", json=response_data, status=200)

        response = self.client.select_size_and_quantity(design_id=design_id, items=expected_payload["items"])

        self.assertIsInstance(response, SelectSizeAndQuantityResponse)
        self.assertEqual(response.design_id, response_data["data"]["designId"])
        self.assertEqual(response.items, response_data["data"]["items"])

        self.assertEqual(len(responses.calls), 1)
        self.assertEqual(responses.calls[0].request.url, "https://api.example.com/orders/sizes-quantity")
        self.assertEqual(responses.calls[0].request.method, "POST")
        self.assertDictEqual(responses.calls[0].request.json(), expected_payload)

    @responses.activate
    def test_set_shipping_destination(self):
        design_id = "123"
        expected_payload = {
            "designId": design_id,
            "address": {
                "recipientName": "John Doe",
                "street": "123 Swag Street",
                "city": "Swag City",
                "state": "Swag State",
                "country": "Swag Country",
                "zip": "12345"
            }
        }
        response_data = {
            "status": "success",
            "message": "Shipping address set successfully",
            "data": {
                "designId": design_id,
                "address": {
                    "recipientName": "John Doe",
                    "street": "123 Swag Street",
                    "city": "Swag City",
                    "state": "Swag State",
                    "country": "Swag Country",
                    "zip": "12345"
                }
            }
        }

        responses.add(responses.POST, "https://api.example.com/orders/shipping", json=response_data, status=200)

        response = self.client.set_shipping_destination(design_id=design_id, address=expected_payload["address"])

        self.assertIsInstance(response, SetShippingDestinationResponse)
        self.assertEqual(response.design_id, response_data["data"]["designId"])
        self.assertEqual(response.address, response_data["data"]["address"])

        self.assertEqual(len(responses.calls), 1)
        self.assertEqual(responses.calls[0].request.url, "https://api.example.com/orders/shipping")
        self.assertEqual(responses.calls[0].request.method, "POST")
        self.assertDictEqual(responses.calls[0].request.json(), expected_payload)

    @responses.activate
    def test_manage_payment_methods(self):
        expected_payload = {
            "paymentMethod": {
                "type": "credit card",
                "cardNumber": "1234567812345678",
                "expiryDate": "07/25",
                "cvv": "123"
            }
        }
        response_data = {
            "status": "success",
            "message": "Payment method added successfully",
            "data": {
                "paymentMethodId": "payment123",
                "type": "credit card",
                "expiryDate": "07/25"
            }
        }

        responses.add(responses.POST, "https://api.example.com/payment-methods", json=response_data, status=200)

        response = self.client.manage_payment_methods(payment_method=expected_payload["paymentMethod"])

        self.assertIsInstance(response, ManagePaymentMethodsResponse)
        self.assertEqual(response.payment_method_id, response_data["data"]["paymentMethodId"])

        self.assertEqual(len(responses.calls), 1)
        self.assertEqual(responses.calls[0].request.url, "https://api.example.com/payment-methods")
        self.assertEqual(responses.calls[0].request.method, "POST")
        self.assertDictEqual(responses.calls[0].request.json(), expected_payload)

    @responses.activate
    def test_place_order(self):
        design_id = "123"
        payment_method_id = "payment123"
        expected_payload = {
            "designId": design_id,
            "paymentMethodId": payment_method_id
        }
        response_data = {
            "status": "success",
            "message": "Order placed successfully",
            "data": {
                "orderId": "order123",
                "designId": design_id,
                "paymentMethodId": payment_method_id,
                "status": "Processing",
                "timestamp": "2023-07-10T16:00:00Z"
            }
        }

        responses.add(responses.POST, "https://api.example.com/orders", json=response_data, status=200)

        response = self.client.place_order(design_id=design_id, payment_method_id=payment_method_id)

        self.assertIsInstance(response, PlaceOrderResponse)
        self.assertEqual(response.order_id, response_data["data"]["orderId"])

        self.assertEqual(len(responses.calls), 1)
        self.assertEqual(responses.calls[0].request.url, "https://api.example.com/orders")
        self.assertEqual(responses.calls[0].request.method, "POST")
        self.assertDictEqual(responses.calls[0].request.json(), expected_payload)

    @responses.activate
    def test_track_order(self):
        order_id = "order123"
        response_data = {
            "status": "success",
            "message": "Order fetched successfully",
            "data": {
                "orderId": order_id,
                "designId": "123",
                "status": "Shipped",
                "timestamp": "2023-07-10T16:00:00Z",
                "shippingAddress": {
                    "recipientName": "John Doe",
                    "street": "123 Swag Street",
                    "city": "Swag City",
                    "state": "Swag State",
                    "country": "Swag Country",
                    "zip": "12345"
                },
                "estimatedDelivery": "2023-07-17T16:00:00Z"
            }
        }

        responses.add(responses.GET, f"https://api.example.com/orders/{order_id}", json=response_data, status=200)

        response = self.client.track_order(order_id)

        self.assertIsInstance(response, TrackOrderResponse)
        self.assertEqual(response.order_id, response_data["data"]["orderId"])

        self.assertEqual(len(responses.calls), 1)
        self.assertEqual(responses.calls[0].request.url, f"https://api.example.com/orders/{order_id}")
        self.assertEqual(responses.calls[0].request.method, "GET")

    @responses.activate
    def test_cancel_order(self):
        order_id = "order123"
        response_data = {
            "status": "success",
            "message": "Order cancelled successfully",
            "data": {
                "orderId": order_id,
                "status": "Cancelled"
            }
        }

        responses.add(responses.DELETE, f"https://api.example.com/orders/{order_id}", json=response_data, status=200)

        response = self.client.cancel_order(order_id)

        self.assertIsInstance(response, CancelOrderResponse)
        self.assertEqual(response.order_id, response_data["data"]["orderId"])

        self.assertEqual(len(responses.calls), 1)
        self.assertEqual(responses.calls[0].request.url, f"https://api.example.com/orders/{order_id}")
        self.assertEqual(responses.calls[0].request.method, "DELETE")

if __name__ == "__main__":
    unittest.main()


#!/opt/bin/lv_micropython
import lvgl as lv
import time
import SDL
lv.init()

LV_DEMO_WIDGETS_SLIDESHOW = 0
LV_THEME_DEFAULT_COLOR_PRIMARY=lv.color_hex(0x01a2b1)
LV_THEME_DEFAULT_COLOR_SECONDARY=lv.color_hex(0x44d1b6)

LV_LED_BRIGHT_MIN = 120
LV_LED_BRIGHT_MAX = 255

SDL.init(w=480,h=320)

LV_DPI =130
LV_ANIM_REPEAT_INFINITE = -1

# Register SDL display driver.

disp_buf1 = lv.disp_buf_t()
buf1_1 = bytes(480 * 10)
disp_buf1.init(buf1_1, None, len(buf1_1)//4)
disp_drv = lv.disp_drv_t()
disp_drv.init()
disp_drv.buffer = disp_buf1
disp_drv.flush_cb = SDL.monitor_flush
disp_drv.hor_res = 480
disp_drv.ver_res = 320
disp_drv.register()

# Register SDL mouse driver

indev_drv = lv.indev_drv_t()
indev_drv.init()
indev_drv.type = lv.INDEV_TYPE.POINTER
indev_drv.read_cb = SDL.mouse_read
indev_drv.register()
# print("Running the Unix version")

# Create a screen and load it
scr=lv.obj()
lv.scr_load(scr)

def LV_DPX(n):
    if n == 0:
        return n
    scr=lv.scr_act()
    display = scr.get_disp()
    dpi = display.get_dpi()
    # print("dpi: ",dpi)
    tmp = (dpi*n+80)//160
    # print("tmp: ",tmp)
    if tmp > 1:
        return tmp
    else:
        return 1

def color_chg_event_cb(sw, e):
    if e == lv.EVENT.VALUE_CHANGED:
        flag = lv.THEME_MATERIAL_FLAG.LIGHT
        if sw.get_state():
            flag=lv.THEME_MATERIAL_FLAG.DARK
        theme = lv.theme_material_init(LV_THEME_DEFAULT_COLOR_PRIMARY,LV_THEME_DEFAULT_COLOR_SECONDARY,flag,
                                       lv.theme_get_font_small(), lv.theme_get_font_normal(), lv.theme_get_font_subtitle(),
                                       lv.theme_get_font_title())
def slider_event_cb(slider, e):
    if e == lv.EVENT.VALUE_CHANGED:
        if slider.get_type() == lv.slider.TYPE.NORMAL:
            slider_value = slider.get_value()
            slider.set_style_local_value_str(lv.slider.PART.KNOB, lv.STATE.DEFAULT, str(slider_value))
        else:
            slider_left=slider.get_left_value()
            slider_right=slider.get_value()
            slider_string = str(slider_left) + '-' + str(slider_right)
            # print("slider left value: %d, slider right value: %d"%(slider_left,slider_right))
            slider.set_style_local_value_str(lv.slider.PART.INDIC, lv.STATE.DEFAULT, slider_string)

def linemeter_anim(a,lmeter, value):
    lmeter.set_value(value)
    label = lmeter.get_child(None)
    label.set_text(str(value))
    label.align(lmeter, lv.ALIGN.CENTER, 0, 0)

def gauge_anim(a,gauge,val):
    gauge.set_value(0,val)
    label=gauge.get_child(None)
    label.set_text(str(val))
    label.align(gauge, lv.ALIGN.CENTER, 0, 0)

def bar_anim(task,bar):
    val = bar.get_value()
    # print("bar value: ",val)
    max_value = bar.get_max_value()
    val += 1
    if val > max_value:
        val=0
    bar.set_value(val,lv.ANIM.OFF)
    cpy_string = "Copying %d/%d"% (val, max_value)
    # print(cpy_string)
    bar.set_style_local_value_str(lv.bar.PART.BG, lv.STATE.DEFAULT, cpy_string)

def arc_phase1_ready_cb(a,arc):
    a_arc=lv.anim_t()
    a_arc.init()
    a_arc.set_custom_exec_cb(lambda a_arc, val: anim_phase2(a_arc,arc,val))
    a_arc.set_values(360, 0)
    a_arc.set_time(1000)
    a_arc.set_ready_cb(lambda a: arc_phase2_ready_cb(a,arc))
    lv.anim_t.start(a_arc)

def arc_phase2_ready_cb(a,arc):
    a_arc=lv.anim_t()
    a_arc.init()
    a_arc.set_custom_exec_cb(lambda a_arc, val: anim_phase1(a_arc,arc,val))
    a_arc.set_time(1000)
    a_arc.set_values(0, 360)
    a_arc.set_ready_cb(lambda a: arc_phase1_ready_cb(a,arc))
    lv.anim_t.start(a_arc)

def anim_phase1(a,arc,val):
    arc.set_end_angle(val)
    label = arc.get_child(None)
    label.set_text(str(val))
    label.align(arc, lv.ALIGN.CENTER, 0, 0)

def anim_phase2(a,arc,val):
    arc.set_end_angle(val)
    label = arc.get_child(None)
    label.set_text(str(val))
    label.align(arc, lv.ALIGN.CENTER, 0, 0)

def controls_create(parent):
    lv.page.set_scrl_layout(lv.page.__cast__(parent), lv.LAYOUT.PRETTY_TOP)
    if LV_DEMO_WIDGETS_SLIDESHOW == 0:
        btns = ["Cancel", "Ok", ""]
        m = lv.msgbox(lv.scr_act(), None)
        m.add_btns(btns)
        btnm = lv.btnmatrix.__cast__(m.get_btnmatrix())
        # print("type(btnm): ",type(btnm))
        btnm.set_btn_ctrl(1, lv.btnmatrix.CTRL.CHECK_STATE)

    h = lv.cont(parent, None)
    h.set_layout(lv.LAYOUT.PRETTY_MID)
    h.add_style(lv.cont.PART.MAIN, style_box)
    h.set_drag_parent(True)

    h.set_style_local_value_str(lv.cont.PART.MAIN, lv.STATE.DEFAULT, "Basics")

    disp_size = display.get_size_category()
    if disp_size <= lv.DISP_SIZE.SMALL:
        grid_w= lv.page.get_width_grid(lv.page.__cast__(parent),1,1)
        # print("grid_w: ",grid_w)
    else:
        grid_w= lv.page.get_width_grid(lv.page.__cast__(parent),2,1)
        # print("grid_w: ",grid_w)

    h.set_fit2(lv.FIT.NONE, lv.FIT.TIGHT)
    h.set_width(grid_w)
    btn = lv.btn(h,None)
    btn.set_fit2(lv.FIT.NONE, lv.FIT.TIGHT)
    if disp_size <= lv.DISP_SIZE.SMALL:
        button_width=h.get_width_grid(1,1)
    else:
        button_width=h.get_width_grid(2,1)
    # print("button_width: %d"%button_width)

    btn.set_width(button_width)
    label = lv.label(btn, None)
    label.set_text("Button")

    btn = lv.btn(h, btn)
    btn.toggle()
    label = lv.label(btn, None)
    label.set_text("Button")

    lv.switch(h, None)

    lv.checkbox(h, None)

    fit_w = h.get_width_fit()

    slider = lv.slider(h, None)
    slider.set_value(40, lv.ANIM.OFF)
    slider.set_event_cb(slider_event_cb)
    slider.set_width_margin(fit_w);

    # Use the knobs style value the display the current value in focused state
    slider.set_style_local_margin_top(lv.slider.PART.BG, lv.STATE.DEFAULT, LV_DPX(25))
    slider.set_style_local_value_font(lv.slider.PART.KNOB, lv.STATE.DEFAULT, lv.theme_get_font_small())
    slider.set_style_local_value_ofs_y(lv.slider.PART.KNOB, lv.STATE.FOCUSED, - LV_DPX(25))
    slider.set_style_local_value_opa(lv.slider.PART.KNOB, lv.STATE.DEFAULT, lv.OPA.TRANSP)
    slider.set_style_local_value_opa(lv.slider.PART.KNOB, lv.STATE.FOCUSED, lv.OPA.COVER)
    slider.set_style_local_transition_time(lv.slider.PART.KNOB, lv.STATE.DEFAULT, 300)
    slider.set_style_local_transition_prop_5(lv.slider.PART.KNOB, lv.STATE.DEFAULT, lv.STYLE.VALUE_OFS_Y)
    slider.set_style_local_transition_prop_6(lv.slider.PART.KNOB, lv.STATE.DEFAULT, lv.STYLE.VALUE_OPA)

    slider = lv.slider(h, None)
    slider.set_type(lv.slider.TYPE.RANGE)
    slider.set_value(70, lv.ANIM.OFF)
    slider.set_left_value(30, lv.ANIM.OFF)
    slider.set_style_local_value_ofs_y(lv.slider.PART.INDIC, lv.STATE.DEFAULT, - LV_DPX(25))
    slider.set_style_local_value_font(lv.slider.PART.INDIC, lv.STATE.DEFAULT, lv.theme_get_font_small())
    slider.set_style_local_value_opa(lv.slider.PART.INDIC, lv.STATE.DEFAULT, lv.OPA.COVER)
    slider.set_event_cb(slider_event_cb)
    lv.event_send(slider,lv.EVENT.VALUE_CHANGED, None)      # To refresh the text
    if slider.get_width() > fit_w:
        slider.set_width(fit_w)

    h = lv.cont(parent, h)
    h.set_fit(lv.FIT.NONE)
    h.set_style_local_value_str(lv.cont.PART.MAIN, lv.STATE.DEFAULT, "Text input")

    ta = lv.textarea(h, None)
    lv.cont.set_fit2(h,lv.FIT.PARENT, lv.FIT.NONE)
    ta.set_text("")
    ta.set_placeholder_text("E-mail address")
    ta.set_one_line(True)
    ta.set_cursor_hidden(True)
    #lv_obj_set_event_cb(ta, ta_event_cb);

    ta = lv.textarea(h, ta)
    ta.set_pwd_mode(True)
    ta.set_placeholder_text("Password")

    ta = lv.textarea(h, None)
    lv.cont.set_fit2(h,lv.FIT.PARENT, lv.FIT.NONE)
    ta.set_text("")
    ta.set_placeholder_text("Message")
    ta.set_cursor_hidden(True)
    #lv_obj_set_event_cb(ta, ta_event_cb);
    lv.cont.set_fit4(h, lv.FIT.PARENT, lv.FIT.PARENT, lv.FIT.NONE, lv.FIT.PARENT)

#    if LV_DEMO_WIDGETS_SLIDESHOW:
#        tab_content_anim_create(parent)

def visuals_create(parent):
    page = lv.page.__cast__(parent)
    lv.page.set_scrl_layout(page, lv.LAYOUT.PRETTY_TOP)

    disp_size = display.get_size_category()

    grid_h_chart = lv.page.get_height_grid(page,1,1)
    if disp_size <= lv.DISP_SIZE.LARGE:
        grid_w_chart=lv.page.get_width_grid(page,1,1)
    else:
        grid_w_chart=lv.page.get_width_grid(page,1,2)

    chart = lv.chart(parent, None)
    chart.add_style(lv.chart.PART.BG, style_box)
    if disp_size <= lv.DISP_SIZE.SMALL:
        chart.set_style_local_text_font(lv.chart.PART.SERIES_BG, lv.STATE.DEFAULT, lv.theme_get_font_small())

    chart.set_drag_parent(True)
    chart.set_style_local_value_str(lv.cont.PART.MAIN, lv.STATE.DEFAULT, "Line chart")
    chart.set_width_margin(grid_w_chart)
    chart.set_height_margin(grid_h_chart)
    chart.set_div_line_count(3, 0)
    chart.set_point_count(8)
    chart.set_type(lv.chart.TYPE.LINE)

    if disp_size > lv.DISP_SIZE.SMALL:
        chart.set_style_local_pad_left(lv.chart.PART.BG, lv.STATE.DEFAULT, 4 * (LV_DPI // 10))
        chart.set_style_local_pad_bottom(lv.chart.PART.BG, lv.STATE.DEFAULT, 3 * (LV_DPI // 10))
        chart.set_style_local_pad_right(lv.chart.PART.BG, lv.STATE.DEFAULT, 2 * (LV_DPI // 10))
        chart.set_style_local_pad_top(lv.chart.PART.BG, lv.STATE.DEFAULT, 2 * (LV_DPI // 10))
        chart.set_y_tick_length(0, 0)
        chart.set_x_tick_length(0, 0)
        chart.set_y_tick_texts("600\n500\n400\n300\n200", 0, lv.chart.AXIS.DRAW_LAST_TICK)
        chart.set_x_tick_texts("Jan\nFeb\nMar\nApr\nMay\nJun\nJul\nAug", 0, lv.chart.AXIS.DRAW_LAST_TICK)

    s1 = chart.add_series(LV_THEME_DEFAULT_COLOR_PRIMARY)
    s2 = chart.add_series(LV_THEME_DEFAULT_COLOR_SECONDARY)

    chart.set_next(s1, 10)
    chart.set_next(s1, 90)
    chart.set_next(s1, 30)
    chart.set_next(s1, 60)
    chart.set_next(s1, 10)
    chart.set_next(s1, 90)
    chart.set_next(s1, 30)
    chart.set_next(s1, 60)
    chart.set_next(s1, 10)
    chart.set_next(s1, 90)

    chart.set_next(s2, 32)
    chart.set_next(s2, 66)
    chart.set_next(s2, 5)
    chart.set_next(s2, 47)
    chart.set_next(s2, 32)
    chart.set_next(s2, 32)
    chart.set_next(s2, 66)
    chart.set_next(s2, 5)
    chart.set_next(s2, 47)
    chart.set_next(s2, 66)
    chart.set_next(s2, 5)
    chart.set_next(s2, 47)

    chart2 = lv.chart(parent, chart)
    chart2.set_type(lv.chart.TYPE.COLUMN)
    chart2.set_style_local_value_str(lv.cont.PART.MAIN, lv.STATE.DEFAULT, "Column chart")

    s1 = chart2.add_series(LV_THEME_DEFAULT_COLOR_PRIMARY)
    s2 = chart2.add_series(LV_THEME_DEFAULT_COLOR_SECONDARY)

    chart2.set_next(s1, 10)
    chart2.set_next(s1, 90)
    chart2.set_next(s1, 30)
    chart2.set_next(s1, 60)
    chart2.set_next(s1, 10)
    chart2.set_next(s1, 90)
    chart2.set_next(s1, 30)
    chart2.set_next(s1, 60)
    chart2.set_next(s1, 10)
    chart2.set_next(s1, 90)

    chart2.set_next(s2, 32)
    chart2.set_next(s2, 66)
    chart2.set_next(s2, 5)
    chart2.set_next(s2, 47)
    chart2.set_next(s2, 32)
    chart2.set_next(s2, 32)
    chart2.set_next(s2, 66)
    chart2.set_next(s2, 5)
    chart2.set_next(s2, 47)
    chart2.set_next(s2, 66)
    chart2.set_next(s2, 5)
    chart2.set_next(s2, 47)

    if disp_size <= lv.DISP_SIZE.SMALL:
        grid_w_meter = lv.page.get_width_grid(page, 1, 1)
    elif disp_size <= lv.DISP_SIZE.MEDIUM :
        grid_w_meter = lv.page.get_width_grid(page, 2, 1)
    else:
        grid_w_meter = lv.page.get_width_grid(page, 3, 1)

    meter_h = lv.page.get_height_fit(page)
    if grid_w_meter < meter_h:
        meter_size = grid_w_meter
    else:
        meter_size = meter_h

    lmeter = lv.linemeter(parent, None)
    lmeter.set_drag_parent(True)
    lmeter.set_value(50)
    lmeter.set_size(meter_size, meter_size)
    lmeter.add_style(lv.linemeter.PART.MAIN, style_box)
    lmeter.set_style_local_value_str(lv.linemeter.PART.MAIN, lv.STATE.DEFAULT, "Line meter")

    label = lv.label(lmeter, None)
    label.align(lmeter, lv.ALIGN.CENTER, 0, 0)
    label.set_style_local_text_font(lv.label.PART.MAIN, lv.STATE.DEFAULT, lv.theme_get_font_title());

    a_lm=lv.anim_t()
    a_lm.init()
    a_lm.set_custom_exec_cb(lambda a, val: linemeter_anim(a,lmeter,val))
    a_lm.set_values(0, 100)
    a_lm.set_time(4000)
    a_lm.set_playback_time(1000)
    a_lm.set_repeat_count(LV_ANIM_REPEAT_INFINITE)
    lv.anim_t.start(a_lm)

    gauge = lv.gauge(parent, None)
    gauge.set_drag_parent(True)
    gauge.set_size(meter_size, meter_size)
    gauge.add_style(lv.gauge.PART.MAIN, style_box)
    gauge.set_style_local_value_str(lv.gauge.PART.MAIN, lv.STATE.DEFAULT, "Gauge")

    label = lv.label(gauge, label)
    label.align(gauge, lv.ALIGN.CENTER, 0, grid_w_meter // 3)

    a_ga=lv.anim_t()
    a_ga.init()
    a_ga.set_custom_exec_cb(lambda a, val: linemeter_anim(a,lmeter,val))
    a_ga.set_values(0, 100)
    a_ga.set_time(4000)
    a_ga.set_playback_time(1000)
    a_ga.set_repeat_count(LV_ANIM_REPEAT_INFINITE)
    a_ga.set_custom_exec_cb(lambda a, val: gauge_anim(a,gauge,val))
    lv.anim_t.start(a_ga)

    arc = lv.arc(parent,None)
    arc.set_drag_parent(True)
    arc.set_bg_angles(0, 360)
    arc.set_rotation(270)
    arc.set_angles(0, 0)
    arc.set_size(meter_size, meter_size)
    arc.add_style(lv.arc.PART.BG, style_box)
    arc.set_style_local_value_str(lv.arc.PART.BG, lv.STATE.DEFAULT, "Arc");

    label = lv.label(arc)
    label.align(arc, lv.ALIGN.CENTER, 0, 0)

    a_arc=lv.anim_t()
    a_arc.init()
    a_arc.set_custom_exec_cb(lambda a_arc, val: anim_phase1(a_arc,arc,val))
    a_arc.set_values(0, 360)
    a_arc.set_ready_cb(lambda a: arc_phase1_ready_cb(a,arc))
    # a_arc.set_repeat_count(LV_ANIM_REPEAT_INFINITE)
    a_arc.set_time(1000)
    lv.anim_t.start(a_arc)

    # Create a bar and use the backgrounds value style property to display the current value
    bar_h = lv.cont(parent, None)
    bar_h.set_fit2(lv.FIT.NONE, lv.FIT.TIGHT)
    bar_h.add_style(lv.cont.PART.MAIN, style_box);
    bar_h.set_style_local_value_str(lv.cont.PART.MAIN, lv.STATE.DEFAULT, "Bar")

    if disp_size <= lv.DISP_SIZE.SMALL:
        bar_h.set_width(lv.page_get_width_grid(page, 1, 1))
    elif disp_size <= lv.DISP_SIZE.MEDIUM:
        bar_h.set_width(lv.page.get_width_grid(page, 2, 1))
    else:
        bar_h.set_width(lv.page.get_width_grid(parent, 3, 2))

    bar = lv.bar(bar_h,None)
    bar.set_width(lv.cont.get_width_fit(bar_h))
    bar.set_style_local_value_font(lv.bar.PART.BG, lv.STATE.DEFAULT, lv.theme_get_font_small())
    bar.set_style_local_value_align(lv.bar.PART.BG, lv.STATE.DEFAULT, lv.ALIGN.OUT_BOTTOM_MID)
    bar.set_style_local_value_ofs_y(lv.bar.PART.BG, lv.STATE.DEFAULT, LV_DPI // 20)
    bar.set_style_local_margin_bottom(lv.bar.PART.BG, lv.STATE.DEFAULT, LV_DPI // 7)
    bar.align(None, lv.ALIGN.CENTER, 0, 0)
    bar.set_value(30,lv.ANIM.OFF)

    led_h = lv.cont(parent, None)
    led_h.set_layout(lv.LAYOUT.PRETTY_MID)
    if disp_size <= lv.DISP_SIZE.SMALL:
        led_h.set_width(lv.page.get_width_grid(page, 1, 1))
    elif disp_size <= lv.DISP_SIZE.MEDIUM:
        led_h.set_width(lv.page.get_width_grid(page, 2, 1))
    else:
        led_h.set_width(lv.page.get_width_grid(page, 3, 1))

    led_h.set_height(lv.obj.get_height(lv.obj.__cast__(bar_h)))
    led_h.add_style(lv.cont.PART.MAIN, style_box)
    led_h.set_drag_parent(True)
    led_h.set_style_local_value_str(lv.cont.PART.MAIN, lv.STATE.DEFAULT, "LEDs")

    led = lv.led(led_h, None)
    led_size = lv.obj.get_height_fit(lv.obj.__cast__(led_h))
    led.set_size(led_size, led_size)
    led.off()

    led = lv.led(led_h, led)
    led.set_bright((LV_LED_BRIGHT_MAX - LV_LED_BRIGHT_MIN) // 2 + LV_LED_BRIGHT_MIN)

    led = lv.led(led_h, led)
    led.on()

    if disp_size == lv.DISP_SIZE.MEDIUM:
        led_h.add_protect(lv.PROTECT.POS)
        led_h.align(bar_h, lv.ALIGN.OUT_BOTTOM_MID, 0, lv.obj.get_style_margin_top(lv.obj.__cast__(led_h), lv.obj.PART.MAIN) + lv.obj.get_style_pad_inner(parent, lv.page.PART.SCROLLABLE))

    task = lv.task_create_basic()
    task.set_cb(lambda task: bar_anim(task, bar))
    task.set_period(100)
    task.set_prio(lv.TASK_PRIO.LOWEST)

def selectors_create(parent):
    page = lv.page.__cast__(parent)
    lv.page.set_scrl_layout(page, lv.LAYOUT.PRETTY_MID)

    grid_h = page.get_height_grid(1, 1)

    if disp_size <= lv.DISP_SIZE.SMALL:
        grid_w = page.get_width_grid(1, 1)
    else:
        grid_w = page.get_width_grid(2, 1)

    cal = lv.calendar(parent, None)
    cal.set_drag_parent(True)
    if disp_size > lv.DISP_SIZE.MEDIUM:
        cal.set_size(min(grid_h, grid_w), min(grid_h, grid_w));
    else :
        cal.set_size(grid_w, grid_w)
        if disp_size <= lv.DISP_SIZE.SMALL:
            cal.set_style_local_text_font(lv.calendat.PART.BG, lv.STATE.DEFAULT, lv.theme_get_font_small())

    hl = [{ "year":2020, "month":1, "day":5},
          {"year":2020, "month":1, "day":9}]

    h = lv.cont(parent, None)
    h.set_drag_parent(True)
    if disp_size <= lv.DISP_SIZE.SMALL:
        h.set_fit2(lv.FIT.NONE, lv.FIT.TIGHT)
        h.set_width(lv.page.get_width_fit(page))
        h.set_layout(lv.LAYOUT.COLUMN_MID)
    elif disp_size <= lv.DISP_SIZE.MEDIUM:
        h.set_size(lv.obj.get_width(lv.obj.__cast__(cal)), lv.obj.get_height(lv.obj.__cast__(cal)))
        h.set_layout(lv.LAYOUT.PRETTY_TOP);
    else :
        h.set_click(False)
        h.set_style_local_bg_opa(lv.PART.MAIN, lv.STATE.DEFAULT, lv.OPA.TRANSP)
        h.set_style_local_border_opa(lv.PART.MAIN, lv.STATE.DEFAULT, lv.OPA.TRANSP)
        h.set_style_local_pad_left(lv.cont.PART.MAIN, lv.STATE.DEFAULT, 0)
        h.set_style_local_pad_right(lv.cont.PART.MAIN, lv.STATE.DEFAULT, 0)
        h.set_style_local_pad_top(lv.cont.PART_MAIN, LV_STATE_DEFAULT, 0);
        h.set_size(min(grid_h, grid_w), min(grid_h, grid_w))
        h.set_layout(lv.LAYOUT.PRETTY_TOP)

    roller = lv.roller(h, None)
    roller.add_style(lv.cont.PART.MAIN, style_box)
    roller.set_style_local_value_str(lv.cont.PART.MAIN, lv.STATE.DEFAULT, "Roller")
    roller.set_auto_fit(False)
    roller.set_align(lv.label.ALIGN.CENTER)
    roller.set_visible_row_count(4)
    if disp_size <= lv.DISP_SIZE.SMALL:
        roller.set_width(lv.cont.get_width_grid(h, 1 , 1))
    else:
        roller.set_width(lv.cont.get_width_grid(h, 2 , 1))

    dd = lv.dropdown(h, None)
    dd.add_style(lv.cont.PART.MAIN, style_box)
    dd.set_style_local_value_str(lv.cont.PART.MAIN, lv.STATE.DEFAULT, "Dropdown")
    if disp_size <= lv.DISP_SIZE.SMALL:
        dd.set_width(lv.cont.get_width_grid(h, 1 , 1))
    else:
        dd.set_width(lv.cont.get_width_grid(h, 2 , 1))

    dd.set_options("Alpha\nBravo\nCharlie\nDelta\nEcho\nFoxtrot\nGolf\nHotel\nIndia\nJuliette\nKilo\nLima\nMike\nNovember\n"
                   "Oscar\nPapa\nQuebec\nRomeo\nSierra\nTango\nUniform\nVictor\nWhiskey\nXray\nYankee\nZulu")

    list = lv.list(parent, None)
    list.set_scroll_propagation(True)
    list.set_size(grid_w, grid_h)

    txts = [lv.SYMBOL.SAVE, "Save", lv.SYMBOL.CUT, "Cut", lv.SYMBOL.COPY, "Copy",
            lv.SYMBOL.OK, "This is a quite long text to scroll on the list", lv.SYMBOL.EDIT, "Edit", lv.SYMBOL.WIFI, "Wifi",
            lv.SYMBOL.BLUETOOTH, "Bluetooth",  lv.SYMBOL.GPS, "GPS", lv.SYMBOL.USB, "USB",
            lv.SYMBOL.SD_CARD, "SD card", lv.SYMBOL.CLOSE, "Close"]

    for i in range(0,len(txts)//2,2):
        btn = list.add_btn(txts[i], txts[i + 1]);
        lv.btn.set_checkable(lv.btn.__cast__(btn),True)

        # Make a button disabled
        if i == 4:
            btn.set_state(lv.btn.STATE.DISABLED)

    cal.set_highlighted_dates(hl, 2)

tv = lv.tabview(lv.scr_act(), None)
display = scr.get_disp()
disp_size = display.get_size_category()
tv.set_style_local_pad_left(lv.tabview.PART.TAB_BG, lv.STATE.DEFAULT, disp_drv.hor_res // 2)

sw = lv.switch(lv.scr_act(), None)
if lv.theme_get_flags() & lv.THEME_MATERIAL_FLAG.DARK:
   sw.on(LV_ANIM_OFF)
sw.set_event_cb(color_chg_event_cb)
sw.set_pos(LV_DPX(10), LV_DPX(10))
sw.set_style_local_value_str(lv.switch.PART.BG, lv.STATE.DEFAULT, "Dark")
sw.set_style_local_value_align(lv.switch.PART.BG, lv.STATE.DEFAULT, lv.ALIGN.OUT_RIGHT_MID)
sw.set_style_local_value_ofs_x(lv.switch.PART.BG, lv.STATE.DEFAULT, LV_DPI//35)

t1 = tv.add_tab("Controls")
t2 = tv.add_tab("Visuals")
t3 = tv.add_tab("Selectors")

style_box = lv.style_t()
style_box.init()
# print("LV_DPX(10): %d, LV_DPX(10): %d"%(LV_DPX(10),LV_DPX(30)))
style_box.set_value_align(lv.STATE.DEFAULT, lv.ALIGN.OUT_TOP_LEFT)
style_box.set_value_ofs_y(lv.STATE.DEFAULT, - LV_DPX(10))
style_box.set_margin_top(lv.STATE.DEFAULT, LV_DPX(30))

controls_create(t1)
visuals_create(t2)
selectors_create(t3)


import torch

from .base import NeuralNetwork
from .layers.linear import BayesianLinear, FeedbackAlignLinear

class BayesianMultilayerPerceptron(NeuralNetwork):
    """
    Bayesian Neural Network with various feedback mechanisms
    """
    def __init__(self, dimensions, nonlinearity, stdv_init, radial):
        super().__init__(dimensions[0], dimensions[-1])
        self.layers = torch.nn.ModuleList(
            BayesianLinear(dim1, dim2, stdv_init, radial)
            for dim1, dim2 in zip(dimensions[:-1], dimensions[1:])
        )

        self.dimensions = dimensions
        self.nonlinearity = nonlinearity

    def forward(self, x):
        """
        Defines the computation performed at every call.

        Returns:
            y_pred: Unnormalized output (i.e. no logits or probabilities)
            state: dict containing hidden activations
        """
        x = x.view((x.size(0), self.input_dim))
        activation = []

        for l in self.layers[:-1]:
            x = l(x)
            x = self.nonlinearity(x)
            activation.append(x)

        # The output is unnormalized (i.e. no logits or probabilities)
        y_pred = self.layers[-1](x)

        return y_pred, {"activation": activation}

    def sample(self):
        for l in self.layers:
            l.sample()

    def reset_parameters(self):
        for l in self.layers:
            l.reset_parameters()

class MultilayerPerceptron(NeuralNetwork):
    """
    Multilayer Perceptron with optional feedback alignment.

    Args:
        dimensions: List of integers defining the network architecture
        nonlinearity: Function used as nonlinearity between layers
        feedback_alignment: Boolean specifying whether to use feedback alignment
    """
    def __init__(self, dimensions, nonlinearity, feedback_alignment=False):
        super().__init__(dimensions[0], dimensions[-1])

        if feedback_alignment:
            self.layers = torch.nn.ModuleList(
                FeedbackAlignLinear(dim1, dim2, bias=True)
                for dim1, dim2 in zip(dimensions[:-1], dimensions[1:])
            )
        else:
            self.layers = torch.nn.ModuleList(
                torch.nn.Linear(dim1, dim2, bias=True)
                for dim1, dim2 in zip(dimensions[:-1], dimensions[1:])
            )
        self.dimensions = dimensions
        self.nonlinearity = nonlinearity

    def forward(self, x):
        """
        Defines the computation performed at every call.

        Returns:
            y_pred: Unnormalized output (i.e. no logits or probabilities)
        """
        x = x.view((x.size(0), self.input_dim))
        activation = []

        for l in self.layers[:-1]:
            x = l(x)
            x = self.nonlinearity(x)
            activation.append(x)

        # The output is unnormalized (i.e. no logits or probabilities)
        y_pred = self.layers[-1](x)

        return y_pred, {"activation": activation}

    def reset_parameters(self):
        for l in self.layers:
            l.reset_parameters()


import csv
from datetime import datetime

# 打开CSV文件并读取数据
with open('vrsn.csv', 'r') as file:
    reader = csv.reader(file)
    data = list(reader)

# 按照日期升序排序数据
data_sorted = sorted(data, key=lambda x: datetime.strptime(x[0], '%m/%d/%Y'))

# 迭代每一行数据并转换日期格式
for row in data_sorted:
    # 使用strptime函数解析原始日期字符串
    date = datetime.strptime(row[0], '%m/%d/%Y')
    # 使用strftime函数将日期格式化为新的格式
    row[0] = date.strftime('%Y-%m-%d')

# 将转换后的数据写回到CSV文件中
with open('vrsn_sorted_and_converted.csv', 'w', newline='') as file:
    writer = csv.writer(file)
    writer.writerows(data_sorted)


"""Migration

Revision ID: 8059985beed1
Revises: d86b14989681
Create Date: 2020-12-07 18:07:55.435065

"""
from alembic import op
import sqlalchemy as sa

# revision identifiers, used by Alembic.
revision = '8059985beed1'
down_revision = 'd86b14989681'
branch_labels = None
depends_on = None

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_column('comments', 'author')
    # ### end Alembic commands ###

def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.add_column('comments', sa.Column('author', sa.VARCHAR(length=255), autoincrement=False, nullable=True))
    # ### end Alembic commands ###


import tensorflow as tf
tf.compat.v1.set_random_seed(777)

W = tf.Variable(tf.random_normal([1]), name='weight')
print(W)
# <tf.Variable 'weight:0' shape=(1,) dtype=float32_ref>

sess = tf.compat.v1.Session()
sess.run(tf.global_variables_initializer())
aaa = sess.run(W)
print("aaa : ", aaa)    # aaa : aaa :  [2.2086694]
sess.close()                    # 세션 닫힘

sess = tf.InteractiveSession()  # 세션을 열어줌
sess.run(tf.global_variables_initializer())
bbb = W.eval()      # 변수.eval
print("bbb : ", bbb)
sess.close()

sess = tf.Session()
sess.run(tf.global_variables_initializer())
ccc = W.eval(session=sess)
print("ccc : ", ccc)
sess.close()

# # 세가지 표현방식
# aaa, bbb, ccc 셋 다 같은 값


from typing import Dict

import pytest
from pytest_mock import MockerFixture

from langchain_community.llms import GradientLLM

_MODEL_ID = "my_model_valid_id"
_GRADIENT_SECRET = "secret_valid_token_123456"
_GRADIENT_WORKSPACE_ID = "valid_workspace_12345"
_GRADIENT_BASE_URL = "https://api.gradient.ai/api"

class MockResponse:
    def __init__(self, json_data: Dict, status_code: int):
        self.json_data = json_data
        self.status_code = status_code

    def json(self) -> Dict:
        return self.json_data

def mocked_requests_post(url: str, headers: dict, json: dict) -> MockResponse:
    assert url.startswith(_GRADIENT_BASE_URL)
    assert _MODEL_ID in url
    assert json
    assert headers

    assert headers.get("authorization") == f"Bearer {_GRADIENT_SECRET}"
    assert headers.get("x-gradient-workspace-id") == f"{_GRADIENT_WORKSPACE_ID}"
    query = json.get("query")
    assert query and isinstance(query, str)
    output = "bar" if "foo" in query else "baz"

    return MockResponse(
        json_data={"generatedOutput": output},
        status_code=200,
    )

@pytest.mark.parametrize(
    "setup",
    [
        dict(
            gradient_api_url=_GRADIENT_BASE_URL,
            gradient_access_token=_GRADIENT_SECRET,
            gradient_workspace_id=_GRADIENT_WORKSPACE_ID,
            model=_MODEL_ID,
        ),
        dict(
            gradient_api_url=_GRADIENT_BASE_URL,
            gradient_access_token=_GRADIENT_SECRET,
            gradient_workspace_id=_GRADIENT_WORKSPACE_ID,
            model_id=_MODEL_ID,
        ),
    ],
)
def test_gradient_llm_sync(mocker: MockerFixture, setup: dict) -> None:
    mocker.patch("requests.post", side_effect=mocked_requests_post)

    llm = GradientLLM(**setup)
    assert llm.gradient_access_token == _GRADIENT_SECRET
    assert llm.gradient_api_url == _GRADIENT_BASE_URL
    assert llm.gradient_workspace_id == _GRADIENT_WORKSPACE_ID
    assert llm.model_id == _MODEL_ID

    response = llm("Say foo:")
    want = "bar"

    assert response == want

@pytest.mark.parametrize(
    "setup",
    [
        dict(
            gradient_api_url=_GRADIENT_BASE_URL,
            gradient_access_token=_GRADIENT_SECRET,
            gradient_workspace_id=_GRADIENT_WORKSPACE_ID,
            model=_MODEL_ID,
        )
    ],
)
def test_gradient_llm_sync_batch(mocker: MockerFixture, setup: dict) -> None:
    mocker.patch("requests.post", side_effect=mocked_requests_post)

    llm = GradientLLM(**setup)
    assert llm.gradient_access_token == _GRADIENT_SECRET
    assert llm.gradient_api_url == _GRADIENT_BASE_URL
    assert llm.gradient_workspace_id == _GRADIENT_WORKSPACE_ID
    assert llm.model_id == _MODEL_ID

    inputs = ["Say foo:", "Say baz:", "Say foo again"]
    response = llm._generate(inputs)

    want = ["bar", "baz", "bar"]
    assert len(response.generations) == len(inputs)
    for i, gen in enumerate(response.generations):
        assert gen[0].text == want[i]


# On-the-fly-CT Reco
version =  "Version 2021.12.22 b"

import numpy
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtGui import QPixmap
from PyQt5.uic import loadUiType
from PIL import Image
import h5py
import tomopy
import math
import time
import os
import csv
import qimage2ndarray
from scipy.ndimage.filters import gaussian_filter, median_filter

Ui_on_the_fly_Window, Q_on_the_fly_Window = loadUiType('on_the_fly_CT_reco_hdf.ui')  # connect to the GUI for the program

class On_the_fly_CT_tester(Ui_on_the_fly_Window, Q_on_the_fly_Window):

    def __init__(self):
        super(On_the_fly_CT_tester, self).__init__()
        self.setupUi(self)
        self.setWindowTitle('On_the_fly_CT_tester')

        #connect buttons to actions
        self.pushLoad.clicked.connect(self.load)
        self.pushReconstruct.clicked.connect(self.reconstruct)
        self.pushReconstruct_all.clicked.connect(self.reconstruct_all)
        self.push_Crop_volume.clicked.connect(self.crop_volume)
        #self.slice_number.valueChanged.connect(self.reconstruct)
        #self.COR.valueChanged.connect(self.reconstruct)
        #self.Offset_Angle.valueChanged.connect(self.reconstruct)
        #self.brightness.valueChanged.connect(self.reconstruct)
        #self.speed_W.valueChanged.connect(self.reconstruct)
        #self.algorithm_list.currentIndexChanged.connect(self.reconstruct)
        #self.filter_list.currentIndexChanged.connect(self.reconstruct)

        self.block_size = 128        #volume will be reconstructed blockwise to reduce needed RAM
        self.extend_FOV = 0.05      #the reconstructed area will be enlarged in order to allow off axis scans
        self.crop_offset = 0        #needed for proper volume cropping

    def buttons_deactivate_all(self):
        self.spinBox_ringradius.setEnabled(False)
        self.Offset_Angle.setEnabled(False)
        self.spinBox_DF.setEnabled(False)
        self.pushLoad.setEnabled(False)

        self.slice_number.setEnabled(False)
        self.COR.setEnabled(False)
        self.Offset_Angle.setEnabled(False)
        self.brightness.setEnabled(False)
        self.speed_W.setEnabled(False)
        self.pushReconstruct.setEnabled(False)
        self.algorithm_list.setEnabled(False)
        self.filter_list.setEnabled(False)

        self.checkBox_phase_2.setEnabled(False)
        self.doubleSpinBox_distance_2.setEnabled(False)
        self.doubleSpinBox_Energy_2.setEnabled(False)
        self.doubleSpinBox_alpha_2.setEnabled(False)

        self.spinBox_first.setEnabled(False)
        self.spinBox_last.setEnabled(False)
        self.push_Crop_volume.setEnabled(False)

        self.pushReconstruct_all.setEnabled(False)
        self.int_low.setEnabled(False)
        self.int_high.setEnabled(False)
    def buttons_activate_load(self):
        self.spinBox_ringradius.setEnabled(True)
        self.spinBox_DF.setEnabled(True)
        self.pushLoad.setEnabled(True)
    def buttons_activate_reco(self):
        self.slice_number.setEnabled(True)
        self.COR.setEnabled(True)
        self.Offset_Angle.setEnabled(True)
        self.brightness.setEnabled(True)
        self.speed_W.setEnabled(True)
        self.pushReconstruct.setEnabled(True)
        self.algorithm_list.setEnabled(True)
        self.filter_list.setEnabled(True)

        self.checkBox_phase_2.setEnabled(True)
        self.doubleSpinBox_distance_2.setEnabled(True)
        self.doubleSpinBox_Energy_2.setEnabled(True)
        self.doubleSpinBox_alpha_2.setEnabled(True)
    def buttons_activate_reco_all(self):
        self.pushReconstruct_all.setEnabled(True)
        self.int_low.setEnabled(True)
        self.int_high.setEnabled(True)
    def buttons_activate_crop_volume(self):
        self.spinBox_first.setEnabled(True)
        self.spinBox_last.setEnabled(True)
        self.push_Crop_volume.setEnabled(True)

    def load(self):

        #grey out the buttons while program is busy
        self.buttons_deactivate_all()

        #ask for first flat field
        path_klick_FF = QtWidgets.QFileDialog.getOpenFileName(self, 'Select first FF-file, please.', "C:\Fly_and_Helix_Test\Flying-CT_Test\MEA_Flying-CT_2x2_crop_normalized")
        self.path_klickFF = path_klick_FF[0]
        print(self.path_klickFF)

        #analyse and cut the path in pieces
        htapFF = self.path_klickFF[::-1]
        self.path_inFF = self.path_klickFF[0: len(htapFF) - htapFF.find('/') - 1: 1]
        self.namepartFF = self.path_klickFF[len(htapFF) - htapFF.find('/') - 1: len(htapFF) - htapFF.find('.') - 5: 1]
        self.counterFF = int(self.path_klickFF[len(htapFF) - htapFF.find('.') - 5: len(htapFF) - htapFF.find('.') - 1:1])
        self.filetypeFF = self.path_klickFF[len(htapFF) - htapFF.find('.') - 1: len(htapFF):1]
        print(self.path_inFF)
        print(self.namepartFF)
        print(self.counterFF)
        print(self.filetypeFF)

        #open file to get the image dimensions
        if self.filetypeFF == '.tif':
            referenceFF = Image.open(self.path_klickFF)
            referenceFF = numpy.array(referenceFF)
            referenceFF = numpy.transpose(referenceFF)
        elif self.filetypeFF == '.h5':
            with h5py.File(self.path_klickFF, 'r') as hdf:
                entry = hdf.get('entry')
                data = entry.get('/entry/data/data')
                referenceFF = numpy.array(data)
                referenceFF = numpy.transpose(referenceFF)
        else:
            print('Error loading file type')

        self.full_sizeFF = referenceFF.shape
        print(self.full_sizeFF)

        #check how many flat fields there are
        for i in range(self.counterFF,999999):
            print(i)
            lastFF = i
            filenameFF = self.path_inFF + self.namepartFF + str(i).zfill(4) + self.filetypeFF

            if os.path.exists(filenameFF) != True:
                break

        print(lastFF)

        #create array to fill FFs in there
        self.FF = numpy.zeros((lastFF - self.counterFF + 1, referenceFF.shape[1], referenceFF.shape[0]), dtype=float)

        #open each flat field and collect in array
        i = self.counterFF
        while i < lastFF:
            self.progressBar.setValue((i + 1) * 100 / lastFF)

            filenameFF = self.path_inFF + self.namepartFF + str(i).zfill(4) + self.filetypeFF

            QtWidgets.QApplication.processEvents()
            print('LoadingFF ', filenameFF)

            if self.filetypeFF == '.tif':
                projFF = Image.open(filenameFF)
                proj_FF = numpy.array(projFF)
            elif self.filetypeFF == '.h5':
                with h5py.File(self.path_klickFF, 'r') as hdf:
                    entry = hdf.get('entry')
                    data = entry.get('/entry/data/data')
                    proj_FF = numpy.array(data)
            else:
                print('Error loading file type')

            self.FF[i - self.counterFF, :, :] = proj_FF

            i = i + 1

        #average all flat fields
        FFavg = numpy.mean(self.FF, axis=0)
        FFavg_df = FFavg - self.spinBox_DF.value()

        #ask for first projection file
        path_klick_raw = QtWidgets.QFileDialog.getOpenFileName(self, 'Select first projection, please.', self.path_klickFF)
        self.path_klick = path_klick_raw[0]
        print(self.path_klick)

        #analyse and cut the path in pieces
        htap = self.path_klick[::-1]
        self.path_in = self.path_klick[0: len(htap) - htap.find('/') - 1: 1]
        ni_htap = self.path_in[::-1]
        self.folder_name = self.path_klick[len(htap) - htap.find('/') - ni_htap.find('/') -1 :len(htap) - htap.find('/') - 1 : 1]
        self.namepart = self.path_klick[len(htap) - htap.find('/') - 1: len(htap) - htap.find('.') - 5: 1]
        self.counter = int(self.path_klick[len(htap) - htap.find('.') - 5: len(htap) - htap.find('.') - 1:1])
        self.filetype = self.path_klick[len(htap) - htap.find('.') - 1: len(htap):1]
        self.Sample.setText(self.path_in)

        #open projection file to get dimensions - (probably not necessary)
        if self.filetype == '.tif':
            reference = Image.open(self.path_klick)
            reference = numpy.array(reference)
            reference = numpy.transpose(reference)
        elif self.filetype == '.h5':
            with h5py.File(self.path_klick, 'r') as hdf:
                entry = hdf.get('entry')
                data = entry.get('/entry/data/data')
                reference = numpy.array(data)
                reference = numpy.transpose(reference)
        else:
            print('Error loading file type')

        self.full_size = reference.shape
        print(self.full_size)

        #check how many files there are
        for i in range(self.counter,999999):
            print('finding last image ',i)
            last = i
            filename = self.path_in + self.namepart + str(i).zfill(4) + self.filetype

            if os.path.exists(filename) != True:
                break

        print(last)

        #create array for all projections and for the angles
        self.A = numpy.zeros((last - self.counter + 1, reference.shape[1], reference.shape[0]), dtype=numpy.uint16)
        self.w = numpy.zeros(last - self.counter + 1, dtype=numpy.float64)

        #open each projection, normalize and store in array
        i = self.counter
        while i < last:
            #update progress bar
            self.progressBar.setValue((i + 1) * 100 / last)

            filename = self.path_in + self.namepart + str(i).zfill(4) + self.filetype

            QtWidgets.QApplication.processEvents()
            print('Loading ', filename)

            #open file
            if self.filetype == '.tif':
                proj = Image.open(filename)
                proj_ = numpy.array(proj)
                self.last_zero_proj = 0
            elif self.filetype == '.h5':
                with h5py.File(filename, 'r') as hdf:
                    entry = hdf.get('entry')
                    data = entry.get('/entry/data/data')
                    proj_ = numpy.array(data)
                    w_data = entry.get('/entry/instrument/NDAttributes/CT_MICOS_W')       #get angles from hdf5-file
                    self.w[i - self.counter] = numpy.array(w_data)
                    print('w', self.w[i - self.counter])
                    if round(self.w[i - self.counter]) == 0:                              #notice the last projection at zero degree
                        self.last_zero_proj = i - self.counter + 3                        #assumes 3 images for speeding up the motor
            else:
                print('Error loading file type')

            #normalize
            proj_df = proj_ - self.spinBox_DF.value()
            proj_norm = numpy.divide(proj_df, FFavg_df)
            proj_norm = numpy.clip(proj_norm, 0.03, 4)
            proj_norm = proj_norm * 16000
            proj_norm = numpy.nan_to_num(proj_norm, copy=True, nan=1.0, posinf=1.0, neginf=1.0)
            proj_norm_16 = numpy.uint16(proj_norm)

            #store in array
            self.A[i - self.counter,:,:] = proj_norm_16

            #collect sum of all normalized projections for ring filtering
            if self.spinBox_ringradius.value() != 0:

                if i == self.counter:
                    self.proj_sum = numpy.array(proj_norm_16, dtype=numpy.single)
                else:
                    self.proj_sum = self.proj_sum + proj_norm_16

            i = i + 1

        print('A', self.A.shape, 'A min vs max', numpy.amin(self.A), numpy.amax(self.A))

        #Ring artifact handling
        if self.spinBox_ringradius.value() != 0:
            print('proj_sum dimensions', self.proj_sum.shape)

            #correction map = (sum of projections) / median filter of (sum of projections)
            proj_sum_filtered = median_filter(self.proj_sum, size = self.spinBox_ringradius.value())
            correction_map = numpy.divide(self.proj_sum, proj_sum_filtered)
            correction_map = numpy.clip(correction_map, 0.9, 1.1)

            print('correction_map dimensions', correction_map.shape, 'correction_map min vs max', numpy.amin(correction_map), numpy.amax(correction_map))

            #apply correction map for ring handling
            i=0
            while i < self.A.shape[0]:
                self.A[i, :, :] = numpy.uint16(numpy.divide(self.A[i, :, :], correction_map))
                self.progressBar.setValue((i + 1) * 100 / self.A.shape[0])
                QtWidgets.QApplication.processEvents()
                i = i+1

        print('A dimensions',self.A.shape, 'A min vs max', numpy.amin(self.A), numpy.amax(self.A))

        #prefill slice number, COR, cropping
        self.slice_number.setMaximum(reference.shape[1]-1)
        self.slice_number.setMinimum(0)
        self.slice_number.setValue(round(reference.shape[1]/2))
        self.COR.setValue(round(reference.shape[0]/2))
        self.spinBox_first.setValue(0)
        self.spinBox_last.setValue(reference.shape[1]-1)

        #prefill rotation-speed[°/img]
        print('found angular values for ',self.w.shape, 'projections')
        print(self.w)
        poly_coeff =  numpy.polyfit(numpy.arange(len(self.w[round((last - self.counter + 1) /4) : round((last - self.counter + 1) * 3/4) ])), self.w[round((last - self.counter + 1) /4) : round((last - self.counter + 1) * 3/4) ], 1, rcond=None, full=False, w=None, cov=False)
        print('Plynom coefficients',poly_coeff)
        self.speed_W.setValue(poly_coeff[0])
        print('Last projection at 0 degree/still speeding up: number', self.last_zero_proj)

        #ungrey the buttons for further use of the program
        self.buttons_activate_load()
        self.buttons_activate_reco()
        #self.buttons_activate_crop_volume()
        #self.buttons_activate_reco_all()
        print('Loading/Normalizing complete!')

    def crop_volume(self):
        #grey out the buttons while program is busy
        self.buttons_deactivate_all()

        #crop the top and/or bottom of the data. store the offset value for saving slices under the right number
        self.A = self.A[:,self.spinBox_first.value():self.spinBox_last.value()+1,:]
        self.crop_offset = self.crop_offset + self.spinBox_first.value()
        self.spinBox_first.setValue(0)
        self.spinBox_last.setValue(self.A.shape[1]-1)
        self.slice_number.setMaximum(self.A.shape[1]-1)
        print('Volume Cropped')
        print('A', self.A.shape)

        #ungrey the buttons for further use of the program
        self.buttons_activate_load()
        self.buttons_activate_reco()
        self.buttons_activate_crop_volume()
        self.buttons_activate_reco_all()

    def reconstruct(self):

        # grey out the buttons while program is busy
        self.buttons_deactivate_all()

        QtWidgets.QApplication.processEvents()
        print('def reconstruct')

        self.full_size = self.A.shape[2]
        self.number_of_projections = self.A.shape[0]

        #determine how far to extend field of view (FOV), 0.0 no extension, 0.5 half extension to both sides (for off center 360 degree scan!!!)
        self.extend_FOV = 2* (abs(self.COR.value() - self.A.shape[2]/2))/ (1 * self.A.shape[2]) + 0.05
        print('extend_FOV ', self.extend_FOV)

        #check if the scan was 180° or 360°
        if self.number_of_projections * self.speed_W.value() >= 270:
            self.number_of_used_projections = round(360 / self.speed_W.value())
        else:
            print('smaller than 3/2 Pi')
            self.number_of_used_projections = round(180 / self.speed_W.value())
        print('number of used projections', self.number_of_used_projections)

        #create list with x-positions of projections
        new_list = (numpy.arange(self.number_of_used_projections) * self.speed_W.value() + self.Offset_Angle.value()) * math.pi / 180
        print('x_list ',new_list.shape)

        #create list with all projection angles
        center_list = [self.COR.value() + round(self.extend_FOV * self.full_size)] * (self.number_of_used_projections)
        print('COR_list ',len(center_list))

        #create one sinogram in the form [z, y, x]
        transposed_sinos = numpy.zeros((min(self.number_of_used_projections, self.A.shape[0]), 1, self.full_size), dtype=float)
        #transposed_sinos[:,0,:] = self.A[0:min(self.number_of_used_projections, self.A.shape[0]), self.slice_number.value(),:]
        transposed_sinos[:,0,:] = self.A[self.last_zero_proj : min(self.last_zero_proj + self.number_of_used_projections, self.A.shape[0]), self.slice_number.value(),:]
        print('transposed_sinos_shape', transposed_sinos.shape)

        #extend data with calculated parameter, compute logarithm, remove NaN-values
        extended_sinos = tomopy.misc.morph.pad(transposed_sinos, axis=2, npad=round(self.extend_FOV * self.full_size), mode='edge')
        extended_sinos = tomopy.minus_log(extended_sinos)
        extended_sinos = (extended_sinos + 9.68) * 1000  # conversion factor to uint
        extended_sinos = numpy.nan_to_num(extended_sinos, copy=True, nan=1.0, posinf=1.0, neginf=1.0)

        #apply phase retrieval if desired
        if self.checkBox_phase_2.isChecked() == True:
            extended_sinos = tomopy.prep.phase.retrieve_phase(extended_sinos, pixel_size=0.0001, dist=self.doubleSpinBox_distance_2.value(), energy=self.doubleSpinBox_Energy_2.value(), alpha=self.doubleSpinBox_alpha_2.value(), pad=True, ncore=None, nchunk=None)

        #reconstruct one slice
        if self.algorithm_list.currentText() == 'FBP_CUDA':
            options = {'proj_type': 'cuda', 'method': 'FBP_CUDA'}
            slices = tomopy.recon(extended_sinos, new_list, center=center_list, algorithm=tomopy.astra, options=options)
        else:
            slices = tomopy.recon(extended_sinos, new_list, center=center_list, algorithm=self.algorithm_list.currentText(),
                                  filter_name=self.filter_list.currentText())

        #cut reconstructed slice to original size
        slices = slices[:,round(self.extend_FOV * self.full_size /2) : -round(self.extend_FOV * self.full_size /2) , round(self.extend_FOV * self.full_size /2) : -round(self.extend_FOV * self.full_size /2)]
        slices = tomopy.circ_mask(slices, axis=0, ratio=1.0)
        original_reconstruction = slices[0, :, :]

        #find and display minimum and maximum values in reconstructed slice
        print(numpy.amin(original_reconstruction))
        print(numpy.amax(original_reconstruction))
        self.min.setText(str(numpy.amin(original_reconstruction)))
        self.max.setText(str(numpy.amax(original_reconstruction)))
        print('reconstructions done')

        #display reconstructed slice
        myarray = (original_reconstruction - numpy.amin(original_reconstruction)) * self.brightness.value() / (numpy.amax(original_reconstruction) - numpy.amin(original_reconstruction))
        myarray = myarray.repeat(2, axis=0).repeat(2, axis=1)
        yourQImage = qimage2ndarray.array2qimage(myarray)
        self.test_reco.setPixmap(QPixmap(yourQImage))

        #ungrey the buttons for further use of the program
        self.buttons_activate_load()
        self.buttons_activate_reco()
        self.buttons_activate_crop_volume()
        self.buttons_activate_reco_all()

    def reconstruct_all(self):
        #grey out the buttons while program is busy
        self.buttons_deactivate_all()

        QtWidgets.QApplication.processEvents()
        print('def reconstruct complete volume')

        #ask for the output path and create it
        self.path_out_reconstructed_ask = QtWidgets.QFileDialog.getExistingDirectory(self, 'Select folder for reconstructions.', self.path_klick)

        #create a folder when saving reconstructed volume as tif-files
        if self.save_tiff.isChecked() == True:
            self.path_out_reconstructed_full = self.path_out_reconstructed_ask + '/'+ self.folder_name
            os.mkdir(self.path_out_reconstructed_full)
        if self.save_hdf5.isChecked() == True:
            self.path_out_reconstructed_full = self.path_out_reconstructed_ask

        self.full_size = self.A.shape[2]
        self.number_of_projections = self.A.shape[0]
        print('X-size', self.A.shape[2])
        print('Nr of projections', self.A.shape[0])
        print('Nr of slices', self.A.shape[1])

        #calculate extension of projections to the sides
        self.extend_FOV = 2* (abs(self.COR.value() - self.A.shape[2]/2))/ (1 * self.A.shape[2]) + 0.05    # extend field of view (FOV), 0.0 no extension, 0.5 half extension to both sides (for half sided 360 degree scan!!!)
        print('extend_FOV ', self.extend_FOV)

        #check if 180° or 360°-scan
        if self.number_of_projections * self.speed_W.value() >= 270:
            self.number_of_used_projections = round(360 / self.speed_W.value())
        else:
            print('smaller than 3/2 Pi')
            self.number_of_used_projections = round(180 / self.speed_W.value())
        print('number of used projections', self.number_of_used_projections)

        #create list with x-positions
        new_list = (numpy.arange(self.number_of_used_projections) * self.speed_W.value() + self.Offset_Angle.value()) * math.pi / 180
        print(new_list.shape)

        #create list with projection angles
        center_list = [self.COR.value() + round(self.extend_FOV * self.full_size)] * (self.number_of_used_projections)
        print(len(center_list))

        #save parameters in csv-file
        file_name_parameter = self.path_out_reconstructed_full + '/' + self.folder_name + '_parameter.csv'
        with open(file_name_parameter, mode = 'w', newline='') as parameter_file:
            csv_writer = csv.writer(parameter_file, delimiter = ' ', quotechar=' ')
            csv_writer.writerow(['Path input                    ', self.path_in,' '])
            csv_writer.writerow(['Path output                   ', self.path_out_reconstructed_full,' '])
            csv_writer.writerow(['Number of used projections    ', str(self.number_of_used_projections),' '])
            csv_writer.writerow(['Center of rotation            ', str(self.COR.value()), ' '])
            csv_writer.writerow(['Dark field value              ', str(self.spinBox_DF.value()),' '])
            csv_writer.writerow(['Ring handling radius          ', str(self.spinBox_ringradius.value()),' '])
            csv_writer.writerow(['Rotation offset               ', str(self.Offset_Angle.value()), ' '])
            csv_writer.writerow(['Rotation speed [°/image]      ', str(self.speed_W.value()), ' '])
            csv_writer.writerow(['Phase retrieval               ', str(self.checkBox_phase_2.isChecked()), ' '])
            csv_writer.writerow(['Phase retrieval distance      ', str(self.doubleSpinBox_distance_2.value()), ' '])
            csv_writer.writerow(['Phase retrieval energy        ', str(self.doubleSpinBox_Energy_2.value()), ' '])
            csv_writer.writerow(['Phase retrieval alpha         ', str(self.doubleSpinBox_alpha_2.value()), ' '])
            csv_writer.writerow(['16-bit                        ', str(self.radioButton_16bit_integer.isChecked()), ' '])
            csv_writer.writerow(['16-bit integer low            ', str(self.int_low.value()), ' '])
            csv_writer.writerow(['16-bit integer high           ', str(self.int_high.value()), ' '])
            csv_writer.writerow(['Reconstruction algorithm      ', self.algorithm_list.currentText(), ' '])
            csv_writer.writerow(['Reconstruction filter         ', self.filter_list.currentText(), ' '])
            csv_writer.writerow(['Software Version              ', version, ' '])
            csv_writer.writerow(['binning                       ', '1x1x1', ' '])

        #divide volume into blocks and reconstruct them one by one in order to save RAM
        i = 0
        while (i < math.ceil(self.A.shape[1] / self.block_size)):

            print('Reconstructing block', i + 1, 'of', math.ceil(self.A.shape[1] / self.block_size))

            #extend data, take logarithm, remove NaN-values
            ###extended_sinos = self.A[0:min(self.number_of_used_projections, self.A.shape[0]), i * self.block_size: (i + 1) * self.block_size, :]
            extended_sinos = self.A[self.last_zero_proj : min(self.last_zero_proj + self.number_of_used_projections, self.A.shape[0]), i * self.block_size: (i + 1) * self.block_size, :]

            extended_sinos = tomopy.misc.morph.pad(extended_sinos, axis=2, npad=round(self.extend_FOV * self.full_size), mode='edge')
            extended_sinos = tomopy.minus_log(extended_sinos)
            extended_sinos = (extended_sinos + 9.68) * 1000  # conversion factor to uint
            extended_sinos = numpy.nan_to_num(extended_sinos, copy=True, nan=1.0, posinf=1.0, neginf=1.0)

            #apply phase retrieval if desired
            if self.checkBox_phase_2.isChecked() == True:
                extended_sinos = tomopy.prep.phase.retrieve_phase(extended_sinos, pixel_size=0.0001, dist=self.doubleSpinBox_distance_2.value(), energy=self.doubleSpinBox_Energy_2.value(), alpha=self.doubleSpinBox_alpha_2.value(), pad=True, ncore=None, nchunk=None)

            #reconstruct
            if self.algorithm_list.currentText() == 'FBP_CUDA':
                options = {'proj_type': 'cuda', 'method': 'FBP_CUDA'}
                slices = tomopy.recon(extended_sinos, new_list, center=center_list, algorithm=tomopy.astra,
                                      options=options)
            else:
                slices = tomopy.recon(extended_sinos, new_list, center=center_list,
                                      algorithm=self.algorithm_list.currentText(),
                                      filter_name=self.filter_list.currentText())

            #crop reconstructed data
            slices = slices[:, round(self.extend_FOV * self.full_size /2): -round(self.extend_FOV * self.full_size /2), round(self.extend_FOV * self.full_size /2): -round(self.extend_FOV * self.full_size /2)]
            slices = tomopy.circ_mask(slices, axis=0, ratio=1.0)

            #16-bit integer conversion
            if self.radioButton_16bit_integer.isChecked() == True:
                ima3 = 65535 * (slices - self.int_low.value()) / (self.int_high.value() - self.int_low.value())
                ima3 = numpy.clip(ima3, 1, 65534)
                slices_save = ima3.astype(numpy.uint16)

            if self.radioButton_32bit_float.isChecked() == True:
                slices_save = slices

            print('Reconstructed Volume is', slices_save.shape)

            #save data
            if self.save_tiff.isChecked() == True:

                # write the reconstructed block to disk as TIF-file
                a = 1
                while (a < self.block_size + 1) and (a < slices_save.shape[0] + 1):
                    self.progressBar.setValue((a + (i * self.block_size)) * 100 / self.A.shape[1])
                    QtCore.QCoreApplication.processEvents()
                    time.sleep(0.02)
                    filename2 = self.path_out_reconstructed_full + self.namepart + str(
                        a + self.crop_offset + i * self.block_size).zfill(4) + '.tif'
                    print('Writing Reconstructed Slices:', filename2)
                    slice_save = slices_save[a - 1, :, :]
                    img = Image.fromarray(slice_save)
                    img.save(filename2)
                    a = a + 1

            if self.save_hdf5.isChecked() == True:
                if i == 0:
                    # create an an hdf5-file and write the first reconstructed block into it
                    with h5py.File(self.path_out_reconstructed_full + '/' + self.folder_name + '.h5', 'w')  as f:
                        f.create_dataset("Volume", data=slices_save, maxshape=(None, slices_save.shape[1], slices_save.shape[2]))
                else:
                    # write the subsequent blocks into the hdf5-file
                    self.progressBar.setValue((i * self.block_size) * 100 / self.A.shape[1])
                    QtCore.QCoreApplication.processEvents()
                    time.sleep(0.02)
                    f = h5py.File(self.path_out_reconstructed_full + '/' + self.folder_name + '.h5', 'r+')
                    vol_proxy = f['Volume']
                    print('volume_proxy.shape', vol_proxy.shape)
                    vol_proxy.resize((vol_proxy.shape[0] + slices_save.shape[0]), axis=0)
                    vol_proxy[i * self.block_size : i * self.block_size + slices_save.shape[0] ,:,:] = slices_save
                    self.progressBar.setValue((i * self.block_size) * 100 / self.A.shape[1])

            i = i + 1

        #set progress bar to 100%
        self.progressBar.setValue(100)
        QtCore.QCoreApplication.processEvents()
        time.sleep(0.02)

        #ungrey the buttons for further use of the program
        self.buttons_activate_load()
        self.buttons_activate_reco()
        self.buttons_activate_crop_volume()
        self.buttons_activate_reco_all()
        print('Done!')

#no idea why we need this, but it wouldn't work without it ;-)
if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)

    main = On_the_fly_CT_tester()
    main.show()
    sys.exit(app.exec_())

#end of code


def solution(prices):
    answer = [0] * len(prices)
    stack = []

    for idx, i in enumerate(prices):
        if stack == []:
            stack.append((i, idx))
            continue

        while len(stack) != 0 and stack[-1][0] > i:
            answer[stack[-1][1]] = idx - stack[-1][1]
            stack.pop(-1)

        stack.append((i, idx))

    i = 0
    idx = len(prices) - 1
    while len(stack) != 0:
        answer[stack[-1][1]] = idx - stack[-1][1]
        stack.pop(-1)

    return answer

print(solution([1, 2, 3, 2, 3]))