"""Base wrapper of scikit-learn-style numpy array predictions.

Functionalities:
- Hiding implementation details of prediction types (e.g., number of
  dimensions, semantics of columns).
- Providing a numpy array view through ``y_pred``. The ``y_pred`` view is
  used in ``rampwf.score``s as input, and in the default implementation
  of combining.
- Handling cross-validation slices through ``set_valid_in_train`` and
  ``set_slice``.
- Handling NaN's in CV bagging by ``valid_indexes``.
- Combining ``Prediction``s (for CV bagging and ensembling). The default is
  to take the (nan)mean of the ``y_pred``s, but it can be overridden in
  derived classes.
Derived classes should all implement ``Predictions`` because we implement
polymorphism through importing ``Predictions`` from the particular file.
``Predictions``s can be asymmetric: ground truth (``y_true``) and predictions
are all stored in these classes. All ``rampwf.score_type``s accept
ground truth as the first argument and prediction as the second.
When constructors are called with a shape, they make an empty ``Predictions``.
This is to store combined ``Predictions``s, so the shape should be the same
as predictions' shape (in case of asymmetric ground truth/prediction).
"""

# Author: Balazs Kegl <balazs.kegl@gmail.com>
# License: BSD 3 clause

import numpy as np
import warnings

class BasePrediction(object):
    def __str__(self):
        return 'y_pred = {}'.format(self.y_pred)

    @property
    def valid_indexes(self):
        """Return valid indices (e.g., a cross-validation slice).

        When combining Predictions on different cross validation slices,
        we start with an empty y_pred. Each time a fold is added, some
        entries become valid. Invalid entries are those that are not
        predicted by any folds, i.e., those that remain NaN.
        """
        if len(self.y_pred.shape) == 1:
            return ~np.isnan(self.y_pred)
        elif len(self.y_pred.shape) == 2:
            return ~np.isnan(self.y_pred[:, 0])
        else:
            raise ValueError('y_pred.shape > 2 is not implemented')

    def set_valid_in_train(self, predictions, test_is):
        """Set a cross-validation slice."""
        self.y_pred[test_is] = predictions.y_pred

    def set_slice(self, valid_indexes):
        """Collapsing y_pred to a cross-validation slice.

        So scores do not need to deal with masks.
        """
        self.y_pred = self.y_pred[valid_indexes]

    def check_y_pred_dimensions(self):
        if self.n_columns == 0 and len(self.y_pred.shape) != 1:
            raise ValueError(
                'Wrong y_pred dimensions: y_pred should be 1D, '
                'instead its shape is {}'.format(self.y_pred.shape))
        if self.n_columns > 0:
            if len(self.y_pred.shape) != 2 or\
                    self.y_pred.shape[1] != self.n_columns:
                raise ValueError(
                    'Wrong y_pred dimensions: y_pred should be 2D '
                    'with {} columns, instead its shape is {}'.format(
                        self.n_columns, self.y_pred.shape))

    @classmethod
    def combine(cls, predictions_list, index_list=None):
        """Combine predictions in predictions_list[index_list].

        The default implemented here is by taking the mean of their y_pred
        views. It can be overridden in derived classes.

        E.g. for regression it is the actual
        predictions, and for classification it is the probability array (which
        should be calibrated if we want the best performance). Called both for
        combining one submission on cv folds (a single model that is trained on
        different folds) and several models on a single fold (blending).

        Parameters
        ----------
        predictions_list : list of instances of Base
            Each element of the list is an instance of Base with the
            same length and type.
        index_list : None | list of integers
            The subset of predictions to be combined. If None, the full set is
            combined.

        Returns
        -------
        combined_predictions : instance of cls
            A predictions instance containing the combined predictions.
        """
        if index_list is None:  # we combine the full list
            index_list = range(len(predictions_list))
        y_comb_list = np.array(
            [predictions_list[i].y_pred for i in index_list])
        # I expect to see RuntimeWarnings in this block
        with warnings.catch_warnings():
            warnings.simplefilter('ignore', category=RuntimeWarning)
            y_comb = np.nanmean(y_comb_list, axis=0)
        combined_predictions = cls(y_pred=y_comb)
        return combined_predictions


import cv2
from djitellopy import Tello
import numpy as np
import torch
from torch import nn
import torchvision

from create_apple_model import Categories as CAP_Categories
from create_rotten_model import Categories as CRM_Categories
from predict_ripe import RipenessPredictor

class CropToSquare:
    def __call__(self, img: torch.Tensor):
        h, w = img.shape[-2:]
        if h > w:
            diff = h - w
            img = img[..., diff // 2 : -diff // 2, :]
        elif w > h:
            diff = w - h
            img = img[..., :, diff // 2 : -diff // 2]
        return img

def detect_apple(model_apple_in_view: nn.Module, image: torch.Tensor, device) -> bool:
    image = image.to(device).unsqueeze(0)
    image = CropToSquare()(image)
    out = model_apple_in_view(image)
    return torch.argmax(out).item() == CAP_Categories.APPLE.value

def detect_rotten(model_detect_rotten: nn.Module, image, device):
    image = image.to(device).unsqueeze(0)
    image = CropToSquare()(image)
    out = model_detect_rotten(image)
    return torch.argmax(out).item() == CRM_Categories.ROTTEN.value

def detect_ripe(model_ripeness_predictor: RipenessPredictor, image):
    return model_ripeness_predictor.predict_ripe(image)

def find_apple_center(drone, model_haar_cascade, image):
    apples = model_haar_cascade.detectMultiScale(image)
    marked_image = image.copy()
    apple_centers = []
    apple_areas = []

    for (x, y, w, h) in apples:
        cv2.rectangle(marked_image, (x, y), (x + w, y + h), (0, 0, 255), 2)
        # get centerx and centery values
        cx = x + w // 2
        cy = y + h // 2
        # calculate the total area
        area = w * h
        # draw a circle where the center is
        cv2.circle(marked_image, (cx, cy), 5, (0, 255, 0), cv2.FILLED)
        # append these values to the lists we created above
        apple_centers.append([cx, cy])
        apple_areas.append(area)
    # get the index of the max area detected over coming frame
    # so that focus on the bigger face if there are multiple faces
    if apple_areas:
        i = apple_areas.index(max(apple_areas))
        return marked_image, [apple_centers[i], apple_areas[i]]
    else:
        return marked_image, [[0, 0], 0]

def track_apple(drone, info, w, pid, p_error, area_range):
    forward_vel = 0
    area = info[1]  # area value
    x, y = info[0]  # centerx and centery values

    error = x - w // 2  # what is the difference between our object and the center
    yaw_vel = pid[0] * error + pid[1] * (
        error - p_error
    )  # calculate yaw value with using PID method
    yaw_vel = int(np.clip(yaw_vel, -100, 100))

    if (
        area_range[0] < area < area_range[1]
    ):  # if the object is in the range we indicated, do not move
        forward_vel = 0
    elif area > area_range[1]:  # if it is too close, move backward
        forward_vel = -20
    elif (
        area < area_range[0] and area != 0
    ):  # if it is too far and if it detects an apple, move forward
        forward_vel = 20

    if (
        x == 0
    ):  # if it does not detect an apple, both speed and error should be 0 so the drone
        # will not rotate
        yaw_vel = 0
        error = 0

    drone.send_rc_control(0, forward_vel, 0, yaw_vel)
    return error

def fruit_fly(drone: Tello):
    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

    (
        model_apple_in_view,
        model_haar_cascade,
        model_detect_rotten,
        model_ripeness_predictor,
    ) = load_models(device)

    drone.connect()
    drone.LOGGER.info(f"Battery: {drone.get_battery()}%")

    img_to_tensor = torchvision.transforms.ToTensor()
    error = 0
    rdi_size = (100, 100)
    try:
        while True:
            img = drone.get_frame_read().frame

            # Convert the image to PyTorch tensor with the appropriate coloring
            torch_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
            torch_img = img_to_tensor(torch_img)
            apple_detected = (
                detect_apple(model_apple_in_view, torch_img, device)
            )
            if apple_detected:
                # Move towards apple
                marked_image, info = find_apple_center(drone, model_haar_cascade, img)
                error = track_apple(
                    drone, info, img.shape[1], [0.4, 0.4, 0], error, [6200, 6800]
                )

                # Trim image to only include the detected apple
                center_x, center_y = info[0]
                area = info[1]
                if area != 0:
                    side_length = np.sqrt(area)
                    x1 = int(center_x - side_length // 2)
                    x2 = int(center_x + side_length // 2)
                    y1 = int(center_y - side_length // 2)
                    y2 = int(center_y + side_length // 2)
                    torch_img = torch_img[..., y1:y2, x1:x2]
                    trimmed_image = cv2.resize(img[y1:y2, x1:x2], rdi_size)

                    # Detect ripeness/rotten
                    is_rotten = detect_rotten(model_detect_rotten, torch_img, device)
                    is_ripe = detect_ripe(model_ripeness_predictor, trimmed_image)

                    print(f"Rotten: {is_rotten}, Ripe: {is_ripe}")
                    cv2.imshow("Ripeness Detector Image", trimmed_image)

                img = marked_image

            cv2.imshow("Output", img)
            # if we click 'q' then land the drone
            if cv2.waitKey(1) & 0xFF == ord("q"):
                break
    finally:
        drone.land()
        drone.streamoff()

def load_mobilenet(
    num_outputs: int,
    device: str | torch.device = None,
):
    if device is None:
        device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    model = torch.hub.load("pytorch/vision:v0.10.0", "mobilenet_v2", verbose=False)
    # Replace the last layer with the number of classes we want
    model.classifier[-1] = nn.Linear(model.classifier[-1].in_features, num_outputs)
    model.to(device)
    return model

def load_models(
    device,
) -> tuple[nn.Module, cv2.CascadeClassifier, nn.Module, RipenessPredictor]:
    apple_in_view = load_mobilenet(num_outputs=2).to(device)
    apple_in_view.load_state_dict(
        torch.load("models/detect_apple/all_files_16its_2022-11-22_18-33-45.pt")
    )
    apple_in_view.eval()

    haar_cascade = cv2.CascadeClassifier("models/cascade/curated_set_cascade.xml")
    detect_rotten = load_mobilenet(num_outputs=2).to(device)
    detect_rotten.load_state_dict(
        torch.load("models/detect_rotten/all_files_16its_2022-11-23_13-55-28.pt")
    )
    detect_rotten.eval()

    ripeness_predictor = RipenessPredictor("models/ripeness/ripeness_model.sav")

    return (
        apple_in_view,
        haar_cascade,
        detect_rotten,
        ripeness_predictor,
    )

class WebcamTello(Tello):
    def __init__(self):
        import djitellopy

        Tello.threads_initialized = True
        host = "192.168.0.1.WEBCAM"
        super().__init__(host)
        self.responses = djitellopy.tello.drones[host]["responses"]
        self.state = djitellopy.tello.drones[host]["state"]
        self.responses.append("DUMMY")
        self.state["DUMMY"] = "DUMMY"

    def get_udp_video_address(self):
        return 0

    def send_command_with_return(
        self, command: str, timeout: int = Tello.RESPONSE_TIMEOUT
    ) -> str:
        return "okay"

    def send_command_without_return(self, command: str) -> None:
        pass

    def get_state_field(self, key: str):
        self.state[key] = -1
        return super().get_state_field(key)

def main():
    # Swap this line to use the real drone
    # drone = Tello()
    drone = WebcamTello()
    fruit_fly(drone)

if __name__ == "__main__":
    main()


import re
from os import fsync

def updating(filename,dico):

    RE = '(('+'|'.join(dico.keys())+')\s*=)[^\r\n]*?(\r?\n|\r)'
    pat = re.compile(RE)

    def jojo(mat,dic = dico):
        return str(dic[mat.group(2)]).join(mat.group(1,3))

    with open(filename,'rb') as f:
        content = f.read()

    with open(filename,'wb') as f:
        f.write(pat.sub(jojo,content))


def cors_preflight(methods):
    def wrapper(f):

        def options(self,  *args, **kwargs):
            return {'Allow': 'GET'}, 200, \
                   {'Access-Control-Allow-Origin': '*',
                    'Access-Control-Allow-Methods': methods,
                    'Access-Control-Allow-Headers': 'Authorization, Content-Type'}

        setattr(f, 'options', options)
        return f
    return wrapper

def mergedicts(dict1, dict2):
    for k in set(dict1.keys()).union(dict2.keys()):
        if k in dict1 and k in dict2:
            if isinstance(dict1[k], dict) and isinstance(dict2[k], dict):
                yield (k, dict(mergedicts(dict1[k], dict2[k])))
            else:
                # If one of the values is not a dict, you can't continue merging it.
                # Value from second dict overrides one in first and we move on.
                yield (k, dict2[k])
                # Alternatively, replace this with exception raiser to alert you of value conflicts
        elif k in dict1:
            yield (k, dict1[k])
        else:
            yield (k, dict2[k])


"""
mrks.py

Functions associated with mrks inversion
"""

import numpy as np
from opt_einsum import contract
import psi4
import time

class MRKS():
    """
    Wavefunction to KS_potential method based on
    [1] [PRL 115, 083001 (2015)],
    [2] [J. Chem. Phys. 146, 084103 (2017)].

    The XC potential is calculated on the grid
    instead of on the potential basis set.
    Whereas, the guide potential is still used and
    plays the role of v_hartree.
    And because of this, the grid for vxc for output
    has to be specified beforehand.

    For CIWavefunction as input, make sure to turn on
    option opdm and tpdm:
        psi4.set_options({
            "opdm": True,
            "tpdm": True,
            'REFERENCE': "RHF"
            })

    Attributes:
    -----------
    Vpot: psi4.core.VBase
        V_potential that contains the info of DFT spherical grid.
    npoint_DFT: int
        number of points for DFT spherical grid.
    vxc_hole_WF: np.ndarray
        vxc_hole_WF on spherical grid. This is stored
        because the calculation of this takes most time.
    """
    vxc_hole_WF = None

    def _vxc_hole_quadrature(self, grid_info=None, atol=1e-5, atol1=1e-4, Vpot=None):
        """
        Calculating v_XC^hole in [1] (15) using quadrature
        integral on the default DFT spherical grid.

        Side note: the calculation is actually quite sensitive to atol/atol1
        i.e. the way to handle singularities. Play with it if you
        have a chance.
        The current model is:
        R2 = |r1 - r2|^2
        R2[R2 <= atol] = infinity (so that 1/R = 0)
        R2[atol < R2 < atol1] = atol1

        When self.wfn.name() == CIWavefunction, opdm and tpdm are used
        for calculation;
        when self.wfn.name() == RHF, actually a simplified version (i.e.
        directly using exact HF exchange densities) is implemented. In other
        words, this part can be much quicker and simplifier for RHF by
        obtaining the exchange hole directly as K Matrix without doing
        double integral by quadrature.
        """
        if self.vxc_hole_WF is not None and grid_info is None:
            return self.vxc_hole_WF

        if self.eng.wfn.name() == "CIWavefunction":
            Tau_ijkl = self.eng.wfn.get_tpdm("SUM", True).np
            D2 = self.eng.wfn.get_opdm(-1, -1, "SUM", True).np
            C = self.eng.wfn.Ca()
            Tau_ijkl = contract("pqrs,ip,jq,ur,vs->ijuv", Tau_ijkl, C, C, C, C)
            D2 = C.np @ D2 @ C.np.T
        else:
            D2a = self.eng.wfn.Da().np
            D2b = self.eng.wfn.Db().np
            D2 = D2a + D2b

        if grid_info is None:
            vxchole = np.zeros(Vpot.grid().npoints())
            nblocks = Vpot.nblocks()
            points_func_outer = Vpot.properties()[0]
            blocks = None
        else:
            blocks, npoints, points_func_outer = grid_info
            vxchole = np.zeros(npoints)
            nblocks = len(blocks)
            points_func_outer.set_deriv(0)

        points_func = Vpot.properties()[0]
        points_func.set_deriv(0)

        # First loop over the outer set of blocks
        num_block_ten_percent = int(nblocks / 10)
        w1_old = 0
        print(f"vxchole quadrature double integral starts ({(Vpot.grid().npoints()):d} points): ", end="")
        start_time = time.time()
        for l_block in range(nblocks):
            # Print out progress
            if num_block_ten_percent != 0 and l_block % num_block_ten_percent == 0:
                print(".", end="")

            # Obtain general grid information
            if blocks is None:
                l_grid = Vpot.get_block(l_block)
            else:
                l_grid = blocks[l_block]

            l_x = np.array(l_grid.x())
            l_y = np.array(l_grid.y())
            l_z = np.array(l_grid.z())
            l_npoints = l_x.shape[0]

            points_func_outer.compute_points(l_grid)

            l_lpos = np.array(l_grid.functions_local_to_global())
            l_phi = np.array(points_func_outer.basis_values()["PHI"])[:l_npoints, :l_lpos.shape[0]]

            # if restricted:
            lD1 = D2[(l_lpos[:, None], l_lpos)]
            rho1 = contract('pm,mn,pn->p', l_phi, lD1, l_phi)
            rho1inv = (1 / rho1)[:, None]

            dvp_l = np.zeros_like(l_x)

            # if not restricted:
            #     dvp_l_b = np.zeros_like(l_x)

            # Loop over the inner set of blocks
            for r_block in range(Vpot.nblocks()):
                r_grid = Vpot.get_block(r_block)
                r_w = np.array(r_grid.w())
                r_x = np.array(r_grid.x())
                r_y = np.array(r_grid.y())
                r_z = np.array(r_grid.z())
                r_npoints = r_w.shape[0]

                points_func.compute_points(r_grid)

                r_lpos = np.array(r_grid.functions_local_to_global())

                # Compute phi!
                r_phi = np.array(points_func.basis_values()["PHI"])[:r_npoints, :r_lpos.shape[0]]

                # Build a local slice of D
                if self.eng.wfn.name() == "CIWavefunction":
                    lD2 = D2[(r_lpos[:, None], r_lpos)]
                    rho2 = contract('pm,mn,pn->p', r_phi, lD2, r_phi)

                    p, q, r, s = np.meshgrid(l_lpos, l_lpos, r_lpos, r_lpos, indexing="ij")
                    Tap_temp = Tau_ijkl[p, q, r, s]

                    n_xc = contract("mnuv,pm,pn,qu,qv->pq", Tap_temp, l_phi, l_phi, r_phi, r_phi)
                    n_xc *= rho1inv
                    n_xc -= rho2
                elif self.eng.wfn.name() == "RHF":
                    lD2 = self.eng.wfn.Da().np[(l_lpos[:, None], r_lpos)]
                    n_xc = - 2 * contract("mu,nv,pm,pn,qu,qv->pq", lD2, lD2, l_phi, l_phi, r_phi, r_phi)
                    n_xc *= rho1inv

                # Build the distnace matrix
                R2 = (l_x[:, None] - r_x) ** 2
                R2 += (l_y[:, None] - r_y) ** 2
                R2 += (l_z[:, None] - r_z) ** 2
                # R2 += 1e-34
                mask1 = R2 <= atol
                mask2 = (R2 > atol) * (R2 < atol1)
                if np.any(mask1 + mask2):
                    R2[mask1] = np.inf
                    R2[mask2] = atol1
                Rinv = 1 / np.sqrt(R2)

                # if restricted:
                dvp_l += np.sum(n_xc * Rinv * r_w, axis=1)

            # if restricted:
            vxchole[w1_old:w1_old + l_npoints] += dvp_l
            w1_old += l_npoints

        print("\n")
        print(f"Totally {vxchole.shape[0]} grid points takes {(time.time() - start_time):.2f}s "
              f"with max {psi4.core.get_global_option('DFT_BLOCK_MAX_POINTS')} points in a block.")
        assert w1_old == vxchole.shape[0], "Somehow the whole space is not fully integrated."
        if blocks is None:
            # if restricted:
            self.vxc_hole_WF = vxchole
            return self.vxc_hole_WF
        else:
            # if restricted:
            return vxchole

    def mRKS(self, maxiter, vxc_grid=None, v_tol=1e-4, D_tol=1e-7,
             eig_tol=1e-4, frac_old=0.5, init="scan",
             sing=(1e-5, 1e-4, 1e-5, 1e-4)):
        """
        the modified Ryabinkin-Kohut-Staroverov method.

        Currently it supports two different kind of input wavefunction:
            1) Psi4.CIWavefunction
            2) Psi4.RHF
        and it only supports spin-restricted wavefunction.
        Side note: spin-unrestricted HF wavefunction (psi4.UHF) can easily
        be supported but unrestricted CI or restricted/unrestricted CCSD
        can not, because of the absence of tpdm in both methods.

        parameters:
        ----------------------
            maxiter: int
                same as opt_max_iter
            vxc_grid: np.ndarray of shape (3, num_grid_points), opt
                When this is given, the final result will be represented
            v_tol: float, opt
                convergence criteria for vxc Fock matrices.
                default: 1e-4
            D_tol: float, opt
                convergence criteria for density matrices.
                default: 1e-7
            eig_tol: float, opt
                convergence criteria for occupied eigenvalue spectrum.
                default: 1e-4
            frac_old: float, opt
                Linear mixing parameter for current vxc and old vxc.
                If 0, no old vxc is mixed in.
                Should be in [0,1)
                default: 0.5.
            init: string, opt
                Initial guess method.
                default: "SCAN"
                1) If None, input wfn info will be used as initial guess.
                2) If "continue" is given, then it will not initialize
                but use the densities and orbitals stored. Meaningly,
                one can run a quick WY calculation as the initial
                guess. This can also be used to user speficified
                initial guess by setting Da, Coca, eigvec_a.
                3) If it's not continue, it would be expecting a
                method name string that works for psi4. A separate psi4 calculation
                would be performed.
            sing: tuple of float of length 4, opt.
                Singularity parameter for _vxc_hole_quadrature()
                default: (1e-5, 1e-4, 1e-5, 1e-4)
                [0]: atol, [1]: atol1 for dft_spherical grid calculation.
                [2]: atol, [3]: atol1 for vxc_grid calculation.

        returns:
        ----------------------
            The result will be save as self.grid.vxc
    """
        if not self.eng.wfn.name() in ["CIWavefunction", "RHF"]:
            raise ValueError("Currently only supports Psi4 CI wavefunction"
                             "inputs because Psi4 CCSD wavefunction currently "
                             "does not support two-particle density matrices.")

        if self.ref != 1:
            raise ValueError("Currently only supports Spin-Restricted "
                             "calculations since Spin-Unrestricted CI "
                             "is not supported by Psi4.")

        if self.guide_components != "hartree":
            raise ValueError("Hartree potential is necessary as the guide potential.")

        Nalpha = self.nalpha

        # Preparing DFT spherical grid
        functional = psi4.driver.dft.build_superfunctional("SVWN", restricted=True)[0]
        Vpot = psi4.core.VBase.build(self.eng.basis, functional, "RV")
        Vpot.initialize()
        Vpot.properties()[0].set_pointers(self.eng.wfn.Da())

        # Preparing for WF properties
        if self.eng.wfn.name() == "CIWavefunction":
            if not (psi4.core.get_global_option("opdm") and psi4.core.get_global_option("tpdm")):
                raise ValueError("For CIWavefunction as input, make sure to turn on opdm and tpdm.")
            # TPDM & ERI Memory check
            nbf = self.nbf
            I_size = (nbf ** 4) * 8.e-9 * 2
            numpy_memory = 2
            memory_footprint = I_size * 1.5
            if I_size > numpy_memory:
                psi4.core.clean()
                raise Exception("Estimated memory utilization (%4.2f GB) exceeds allotted memory \
                                            limit of %4.2f GB." % (memory_footprint, numpy_memory))
            else:
                print("Memory taken by ERI integral matrix and 2pdm is about: %.3f GB." % memory_footprint)

            opdm = np.array(self.eng.wfn.get_opdm(-1,-1,"SUM",False))
            tpdm = self.eng.wfn.get_tpdm("SUM", True).np

            Ca = self.eng.wfn.Ca().np

            mints = psi4.core.MintsHelper(self.eng.basis)

            Ca_psi4 = psi4.core.Matrix.from_array(Ca)
            I = mints.mo_eri(Ca_psi4, Ca_psi4, Ca_psi4, Ca_psi4).np
            # I = 0.5 * I + 0.25 * np.transpose(I, [0, 1, 3, 2]) + 0.25 * np.transpose(I, [1, 0, 2, 3])
            # Transfer the AO h into MO h
            h = Ca.T @ (self.T + self.V) @ Ca

            # Generalized Fock Matrix is constructed on the
            # basis of MOs, which are orthonormal.
            F_GFM = opdm @ h + contract("rsnq,rsmq->mn", I, tpdm)
            F_GFM = 0.5 * (F_GFM + F_GFM.T)

            del mints, I

            C_a_GFM = psi4.core.Matrix(nbf, nbf)
            eigs_a_GFM = psi4.core.Vector(nbf)
            psi4.core.Matrix.from_array(F_GFM).diagonalize(C_a_GFM,
                                                           eigs_a_GFM,
                                                           psi4.core.DiagonalizeOrder.Ascending)

            eigs_a_GFM = eigs_a_GFM.np / 2.0  # RHF
            C_a_GFM = C_a_GFM.np
            # Transfer to AOs
            C_a_GFM = Ca @ C_a_GFM

            # Solving for Natural Orbitals (NO)
            C_a_NO = psi4.core.Matrix(nbf, nbf)
            eigs_a_NO = psi4.core.Vector(nbf)
            psi4.core.Matrix.from_array(opdm).diagonalize(C_a_NO, eigs_a_NO, psi4.core.DiagonalizeOrder.Descending)
            eigs_a_NO = eigs_a_NO.np / 2.0  # RHF
            C_a_NO = C_a_NO.np
            C_a_NO = Ca @ C_a_NO

            # Rrepare components on the grid
            ebarWF      = self.eng.grid._average_local_orbital_energy(self.Dt[0], C_a_GFM, eigs_a_GFM, Vpot=Vpot)
            taup_rho_WF = self.eng.grid._pauli_kinetic_energy_density(self.Dt[0], C_a_NO, eigs_a_NO, Vpot=Vpot)
        elif self.eng.wfn.name() == "RHF":  # Since HF is a special case, there is no need for GFM and NO as in CI.
            epsilon_a = self.eng.wfn.epsilon_a_subset("AO", "OCC").np
            ebarWF = self.eng.grid._average_local_orbital_energy(self.Dt[0], self.ct[0][:,:Nalpha], epsilon_a, Vpot=Vpot)
            taup_rho_WF = self.eng.grid._pauli_kinetic_energy_density(self.Dt[0], self.ct[0], Vpot=Vpot)
        else:
            raise ValueError("Currently only supports Spin-Restricted "
                             "calculations since Spin-Unrestricted CI "
                             "is not supported by Psi4.")

        vxchole = self._vxc_hole_quadrature(atol=sing[0], atol1=sing[1], Vpot=Vpot)

        emax = np.max(ebarWF)

        # Initialization.
        if init is None:
            self.Da = np.copy(self.Dt[0])
            self.Coca = np.copy(self.ct[0])
            self.eigvecs_a = self.eng.wfn.epsilon_a().np[:Nalpha]
        elif init.lower()=="continue":
            pass
        else:
            wfn_temp = psi4.energy(init+"/" + self.eng.basis_str, molecule=self.eng.mol, return_wfn=True)[1]
            self.Da = np.array(wfn_temp.Da())
            self.Coca = np.array(wfn_temp.Ca())[:, :Nalpha]
            self.eigvecs_a = np.array(wfn_temp.epsilon_a())
            del wfn_temp

        vxc_old = 0.0
        Da_old = 0.0
        eig_old = 0.0
        for mRKS_step in range(1, maxiter+1):
            # ebarKS = self._average_local_orbital_energy(self.molecule.Da.np, self.molecule.Ca.np[:,:Nalpha], self.molecule.eig_a.np[:Nalpha] + self.vout_constant)
            ebarKS      = self.eng.grid._average_local_orbital_energy(self.Da, self.Coca, self.eigvecs_a[:Nalpha], Vpot=Vpot)
            taup_rho_KS = self.eng.grid._pauli_kinetic_energy_density(self.Da, self.Coca, Vpot=Vpot)
            # self.vout_constant = emax - self.molecule.eig_a.np[self.molecule.nalpha - 1]
            potential_shift = emax - np.max(ebarKS)
            self.shift = potential_shift

            vxc = vxchole + ebarKS - ebarWF + taup_rho_WF - taup_rho_KS + potential_shift

            # Add compulsory mixing parameter close to the convergence to help convergence HOPEFULLY

            verror = np.linalg.norm(vxc - vxc_old) / self.nbf ** 2
            if verror < v_tol:
                print("vxc stops updating.")
                break

            Derror = np.linalg.norm(self.Da - Da_old) / self.nbf ** 2
            eerror = (np.linalg.norm(self.eigvecs_a[:Nalpha] - eig_old) / Nalpha)
            if (Derror < D_tol) and (eerror < eig_tol):
                print("KSDFT stops updating.")
                break

            # linear Mixture
            if mRKS_step != 1:
                vxc = vxc * (1 - frac_old) + vxc_old * frac_old

            # Save old data.
            vxc_old = np.copy(vxc)
            Da_old = np.copy(self.Da)
            eig_old = np.copy(self.eigvecs_a[:Nalpha])

            vxc_Fock = self.eng.grid.dft_grid_to_fock(vxc, Vpot)

            self._diagonalize_with_potential_vFock(v=vxc_Fock)

            print(f"Iter: {mRKS_step}, Density Change: {Derror:2.2e}, Eigenvalue Change: {eerror:2.2e}, "
                  f"Potential Change: {verror:2.2e}.")

        if vxc_grid is not None:
            grid_info = self.eng.grid.grid_to_blocks(vxc_grid)
            grid_info[-1].set_pointers(self.eng.wfn.Da())

            # A larger atol seems to be necessary for user-defined grid
            vxchole = self._vxc_hole_quadrature(grid_info=grid_info,
                                                atol=sing[2], atol1=sing[3], Vpot=Vpot)
            if self.eng.wfn.name() == "CIWavefunction":
                ebarWF = self.eng.grid._average_local_orbital_energy(self.Dt[0],
                                                            C_a_GFM, eigs_a_GFM,
                                                            grid_info=grid_info,Vpot=Vpot)
                taup_rho_WF = self.eng.grid._pauli_kinetic_energy_density(self.Dt[0],
                                                                 C_a_NO, eigs_a_NO,
                                                                 grid_info=grid_info, Vpot=Vpot)
            elif self.eng.wfn.name() == "RHF":
                ebarWF = self.eng.grid._average_local_orbital_energy(self.Dt[0],
                                                            self.ct[0],
                                                            epsilon_a[:Nalpha],
                                                            grid_info=grid_info, Vpot=Vpot)
                taup_rho_WF = self.eng.grid._pauli_kinetic_energy_density(self.Dt[0],
                                                                 self.ct[0],
                                                                 grid_info=grid_info, Vpot=Vpot)
            ebarKS = self.eng.grid._average_local_orbital_energy(self.Da, self.Coca,
                                                        self.eigvecs_a[:Nalpha], grid_info=grid_info)
            taup_rho_KS = self.eng.grid._pauli_kinetic_energy_density(self.Da, self.Coca,
                                                             grid_info=grid_info, Vpot=Vpot)

            potential_shift = np.max(ebarWF) - np.max(ebarKS)
            self.shift = potential_shift

            vxc = vxchole + ebarKS - ebarWF + taup_rho_WF - taup_rho_KS + potential_shift
        self.grid_vxc = vxc
        return

    def _diagonalize_with_potential_vFock(self, v=None):
        """
        Diagonalize Fock matrix with additional external potential
        """

        if v is None:
            fock_a = self.V + self.T + self.va
        else:
            if self.ref == 1:
                fock_a = self.V + self.T + self.va + v
            else:
                valpha, vbeta = v
                fock_a = self.V + self.T + self.va + valpha
                fock_b = self.V + self.T + self.vb + vbeta

        self.Ca, self.Coca, self.Da, self.eigvecs_a = self.diagonalize( fock_a, self.nalpha )

        if self.ref == 1:
            self.Cb, self.Cocb, self.Db, self.eigvecs_b = self.Ca.copy(), self.Coca.copy(), self.Da.copy(), self.eigvecs_a.copy()
        else:
            self.Cb, self.Cocb, self.Db, self.eigvecs_b = self.diagonalize( fock_b, self.nbeta )


# 서로 다른 n개 중에서 r개 순서없이 고르기
# pick r items without of order from each different n items
# 서로 다른 n개 중에서 r개를 순서 없이 고르는 방법의 가짓수를 출력하시오.
# 1, 2, 3 서로 다른 3개 중에 2개를 고를 수 있는 방법의 가짓수는 (1, 2),
# (2, 3), (1, 3)의 3가지이다.
# p개 중에서 q개를 순서 없이 고르는 방법의 가짓수는 (p-1)개 중에서 (q-1)개를
# 선택하고 마지막 p번째 것을 선택하는 경우의 가짓수 + (p-1)개 중에서 q개를
# 선택하고 마지막 p번째 것을 선택하지 않는 경우의 가짓수이다.
# f(p, q)를 p개 중에서 q개를 순서 없이 선택하는 방법의 가짓수라고 정의하면,
# 위의 의미를 다음과 같은 점화 관계식으로 표현할 수 있다.
# f(p, q) = f(p-1, q-1) + f(p-1, q)
# 재귀 호출을 중단시키기 위해 가장 작은 경우나 특별한 몇 가지 경우 생각해보면
# - p개 중에서 1개를 순서 없이 선택하는 방법의 가짓수는 p,
# - p개 중에서 p개를 순서 없이 선택하는 방법의 가짓수는 1,
# - 10개 중에서 20개를 순서 없이 선택하는 방법의 가짓수는 0,
# 와 같이 경우들을 생각해 낼 수 있다.
# 서로 다른 n개 중에서 순서 없이 r개를 고를 수 있는 방법의 가짓수를 출력.
# method 1
a, b = map(int, input().split())
d = {}
def combi(a, b):
    if b == 1:
        d[(a, b)] = a
        return d[(a, b)]
    elif b == a:
        d[(a, b)] = 1
        return d[(a, b)]
    elif a < b:
        d[(a, b)] = 0
        return d[(a, b)]
    else:
        d[(a, b)] = combi(a-1, b-1) + combi(a-1, b)
        return d[(a, b)]
print(combi(a, b))


# Configuration file for the Sphinx documentation builder.

import os
import sys

# -- Project information

project = "IndieWeb Utils"
copyright = "capjamesg 2022"
author = "capjamesg"

sys.path.insert(0, os.path.abspath("../../src/"))

release = "0.8.0"
version = "0.8.0"

# -- General configuration

extensions = [
    "sphinx.ext.doctest",
    "sphinx.ext.autodoc",
    "sphinx.ext.autosummary",
    "sphinx.ext.intersphinx",
    "sphinx.ext.viewcode",
]

intersphinx_mapping = {
    "python": ("https://docs.python.org/3/", None),
    "sphinx": ("https://www.sphinx-doc.org/en/master/", None),
}
intersphinx_disabled_domains = ["std"]

templates_path = ["_templates"]

# -- Options for HTML output

# -- Options for EPUB output
epub_show_urls = "footnote"

html_static_path = ["_static"]

html_logo = "_static/indieweb.png"


# CCC 2019 Junior 2: Time to Decompress
#
# Author: Charles Chen
#
# Strings and loops

num_lines = int(input())
num_symbols = []
symbol_type = []

for i in range(num_lines):
    input_data = input().split()
    num_symbols.append(int(input_data[0]))
    symbol_type.append(input_data[1])

for i in range(num_lines):
    print(symbol_type[i] * num_symbols[i])


# 16. 3Sum Closest

# https://leetcode.com/problems/3sum-closest/

class Solution:
    def threeSumClosest(self, nums: List[int], target: int) -> int:
        nums.sort()
        min_diff = 99999999999999
        for i in range(len(nums) - 2):
            if i > 0 and nums[i] == nums[i - 1]:
                continue

            left, right = i + 1, len(nums) - 1
            while left < right:
                diff = (nums[i] + nums[left] + nums[right]) - target
                if abs(diff) < min_diff:
                    min_diff = abs(diff)
                    result = nums[i] + nums[left] + nums[right]

                if diff > 0:
                    right -= 1
                elif diff < 0:
                    left += 1
                else:
                    return target
        return result


from PIL import Image
from datetime import datetime
from time import sleep

import io
import socket
import struct
import numpy as np
import time
import base64
import xlsxwriter

workbook = xlsxwriter.Workbook('Server_time.xlsx')
worksheet = workbook.add_worksheet()

def current_mili_time():
  return int(round(time.time() * 1000))

def Main():
  server_socket = socket.socket()
  server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  server_socket.bind(('127.0.0.1', 8080))
  server_socket.listen(0)

  connection = server_socket.accept()[0]

  row = 0
  worksheet.write(row, 0, 'Start time')
  worksheet.write(row, 1, 'End time')
  row += 1

  try:
    while True:
        start_time = datetime.utcnow()
        worksheet.write(row, 0, "%s" % (start_time.microsecond/1000))
        # Receve image size
        image_len = connection.recv(4)
        image_size = struct.unpack('!i', image_len)[0]
        image_base64 = ''
        print(image_size)
        #Receve image
        while image_size > 0:
          if image_size >= 4096:
            data = connection.recv(4096)
            image_size -= len(data)
            image_base64 += data.decode('utf-8')
          else:
            data = connection.recv(image_size)
            image_size -= len(data)
            image_base64 += data.decode('utf-8')
        # Decode image
        image = open('pi_image.jpg', 'wb')
        image.write(base64.b64decode(image_base64))
        image.close()
        # Tensorflow
        sleep(0.150)
        data = 'idle'
        connection.send(data.encode())
        now = datetime.utcnow()
        #worksheet.write(row, 1, "%s" % (now.microsecond/1000))
        delay = ((start_time.microsecond/1000)+333)-(now.microsecond/1000)
        if delay > 1000:
            delay -= 1000
        sleep(delay/1000)
        now = datetime.utcnow()
        worksheet.write(row, 1, "%s" % (now.microsecond/1000))
        row += 1
  finally:
    workbook.close()
    connection.close()
    server_socket.close()

if __name__ == '__main__':
  Main()


# 【问题描述】
# 给定一个10进制数，将其转换为任意的进制数（不会出现17进制或以上）
# 【输入形式】
# 输入两个数M,N，其中M表示需要被转换的10进制数，N表示给定的进制，中间用空格隔开
# 【输出形式】
# M的N进制表示，如遇到字母请使用大写

# 【样例输入】
# 16 2

# 【样例输出】
# 10000

# 【样例说明】这就不用我多说了8
# 【评分标准】这也不用我多说了8

s = [int(i) for i in input().split()]
num = s[0]
b = s[1]
bits = []
while(num != 0):
    bits.append(num % b)
    num = num // b
bits.reverse()
for i in bits:
    if i >= 10:
        print(chr(ord('A')+i-10),end='')
    else:
        print(i,end='')

# for i in bits:
#     if i == 10:
#         print('A', end='')
#     elif i == 11:
#         print('B', end='')
#     elif i == 12:
#         print('C', end='')
#     elif i == 13:
#         print('D', end='')
#     elif i == 14:
#         print('E', end='')
#     elif i == 15:
#         print('F', end='')
#     else:
#         print(i, end='')


import sys
import logging
import gzip
from argparse import ArgumentParser
from typing import Dict, Iterator, List, Optional, Tuple

from dae.utils.verbosity_configuration import VerbosityConfiguration
from dae.genomic_resources import build_genomic_resource_repository
from dae.genomic_resources.genomic_context import GenomicContext
from dae.genomic_resources.genomic_context import get_genomic_context
from dae.genomic_resources.repository import GenomicResourceRepo
from dae.genomic_resources.gene_models import GeneModels, \
    build_gene_models_from_file, \
    build_gene_models_from_resource
from dae.genomic_resources.reference_genome import ReferenceGenome
from dae.genomic_resources.reference_genome import \
    build_reference_genome_from_file
from dae.genomic_resources.reference_genome import \
    build_reference_genome_from_resource

from dae.effect_annotation.annotator import EffectAnnotator
from dae.effect_annotation.effect import AnnotationEffect

logger = logging.getLogger(__name__)

class EffectAnnotatorBuilder:
    @staticmethod
    def set_arguments(parser: ArgumentParser) -> None:
        genomic_repository_group = parser.add_argument_group(
            "Genomic repository options")

        genomic_repository_group.add_argument(
            "-grr", "--genomic-repository-config-filename",
            help="Genomic Repository Configuraiton File"
        )

        gene_model_file_group = parser.add_argument_group(
            "Gene models file options")

        gene_model_file_group.add_argument(
            "-gmfn", "--gene-models-filename",
            help="Gene models file name."
        )
        gene_model_file_group.add_argument(
            "-gmff", "--gene-models-fileformat",
            help="Gene models file format."
        )
        gene_model_file_group.add_argument(
            "-gmmfn", "--gene-mapping-filename",
            help="Gene mapping file.",
            default=None,
            action="store",
        )
        gene_model_resource_group = parser.add_argument_group(
            "Gene models resource options")
        gene_model_resource_group.add_argument(
            "-gmri", "--gene-models-resource-id",
            help="Gene models resource id."
        )

        reference_genome_file_group = parser.add_argument_group(
            "Reference genome file options")
        reference_genome_file_group.add_argument(
            "-rgfn", "--reference-genome-filename",
            help="Reference genome file name."
        )

        reference_genome_resource_group = parser.add_argument_group(
            "Reference genome resource options")
        reference_genome_resource_group.add_argument(
            "-rgri", "--reference-genome-resource-id",
            help="Reference genome resource id."
        )

        parser.add_argument(
            "-pl", "--promoter-len",
            help="promoter length",
            default=0,
            type=int,
        )

    def __init__(self, args):
        self.args = args
        self._gc: Optional[GenomicContext] = None

    def get_genomic_context(self) -> GenomicContext:
        if not self._gc:
            self._gc = get_genomic_context()
        return self._gc

    def get_grr(self) -> GenomicResourceRepo:
        grr: Optional[GenomicResourceRepo] = None

        if self.args.genomic_repository_config_filename:
            grr = build_genomic_resource_repository(
                self.args.genomic_repository_config_filename)
        else:
            grr = self.get_genomic_context().get_genomic_resources_repository()
        if grr:
            return grr
        return build_genomic_resource_repository()

    def get_gene_models(self) -> GeneModels:
        if self.args.gene_models_resource_id:
            resource = self.get_grr().get_resource(
                self.args.gene_models_resource_id)
            return build_gene_models_from_resource(resource).load()

        if self.args.gene_models_filename:
            return build_gene_models_from_file(
                self.args.gene_models_filename,
                self.args.gene_models_fileformat,
                self.args.gene_mapping_filename)

        gm = self.get_genomic_context().get_gene_models()
        if gm:
            return gm
        raise ValueError("No gene models could be found!")

    def get_refernce_genome(self) -> ReferenceGenome:
        if self.args.reference_genome_resource_id:
            resource = self.get_grr().get_resource(
                self.args.reference_genome_resource_id)
            return build_reference_genome_from_resource(resource)

        if self.args.reference_genome_filename:
            return build_reference_genome_from_file(
                self.args.reference_genome_filename)

        ref = self.get_genomic_context().get_reference_genome()
        if ref:
            return ref
        raise ValueError("No reference genome could be found!")

    def build_effect_annotator(self):
        ref = self.get_refernce_genome()
        gm = self.get_gene_models()
        logger.info(
            "Building effect annotator with:\n"
            "\treferende genome from %s,\n"
            "\tgene models from %s, and\n"
            "\tpromoter lengths of %s",
            ref.resource.resource_id, gm.resource.resource_id,
            self.args.promoter_len)
        return EffectAnnotator(ref, gm, promoter_len=self.args.promoter_len)

class VariantColumnInputFile:
    variant_columns = ["chrom", "pos",
                       "location", "variant", "ref", "alt"]

    @staticmethod
    def set_argument(parser: ArgumentParser):
        variant_columns_group = parser.add_argument_group(
            "Variant columns")
        for variant_column in VariantColumnInputFile.variant_columns:
            variant_columns_group.add_argument(
                f"--{variant_column}-col",
                default=variant_column)
        input_file_group = parser.add_argument_group(
            "Input file")
        input_file_group.add_argument("input_filename",
                                      nargs="?", default="-")
        input_file_group.add_argument("--input-sep", default="\t")

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

        # open file
        filename = self.args.input_filename
        if filename == "-":
            self.file = sys.stdin
        else:
            if filename.endswith("gz"):
                self.file = gzip.open(filename, "rt")
            else:
                self.file = open(filename, "rt")  # pylint: disable=R1732

        # read header
        self.header: List[str] = self.file.readline(). \
            strip("\n\r").split(self.args.input_sep)

        # prepare the variant_attribute_index
        args_dict = vars(self.args)
        self.variant_attribute_index: Dict[str, int] = {}
        for variant_attribute in VariantColumnInputFile.variant_columns:
            col = args_dict[f"{variant_attribute}_col"]
            idx = [i for i, h in enumerate(self.header) if h == col]
            if len(idx) > 1:
                raise ValueError(
                    f"the column {col} is repeated twice in the "
                    f"input file {filename}")
            if len(idx) == 1:
                self.variant_attribute_index[variant_attribute] = idx[0]

    def get_header(self) -> List[str]:
        return self.header

    def get_lines(self) -> Iterator[Tuple[List[str], Dict[str, str]]]:
        for line in self.file:
            columns = line.strip("\n\r").split(self.args.input_sep)
            variant_attributes = {
                k: columns[i] for k, i in self.variant_attribute_index.items()
            }
            yield columns, variant_attributes

    def close(self) -> None:
        self.file.close()

class VariantColumnOutputFile:
    @staticmethod
    def set_argument(parser: ArgumentParser):
        output_file_group = parser.add_argument_group(
            "Output file")
        output_file_group.add_argument("output_filename",
                                       nargs="?", default="-")
        output_file_group.add_argument("--output-sep", default="\t")

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

        filename = self.args.output_filename
        if filename == "-":
            self.file = sys.stdout
        else:
            if filename.endswith("gz"):
                self.file = gzip.open(filename, "wt")
            else:
                self.file = open(filename, "wt")  # pylint: disable=R1732

    def write_columns(self, columns) -> None:
        print(*columns, sep=self.args.output_sep, file=self.file)

    def close(self) -> None:
        self.file.close()

class AnnotationAttributes:
    ALL_ATTRIBUTE_IDXS = {aa: aai for aai, aa in enumerate(
        ["worst_effect", "gene_effects", "effect_details"])}

    @staticmethod
    def set_argument(parser: ArgumentParser, default_columns: str =
                     "worst_effect,gene_effects,effect_details"):
        annotation_attributes_group = parser.add_argument_group(
            "Annotation attributes.")
        annotation_attributes_group. \
            add_argument("--annotation-attributes",
                         default=default_columns,
                         help="The available attributes are "
                         "worst_effect, gene_effects, and effect_details. "
                         "Examples: "
                         "1. 'worst_effect, gene_effects';"
                         "2. 'WE: worst_effect, GE: gene_effects, "
                         "ED: effect_details'"
                         f"The default is : '{default_columns}'.")

    def __init__(self, args):
        self.args = args
        self.out_attributes: List[str] = []
        self.source_attributes: List[str] = []

        for attribute_def in self.args.annotation_attributes.split(","):
            parts = attribute_def.split(":")
            if len(parts) == 1:
                out = parts[0]
                source = parts[0]
            elif len(parts) == 2:
                out = parts[0]
                source = parts[1]
            else:
                raise ValueError(
                    "Incorrect attribute definition. "
                    "TO IMPROVE MESSAGE!")
            self.out_attributes.append(out)
            self.source_attributes.append(source)
        if len(self.out_attributes) != len(set(self.out_attributes)):
            raise ValueError(
                "The output attributes should not be repeated. "
                "TO IMPROVE MESSAGE!!!")
        self.value_idxs = [AnnotationAttributes.ALL_ATTRIBUTE_IDXS[aa]
                           for aa in self.source_attributes]

    def get_out_attributes(self) -> List[str]:
        return self.out_attributes

    def get_source_attributes(self) -> List[str]:
        return self.source_attributes

    def get_values(self, effect) -> List[str]:
        full_desc = AnnotationEffect.effects_description(effect)
        return [full_desc[idx] for idx in self.value_idxs]

def cli_columns():
    parser = ArgumentParser(
        description="Annotate Variant Effects in a Column File.")

    VerbosityConfiguration.set_argumnets(parser)
    EffectAnnotatorBuilder.set_arguments(parser)
    VariantColumnInputFile.set_argument(parser)
    VariantColumnOutputFile.set_argument(parser)
    AnnotationAttributes.set_argument(parser)

    args = parser.parse_args(sys.argv[1:])
    VerbosityConfiguration.set(args)
    annotator = EffectAnnotatorBuilder(args).build_effect_annotator()
    input_file = VariantColumnInputFile(args)
    output_file = VariantColumnOutputFile(args)
    annotation_attributes = AnnotationAttributes(args)

    output_file.write_columns(
        input_file.get_header() + annotation_attributes.get_out_attributes())
    for columns, vdef in input_file.get_lines():
        logger.debug("vdef: %s AAA", vdef)
        effect = annotator.do_annotate_variant(**vdef)
        output_file.write_columns(
            columns + annotation_attributes.get_values(effect)
        )

def cli_vcf():
    # pylint: disable=C0415
    # type: ignore
    import pysam

    parser = ArgumentParser(
        description="Annotate Variant Effects in a VCF file.")

    VerbosityConfiguration.set_argumnets(parser)
    EffectAnnotatorBuilder.set_arguments(parser)
    AnnotationAttributes.set_argument(
        parser,
        default_columns="WE:worst_effect,GE:gene_effects,ED:effect_details")

    parser.add_argument("input_filename", help="input VCF variants file name")
    parser.add_argument(
        "output_filename", nargs="?", help="output file name (default: stdout)"
    )
    args = parser.parse_args(sys.argv[1:])
    VerbosityConfiguration.set(args)
    annotator = EffectAnnotatorBuilder(args).build_effect_annotator()
    annotation_attributes = AnnotationAttributes(args)

    # pylint: disable=no-member
    infile = pysam.VariantFile(args.input_filename)
    if args.output_filename is None:
        outfile = sys.stdout
    else:
        outfile = open(args.output_filename, "w")  # pylint: disable=R1732

    # handling the header
    header = infile.header
    header.add_meta(
        "variant_effect_annotation", "GPF variant effects annotation."
    )
    header.add_meta(
        "variant_effect_annotation_command", f'"{" ".join(sys.argv)}"'
    )
    source_attribute_description = {
        "worst_effect": "The worst effect.",
        "gene_effects": "Gene effects.",
        "effect_details": "Detailed effects."
    }
    for out_a, src_a in zip(annotation_attributes.get_out_attributes(),
                            annotation_attributes.get_source_attributes()):
        header.info.add(out_a, "A", "String",
                        source_attribute_description[src_a])

    print(str(header), file=outfile, end="")

    # handling the variants
    out_as = annotation_attributes.get_out_attributes()
    for variant in infile:
        buffers = [list([]) for _ in out_as]

        for alt in variant.alts:
            effect = annotator.do_annotate_variant(
                chrom=variant.chrom,
                pos=variant.pos,
                ref=variant.ref,
                alt=alt
            )
            for buff, v in zip(buffers,
                               annotation_attributes.get_values(effect)):
                buff.append(v)

        for out_a, buff in zip(out_as, buffers):
            variant.info[out_a] = ",".join(buff)
        print(str(variant), file=outfile, end="")

    infile.close()
    if args.output_filename:
        outfile.close()

if __name__ == "__main__":
    cli_columns()


class Solution:
    def getSkyline(self, buildings: [[int]]) -> [[int]]:
        if not buildings:
            return []
        if len(buildings) == 1:
            return [[buildings[0][0], buildings[0][2]], [buildings[0][1], 0]]

        mid = len(buildings) // 2
        left = self.getSkyline(buildings[:mid])
        right = self.getSkyline(buildings[mid:])
        return self.merge(left, right)

    def merge(self, left, right):
        lh = rh = l = r = 0
        res = []
        while l < len(left) and r < len(right):
            if left[l][0] < right[r][0]:
                cp = [left[l][0], max(left[l][1], rh)]
                lh = left[l][1]
                l += 1
            elif left[l][0] > right[r][0]:
                cp = [right[r][0], max(right[r][1], lh)]
                rh = right[r][1]
                r += 1
            else:
                cp = [left[l][0], max(left[l][1], right[r][1])]
                lh, rh = left[l][1], right[r][1]
                l += 1
                r += 1
            if len(res) == 0 or res[-1][1] != cp[1]:
                res.append(cp)
        res += left[l:] + right[r:]
        return res


# Tengo una lista con datos de clientes:
# DNI, nombre y apellido, monto de deuda en pesos y localidad.
# Salida:
# 1.El apellido del mayor deudor es: Massingham
# 2.El total de deuda acumulada de los riocuartenses es de $624606
# 3.Los nombres de pila de los clientes cuyos DNI comiencen con 2 son:
# Elmore
# Wheeler

datos = [
'37572991#Shauna Romanov#137345#Villa María',
'43666785#Brenden Raynard#48176#Villa María',
'33950484#Ronna Massingham#187725#Villa María',
'31735292#Mirabella Fitzpayn#111838#Sampacho',
'44444776#Amabelle Dominetti#39495#Villa María',
'42872667#Grady Aronsohn#34119#La Carlota',
'36482697#Kalinda Lamplough#134823#Sampacho',
'39917430#Clemmy Grigorian#37985#Sampacho',
'47692622#Arley Farrell#105085#Río Cuarto',
'20765699#Elmore Godber#130063#La Carlota',
'43509224#Tessa Dumingo#94858#Villa María',
'22334742#Wheeler Tetford#53174#La Carlota',
'35595922#Eachelle Ronaghan#157894#Río Cuarto',
'30420756#Drucy Corriea#109433#La Carlota',
'35296538#Beatrisa Wanden#157237#Río Cuarto',
'38077386#Debi Shine#38621#Río Cuarto',
'36431955#Timothea Simonson#165769#Río Cuarto',
'34528663#Chrissy Sainsbury#104154#Sampacho',
'43839759#Leonid Mingauld#106125#Sampacho',
'19987470#Rasla Frankiewicz#139459#Villa María'
]

nuevalista = []
apellido = []
apellido_mayor = ""
mayor_deudor = 0
deuda_acum = ""

for elementos in datos:
    nuevalista = elementos.split("#")
    deuda = int(nuevalista[2])
    apellido = nuevalista[1].split()
    if deuda > mayor_deudor:
        mayor_deudor = deuda
        apellido_mayor = apellido

apellido_mayor = apellido_mayor.pop(1)
print("El apellido del mayor deudor es",apellido_mayor)

acumulado = 0
monto_deuda = 0
for i in datos:
    separador = i.split("#")
    localidad = separador[3]
    if localidad == "Río Cuarto":
        monto_deuda = int(separador[2])
        acumulado += monto_deuda

print("El monto de deuda acumulada de Rio cuartenses es de $",acumulado)

#     mayor_deudor = elementos[2]

# print(mayor_deudor)

#3
nombres = []
dni = []

for i in datos:
    separador = i.split("#")
    nombres = separador[1]
    dni = separador[0]
    if dni[0] == "2":
        nombres = nombres.split()
        print(nombres[0])


import csv
import os
import re
#from math import round
import sys
import numpy
from matplotlib.lines import Line2D
import matplotlib.pyplot as plt

plt.rcParams.update({
    "text.usetex": True,
    "font.family": "Helvetica",
    "font.size": 18
})

if len(sys.argv)==2:
    file='-'+sys.argv[1]
else:
    file=""

if "DISPLAY" not in os.environ:
    os.environ["DISPLAY"] = ":0"

xdata = {}
ydata = {}

name_to_nx = {}
name_to_nt = {}

with open('perfdata'+file+'.csv','r',newline='') as cfd:
    skip = True
    for row in csv.reader(cfd):
        if skip:
            skip = False
            continue
        #name = "%s-%d" % (row[0], int(row[1]))
        name = row[0]
        nx = row[1]
        nt = row[2]
        if name in name_to_nt:
            if name_to_nt[name] != nt:
                print("WARNING: Multiple values of nt were used")
        else:
            name_to_nt[name] = nt
        if name in name_to_nx:
            if name_to_nx[name] != nx:
                print("WARNING: Multiple values of nx were used")
        else:
            name_to_nx[name] = nx
        if name not in xdata:
            xdata[name] = []
            ydata[name] = []
        nthreads = float(row[3])
        xdata[name] += [nthreads]
        ydata[name] += [float(row[6])]

import numpy as np
from scipy.optimize import curve_fit as cf

def fixname(s):
    while True:
        n = re.sub(r'(\d)(\d\d\d)\b',r'\1,\2',s)
        if s == n:
            return s
        s = n

symbols = {
    "java" : "D",
    "c++" : "8",
    "cxx" : "8",
    "charm++" : "x",
    "hpx" : "+",
    "julia" : "v",
    "python" : "*",
    "swift" : "^",
    "chapel" : ">",
    "chapelng" : "<",
    "go" : "s",
    "rust" : "p",
    "heat" : "x",
    "heat_ghosts" : "p"
}

colors = {
    "java" : "darkgray",
    "c++" : "dimgray",
    "cxx" : "dimgray",
    "charm++" : "gray",
    "hpx" : "black",
    "julia" : "black",
    "python" : "black",
    "swift" : "dimgray",
    "chapel" : "gray",
    "chapelng" : "darkgray",
    "go" : "silver",
    "rust" : "black",
    "heat" : "black",
    "heat_ghosts" : "gray"
}

lines = {
    "java" : "-",
    "c++" : "--",
    "cxx" : ":",
    "charm++" : "-",
    "hpx" : "--",
    "julia" : ":",
    "python" : "-",
    "swift" : "--",
    "chapel" : ":",
    "chapelng" : "-",
    "go" : "--",
    "rust" : ":",
    "heat" : "-",
    "heat_ghosts" : "--"
}

lineLabels = []
labels = []

for name in xdata:
    xv = np.asarray(xdata[name])
    yv = np.asarray(ydata[name])
    assert len(xv) == len(yv)
    fix = fixname(name)
    symbol = symbols[name]
    color = colors[name]
    labels.append(fix)
    lineLabels.append(Line2D([0], [0], color=color, linewidth=3, linestyle='--', marker=symbol))
    p = plt.semilogy(xv,yv,symbol,color=color)

    def rt(x, k, p, o, o2, o3):
        return k*(1-p + p/x + o*np.log(x) + o2*np.sqrt(x)+o3*x)

    if len(xv) > 3:
        try:
            bounds_upper = [np.inf, 1, 1, 1, 1]
            bounds_lower = [0 for x in bounds_upper]
            bounds = (tuple(bounds_lower), tuple(bounds_upper))
            r  = cf(rt,xv,yv,maxfev=5000,bounds=bounds)
        except Exception as e:
            print("Could not fit curve for:",name,e)
            continue
        k=r[0][0]
        pbar=r[0][1]
        o=r[0][2]
        o2=r[0][3]
        o3=r[0][4]
        print("For ",name,": Parallel=","%.8g" % pbar," using ",len(xv)," run data pts.",sep='')
        overheads = 0
        if o > 1e-14:
            print("   Overhead log(N)=%.8g:" % o),
            overheads += 1
        if o2 > 1e-14:
            print("   Overhead sqrt(N)=%.8g:" % o2),
            overheads += 1
        if o3 > 1e-14:
            print("   Overhead N=%.8g:" % o3),
            overheads += 1
        if overheads == 0:
            print("   No appreciable overheads")
        corr_matrix = numpy.corrcoef(xv,yv)
        corr = corr_matrix[0,1]
        print("r2 = ",corr**2)
        print()
        xv2 = np.asarray(range(1,round(1+max(xdata[name]))))
        yv2 = rt(xv2,*r[0])
        line = lines[name]
        plt.semilogy(xv2,yv2,line,color=color)
        #plt.semilogy(xv2,yv2,'-',label='fit '+fix,color=color)
plt.legend(lineLabels,labels,ncol=4,shadow=True,fancybox=True,loc='upper center', bbox_to_anchor=(0.5, -0.15))
ax = plt.gca()
#ax.legend(loc='upper center', bbox_to_anchor=(0.5, -0.15),
#          fancybox=True, shadow=True, ncol=4)
plt.grid()
plt.xlabel("\#cores")
plt.ylabel("Time [s]")
plt.title("nx="+nx+" and nt="+nt)
plt.savefig('plot'+file+'.pdf',bbox_inches='tight')
plt.savefig('plot'+file+'.png',bbox_inches='tight')
plt.tight_layout()
print("Saving to plotme.png")
plt.savefig("plotme.png")
plt.show()


import cv2 as cv
from tkinter import filedialog

# Reading images
# img = cv.imread('index.jpg')
# cv.imshow("Image", img)
# cv.waitKey(0)

# Rescaling
def rescale(frame, scale=0.75):
    width = int(frame.shape[1] * scale)
    height = int(frame.shape[0] * scale)

    dimensions = (width, height)

    return cv.resize(frame, dimensions, interpolation=cv.INTER_AREA)

# Reading Videos
capture = cv.VideoCapture(filedialog.askopenfilename())

while True:
    ret, frame = capture.read()
    frame_resized = rescale(frame)
    cv.imshow("Video", frame_resized)
    if cv.waitKey(20) & 0xFF == ord('d'):
        break
capture.release()
cv.destroyAllWindows()


from safegtk import SafeGTK
import rpyc
import gobject
import gtk
import pygtk
pygtk.require('2.0')

def BrowserServiceFactory(browser):
    class BrowserService(rpyc.Service):
        def on_connect(self, conn):
            conn._config["allow_public_attrs"] = True

        def exposed_navigate(self, url):
            old_url = browser.txt_url.get_text()
            if url.startswith("/"):
                base = old_url.split("/")[0]
                url = base + url
            browser.txt_url.set_text(url)
            browser.on_navigate(None)
    return BrowserService

class Browser(object):
    def __init__(self):
        self.conn = None

        window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        window.set_resizable(True)
        window.connect("destroy", self.on_close)
        window.set_title("Web8 Browser")
        self.box_main = gtk.VBox()
        self.box_main.show()
        window.add(self.box_main)

        hbox1 = gtk.HBox()
        hbox1.show()
        self.box_main.pack_start(hbox1, fill=False, expand=False)

        self.txt_url = gtk.Entry()
        self.txt_url.set_text("localhost/main")
        self.txt_url.show()
        self.txt_url.connect("activate", self.on_navigate)
        hbox1.pack_start(self.txt_url)

        btn_send = gtk.Button("Go")
        btn_send.show()
        btn_send.connect("clicked", self.on_navigate)
        hbox1.pack_start(btn_send, fill=False, expand=False, padding=10)

        self.box_content = None
        window.show()

    def on_close(self, widget):
        if self.conn:
            self.conn.close()
            self.conn = None
        gtk.main_quit()

    def on_navigate(self, widget, data=None):
        url = self.txt_url.get_text()
        if "/" not in url:
            url += "/"
        host, page = url.split("/", 1)
        if ":" in host:
            addr, port = host.split(":", 1)
            port = int(port)
        else:
            addr = host
            port = 18833
        if self.conn:
            self.conn.close()
            self.conn = None

        if self.box_content:
            self.box_main.remove(self.box_content)
            self.box_content.destroy()
            self.box_content = None
        self.box_content = gtk.VBox()
        self.box_content.show()
        self.box_main.pack_start(self.box_content)

        self.conn = rpyc.connect(host, port, service=BrowserServiceFactory(self))
        gobject.io_add_watch(self.conn, gobject.IO_IN, self.bg_server)
        self.conn.root.get_page(SafeGTK, self.box_content, page)

    def bg_server(self, source=None, cond=None):
        if self.conn:
            self.conn.poll_all()
            return True
        else:
            return False

if __name__ == "__main__":
    b = Browser()
    gtk.main()


import streamlit as st
import numpy as np
import pandas as pd
import plotly.express as px
import ast

def read_df():
    df = pd.read_csv("250_top_IMDB.csv")

    def convert_runtime(runtime):
        parts = runtime.split()
        total_minutes = 0
        for part in parts:
            if "h" in part:
                total_minutes += int(part.replace("h", "")) * 60
            elif "m" in part:
                total_minutes += int(part.replace("m", ""))
        return total_minutes

    df["runtime"] = df["runtime"].apply(convert_runtime)
    nanValue = df["gross_us_canada"][4]

    def convert_gross(gross_val):
        if nanValue is gross_val:
            return 0
        else:
            return int(gross_val.replace("$", "").replace(",", ""))

    def convert_parental_guide(parental_guide_val):
        if (
            parental_guide_val in ["null", "blank", "Not Rated"]
            or nanValue is parental_guide_val
        ):
            return "Unrated"
        return parental_guide_val

    def extract_keys(dictionary):
        return list(dictionary.keys())[0]

    df["gross_us_canada"] = df["gross_us_canada"].apply(convert_gross)
    df["parental_guide"] = df["parental_guide"].apply(convert_parental_guide)

    df["genre"] = df["genre"].apply(ast.literal_eval)
    df["directore"] = df["directore"].apply(ast.literal_eval)
    df["writer"] = df["writer"].apply(ast.literal_eval)
    df["star"] = df["star"].apply(ast.literal_eval)

    df["dict_id"] = df["dict_id"].apply(ast.literal_eval)
    df["dict_id"] = df["dict_id"].apply(extract_keys)

    df.drop(columns=["storyline"], inplace=True)

    return df

def top_stars(df, top_n=10):
    df_star = pd.DataFrame(
        columns=[
            "person_id",
            "person_name",
        ]
    )

    def create_df_main(df, df_star):
        for index, row in df.iterrows():
            star = row["star"]
            for i in star:
                new_row = {
                    "person_id": star[i],
                    "person_name": i,
                }
                df_star.loc[len(df_star)] = new_row
        return df_star

    df_star = create_df_main(df, df_star)
    temp = df_star.value_counts()
    temp = temp.head(top_n)
    return pd.DataFrame(temp).reset_index()

df = read_df()
top_n = 10

st.set_page_config(page_title="Static Charts")
st.title("Second Subcategory; Static Charts")

top_10_movies = df.nlargest(top_n, "gross_us_canada")
fig = px.bar(
    top_10_movies,
    x="title",
    y="gross_us_canada",
    title="Bar Chart of 10 Best Selling Movies",
)
tab1, tab2 = st.tabs(["Streamlit theme (default)", "Plotly native theme"])
with tab1:
    st.plotly_chart(fig, theme="streamlit")
with tab2:
    st.plotly_chart(fig, theme=None)

top_10_stars = top_stars(df)
fig = px.bar(
    top_10_stars,
    x="person_name",
    y="count",
    title="Bar Chart of the 10 Most Prolific Actors",
)
tab1, tab2 = st.tabs(["Streamlit theme (default)", "Plotly native theme"])
with tab1:
    st.plotly_chart(fig, theme="streamlit")
with tab2:
    st.plotly_chart(fig, theme=None)

temp = df.explode("genre")
temp = temp["genre"].value_counts()
temp = pd.DataFrame(temp).reset_index()
fig = px.pie(
    temp, values="count", names="genre", title="Pie Chart of the number of each Genre"
)
tab1, tab2 = st.tabs(["Streamlit theme (default)", "Plotly native theme"])
with tab1:
    st.plotly_chart(fig, theme="streamlit")
with tab2:
    st.plotly_chart(fig, theme=None)

temp = df["parental_guide"].value_counts()
temp = pd.DataFrame(temp).reset_index()
fig = px.pie(
    temp,
    values="count",
    names="parental_guide",
    title="Pie Chart of the number of `parental_guide` Rating in Movies",
)
tab1, tab2 = st.tabs(["Streamlit theme (default)", "Plotly native theme"])
with tab1:
    st.plotly_chart(fig, theme="streamlit")
with tab2:
    st.plotly_chart(fig, theme=None)

df_exploded = df.explode("genre")
genre_age_counts = (
    df_exploded.groupby(["genre", "parental_guide"]).size().unstack(fill_value=0)
)
genre_age_counts
st.bar_chart(genre_age_counts)


import numpy as np
import imageio
import os
from ssr.utility.logging_extension import logger

def read_hdr_image(in_hdr_png):
    # =========================================================================
    # https://github.com/imageio/imageio/issues/204
    # Read with FreeImage instead of Pillow is MANDATORY TO READ 16 bit color
    # pngs correctly!!!!
    hdr_img = imageio.imread(in_hdr_png, "PNG-FI").astype(dtype=np.float64)
    # =========================================================================

    if hdr_img.ndim == 3:
        red_channel = hdr_img[:, :, 0]
        green_channel = hdr_img[:, :, 1]
        blue_channel = hdr_img[:, :, 2]
        assert np.amax(red_channel) > 7
        assert np.amax(green_channel) > 7
        assert np.amax(blue_channel) > 7

    return hdr_img

def write_as_ldr_image(hdr_img, ofp):
    if os.path.exists(ofp):
        os.remove(ofp)
    imageio.imwrite(ofp, hdr_img.astype(dtype=np.uint8))

def write_as_hdr_image(hdr_img, ofp):
    if os.path.exists(ofp):
        os.remove(ofp)
    imageio.imwrite(ofp, hdr_img.astype(dtype=np.uint16))

def split_msi(in_png, r_out_png, g_out_png, b_out_png, target_dtype=np.uint8):
    im = imageio.imread(in_png)

    imageio.imwrite(r_out_png, im[:, :, 0].astype(dtype=target_dtype))
    imageio.imwrite(g_out_png, im[:, :, 1].astype(dtype=target_dtype))
    imageio.imwrite(b_out_png, im[:, :, 2].astype(dtype=target_dtype))

def combine_msi(
    b_out_png, g_out_png, r_out_png, out_png, target_dtype=np.uint8
):
    image_b = imageio.imread(b_out_png)
    image_g = imageio.imread(g_out_png)
    image_r = imageio.imread(r_out_png)

    combined_np = np.dstack(
        (np.array(image_r), np.array(image_g), np.array(image_b))
    )

    imageio.imwrite(out_png, combined_np.astype(dtype=target_dtype))

def tone_map_channel(channel, percentile=0.5, exp=1.0 / 2.2):

    # =========================================================================
    # Use QGIS to examine the PNG result (i.e. color range of the created file)
    # =========================================================================

    # gamma correction
    # Could be also computed with GDAL
    # https://gdal.org/programs/gdal_translate.html#cmdoption-gdal-translate-exponent
    tone_mapped_channel = np.power(channel, exp)

    # cut off the small values
    below_thres = np.percentile(
        tone_mapped_channel.reshape((-1, 1)), percentile
    )
    tone_mapped_channel[tone_mapped_channel < below_thres] = below_thres
    # cut off the big values
    above_thres = np.percentile(
        tone_mapped_channel.reshape((-1, 1)), 100 - percentile
    )
    tone_mapped_channel[tone_mapped_channel > above_thres] = above_thres

    # Put in range 0 - 255
    tone_mapped_channel = (
        255 * (tone_mapped_channel - below_thres) / (above_thres - below_thres)
    )
    return tone_mapped_channel

def tone_map_separate(im, percentile=0.5, exp=1.0 / 2.2):
    red_channel = im[:, :, 0]
    green_channel = im[:, :, 1]
    blue_channel = im[:, :, 2]

    red_channel = tone_map_channel(red_channel, percentile, exp)
    green_channel = tone_map_channel(green_channel, percentile, exp)
    blue_channel = tone_map_channel(blue_channel, percentile, exp)

    hdr_result_tone_mapped = np.dstack(
        (
            np.array(red_channel),
            np.array(green_channel),
            np.array(blue_channel),
        )
    )

    return hdr_result_tone_mapped

def rgb_2_gray(rgb):
    weights = get_rgb_2_gray_weights()
    return (
        weights[0] * rgb[..., 0]
        + weights[1] * rgb[..., 1]
        + weights[2] * rgb[..., 2]
    )

def get_rgb_2_gray_weights(use_luminance_weights=True):
    # https://brohrer.github.io/convert_rgb_to_grayscale.html
    #   Channel-dependent luminance perception
    #       Y_linear = 0.2126 R + 0.7152 G + 0.0722 B
    #   Gamma compression
    #       ...
    #   Linear approximation
    #       Y' = 0.299 + 0.587 G + 0.114 B
    #   Which one should I use?
    #      If close is good enough or if you really care about speed, use the
    #      linear approximation of gamma correction.
    #      This is the approach used by MATLAB, Pillow, and OpenCV

    # https://stackoverflow.com/questions/12201577/how-can-i-convert-an-rgb-image-into-grayscale-in-python
    #   gray = 0.2989 * r + 0.5870 * g + 0.1140 * b
    if use_luminance_weights:
        return [0.2989, 0.5870, 0.1140]
    else:
        return [1.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0]

def tone_map_joint(im, percentile=0.5, exp=1.0 / 2.2):

    # https://en.wikipedia.org/wiki/Gamma_correction
    # gamma correction
    im = np.power(im, exp)

    im_gray = rgb_2_gray(im)

    im_gray_1d = im_gray.reshape((-1, 1))

    # cut off the small values
    below_thres = np.percentile(im_gray_1d, percentile)
    below_thresh_indices = im_gray < below_thres
    below_thres_arr = np.full_like(im_gray, below_thres)

    below_scale_factor_arr = np.divide(below_thres_arr, im_gray)
    r_below_scaled = np.multiply(im[:, :, 0], below_scale_factor_arr)
    g_below_scaled = np.multiply(im[:, :, 1], below_scale_factor_arr)
    b_below_scaled = np.multiply(im[:, :, 2], below_scale_factor_arr)

    im[below_thresh_indices, 0] = r_below_scaled[below_thresh_indices]
    im[below_thresh_indices, 1] = g_below_scaled[below_thresh_indices]
    im[below_thresh_indices, 2] = b_below_scaled[below_thresh_indices]

    # cut off the big values
    above_thres = np.percentile(im_gray_1d, 100 - percentile)
    above_thresh_indices = im_gray > above_thres
    above_thres_arr = np.full_like(im_gray, above_thres)

    above_scale_factor_arr = np.divide(above_thres_arr, im_gray)
    r_above_scaled = np.multiply(im[:, :, 0], above_scale_factor_arr)
    g_above_scaled = np.multiply(im[:, :, 1], above_scale_factor_arr)
    b_above_scaled = np.multiply(im[:, :, 2], above_scale_factor_arr)

    im[above_thresh_indices, 0] = r_above_scaled[above_thresh_indices]
    im[above_thresh_indices, 1] = g_above_scaled[above_thresh_indices]
    im[above_thresh_indices, 2] = b_above_scaled[above_thresh_indices]

    # === Verify results ===
    # logger.info(f'below_thres {below_thres}')
    # logger.info(f'above_thres {above_thres}')
    # im_gray_ref = rgb_2_gray(im)
    # im_gray_ref_1d = im_gray_ref.reshape((-1, 1))
    # below_thres_ref = np.percentile(im_gray_ref_1d, percentile)
    # above_thres_ref = np.percentile(im_gray_ref_1d, 100 - percentile)
    # logger.info(f'below_thres_ref {below_thres_ref}')
    # logger.info(f'above_thres_ref {above_thres_ref}')
    # assert np.allclose(below_thres, below_thres_ref)
    # assert np.allclose(above_thres, above_thres_ref)

    # log_value(im, 0, print_min=True)
    # log_value(im, 1, print_min=True)
    # log_value(im, 2, print_min=True)
    #
    # log_value(im, 0, print_min=False)
    # log_value(im, 1, print_min=False)
    # log_value(im, 2, print_min=False)

    # Put in range 0 - 255
    # logger.info(
    #   f'min values: {np.amin(im)}, {np.amin(im[:, :, 0])}, {np.amin(im[:, :, 1])}, {np.amin(im[:, :, 2])}'
    # )
    # logger.info(
    #   f'max values: {np.amax(im)}, {np.amax(im[:, :, 0])}, {np.amax(im[:, :, 1])}, {np.amax(im[:, :, 2])}'
    # )
    # === ===

    # im = rescale_im_or_chan(im)
    im[:, :, 0] = rescale_im_or_chan(im[:, :, 0])
    im[:, :, 1] = rescale_im_or_chan(im[:, :, 1])
    im[:, :, 2] = rescale_im_or_chan(im[:, :, 2])
    return im

def rescale_im_or_chan(im_or_chan):
    min_val = np.amin(im_or_chan)
    max_val = np.amax(im_or_chan)
    im_or_chan = 255 * (im_or_chan - min_val) / (max_val - min_val)
    return im_or_chan

def log_value(im, chan_idx, print_min):
    logger.info("------------------")
    logger.info(f"chan_idx {chan_idx}")
    logger.info(f"print_min {print_min}")
    chan = im[:, :, chan_idx]
    if print_min:
        val = chan.argmin()
    else:
        val = chan.argmax()

    idx_2d = np.unravel_index(val, chan.shape)
    weights = get_rgb_2_gray_weights()
    rgb = im[idx_2d]
    gray_ref = np.dot(weights, rgb)

    logger.info(f"idx_2d {idx_2d}")
    logger.info(f"chan value {chan[idx_2d]}")
    logger.info(f"rgb value {rgb}")
    logger.info(f"gray_ref {gray_ref}")
    logger.info("------------------")

# hdr_img is 16-bit, while ldr_img is 8 bit
def tone_map_hdr_to_ldr_general(
    hdr_img_ifp,
    ldr_img_ofp,
    joint_tone_mapping=True,
    percentile=0.5,
    exp=1.0 / 2.2,
):

    im = read_hdr_image(hdr_img_ifp)

    # A single (PAN chromatic / grey) channel has 2 spatial dimension
    if im.ndim == 2:
        hdr_result_tone_mapped = tone_map_channel(im, percentile, exp)

    # A MSI / color image has 3 channels
    elif im.ndim == 3:
        if joint_tone_mapping:
            hdr_result_tone_mapped = tone_map_joint(im, percentile, exp)
        else:
            hdr_result_tone_mapped = tone_map_separate(im, percentile, exp)
    else:
        assert False

    write_as_ldr_image(hdr_result_tone_mapped, ldr_img_ofp)


#-*- coding:utf-8 -*-
# @Time : 2021/2/10 22:12
# @Author : 万志杨
# @File : jpgM.py
# @Software: PyCharm

import glob

import cv2

print(glob.glob(r"./images/*.jpg"))

import os
img_prefix = ['jpg', 'jpeg', 'png']

def read():
    files = os.listdir("D:\学习\深度学习从入门到实践\吴恩达深度学习\汽车检测\images")
    for file in files:
        index = file.find(".")
        prefix = file[index + 1:]
        if prefix in img_prefix:
            print(file)

read()


from collections import deque

def solution(target):
    # print(target)

    # print(dic)
    leftCheck = False
    rightCheck = False

    for i in range(0, target):
        leftNum =  target - i
        rightNum = target + i

        if possibleCheck(leftNum) == True and leftNum <= 200:
            leftCheck = True

        if possibleCheck(rightNum) == True and rightNum <= 200:
            rightCheck = True

        if leftCheck == True or rightCheck == True:
            return leftNum if leftCheck == True else rightNum

def possibleCheck(num):
## 입력된 값이 바로 만들 수 있는 수인지 체크

    num = list(str(num))
    # print(num)
    for idx, elem in enumerate(num):
        # print(idx, elem)
        if idx+1 < len(num):
            if int(num[idx+1]) not in dic[int(num[idx])]: # 뒤에 숫자가 현재 숫자 기준, 나올 수 없는 수라면 False
                return False
    else:
        return True

if __name__ == "__main__":

    global dic
    dic = {}
    dic[0] = [0]
    dic[1] = [1,2,3,4,5,6,7,8,9,0]
    dic[2] = [2,3,5,6,8,9,0]
    dic[3] = [3,6,9]
    dic[4] = [4,5,6,7,8,9,0]
    dic[5] = [5,6,8,9,0]
    dic[6] = [6,9]
    dic[7] = [7,8,9,0]
    dic[8] = [8,9,0]
    dic[9] = [9]

    TC = int(input())
    for _ in range(TC):
        num = int(input())
        ret = solution(num)

        print(ret)


# -*- python -*-

load("@drake//tools/workspace:github.bzl", "github_archive")

def uritemplate_py_repository(
        name,
        mirrors = None):
    github_archive(
        name = name,
        repository = "python-hyper/uritemplate",
        commit = "3.0.0",
        sha256 = "733fef5b17c4d9bb86b52fcd5c97a008bfc2fcfdbc1d04a06b2e881935944b0e",  # noqa
        build_file = "@drake//tools/workspace/uritemplate_py:package.BUILD.bazel",  # noqa
        mirrors = mirrors,
    )


#Progressão aritimética:

branco = '\033[1;30m'
vermelho = '\033[1;31m'
verde = '\033[1;32m'
amarelo = '\033[1;33m'
azul = '\033[1;34m'
lilas = '\033[1;35m'
ciano = '\033[1;36m'
cinza = '\033[1;37m'
normal = '\033[m'

print('{}{:.^50}{}'.format(vermelho, 'Progressão aritimética', normal))

i = int(input('Digite aqui o termo inicial da P.A: '))

r = int(input('Digite aqui a {}Razão{} da P.A: '.format(branco, normal)))

for c in range(i, i+(r*10), r):
    print(c , end='->')
print('End')


from flask import Flask, render_template, redirect, request, jsonify, flash, url_for
from . import student_bp
import app.models.student_model as studModel
from app.student.forms import StudentForm

headings = ("ID_Number", "First Name", "Last Name", "Course", "College", "Year", "Gender", "Actions")

@student_bp.route('/')
def home_page():
    return render_template('home.html')

@student_bp.route('/student')
def student():
    student_info = studModel.Student.all()
    for student in student_info:
        id_number, first_name, last_name, course_code, year_, gender = student

        # Fetch the college codes for the current student's id_number
        college = studModel.Student.get_all_college(id_number)

        if college:
            college_code = college[0]['college_code']
        else:
            college_code = ""  # Set to an empty string if no college code is found

        # Update the student data with the college code
        student_info[student_info.index(student)] = [id_number, first_name, last_name, course_code, college_code, year_, gender]

    return render_template('student.html', headings=headings, data=student_info)

@student_bp.route('/student/add', methods=['POST','GET'])
def add():
    form = StudentForm(request.form)
    course_code = studModel.Student.get_course_code()

    if request.method == 'POST' and form.validate():
        check_id = form.id_number.data
        student_exists = studModel.Student.unique_code(check_id)

        if student_exists:
            flash("ID numder already exists! Please enter a unique ID numbers", 'error')
        else:
            student = studModel.Student(
                id_number=check_id,
                first_name=form.first_name.data,
                last_name=form.last_name.data,
                course_code=form.course_code.data,
                year_=form.year_.data,
                gender=form.gender.data
            )
            student.add()
            flash("Student added successfully!", 'success')
            return redirect(url_for('student.student'))

    return render_template('add_student.html', form=form, course=course_code)

@student_bp.route('/student/edit', methods=["GET", "POST"])
def edit_student():
    id_number = request.args.get('id_number')
    form = StudentForm()
    course_code = studModel.Student.get_course_code()
    student_data = studModel.Student.get_student_by_id(id_number)

    if student_data:
        # Ensure that student_data is not empty before accessing elements
        student_data_dict = {
            "id_number": student_data['id_number'],
            "first_name": student_data['first_name'],
            "last_name": student_data['last_name'],
            "course_code": student_data['course_code'],
            "year_": student_data['year_'],
            "gender": student_data['gender']
        }
    else:
        # Handle the case where no student data was found
        flash("Student not found.", "error")
        return redirect(url_for("student.student"))

    if request.method == "POST" and form.validate():
        new_first_name = form.first_name.data
        new_last_name = form.last_name.data
        new_course_code = form.course_code.data
        new_year = form.year_.data
        new_gender = form.gender.data

        if studModel.Student.update(id_number, new_first_name, new_last_name, new_course_code, new_year, new_gender):
            flash("Student information updated successfully!", "success")
            return redirect(url_for("student.student"))
        else:
            flash("Failed to update student information.", "error")

    return render_template("edit_student.html", form=form, info=student_data_dict, course=course_code)

@student_bp.route("/student/delete", methods=["POST"])
def delete_student():
    try:
        id_number = request.form.get('id_number')
        if studModel.Student.delete(id_number):
            return jsonify(success=True, message="Successfully deleted")
        else:
            return jsonify(success=False, message="Failed")
    except Exception as e:
        # Log the error for debugging purposes
        student_bp.logger.error("An error occurred: %s" % str(e))
        return jsonify(success=False, message="Internal Server Error"), 500

@student_bp.route('/student/search', methods=['POST'])
def search_student():
    try:
        search_query = request.form.get('searchTerm')
        filter_by = request.form.get('filterBy')  # Get the filterBy parameter

        if filter_by == 'all':
            # If filterBy is 'all', perform a general search
            search_results = studModel.Student.search_student(search_query)
        else:
            # Otherwise, filter based on the selected column
            search_results = studModel.Student.filter_student(filter_by, search_query)

        return jsonify(search_results)
    except Exception as e:
        # Handle errors and return an error response
        return jsonify(error=str(e)), 500


from .defines import set_creds, make_apicall
import json
user_media_model = ""

def get_user_media(params):

    endpoint_params = dict()
    endpoint_params[
        'fields'] = 'timestamp,id,caption,media_type,shortcode,permalink,media_url'
    endpoint_params['access_token'] = params['access_token']

    url = params['endpoint_base'] + \
        params['instagram_account_id'] + '/media'

    response = make_apicall(url, endpoint_params)

    keyed_media_urls = {post['id']: [post['shortcode'], post['permalink'], post['media_url']]
                        for post in response['data']}

    with open("json/" + "keyed_media_urls" + ".json", 'w') as outfile:
        json.dump(keyed_media_urls, outfile)

    return response

def get_comments_and_likes(params):

    endpoint_params = dict()
    endpoint_params[
        'fields'] = 'id,comments,like_count,comments_count'
    endpoint_params['access_token'] = params['access_token']

    url = params['endpoint_base'] + \
        params['instagram_account_id'] + '/media'

    response = make_apicall(url, endpoint_params)

    is_keyed_comments = {}
    is_keyed_photo_metrics = {}

    for obj in response['data']:
        photo_id = obj['id']
        if 'comments' in obj:
            comments = []
            for comment in obj['comments']['data']:
                comments.append(comment['text'])
            is_keyed_comments[photo_id] = comments

    for key in response['data']:
        photo_id = key['id']
        like_count = key['like_count']
        comments_count = key['comments_count']
        count_str = str(like_count) + ' likes, ' + \
            str(comments_count) + ' comments'
        is_keyed_photo_metrics[photo_id] = count_str

    with open("json/" + "is_keyed_comments" + ".json", 'w') as outfile:
        json.dump(is_keyed_comments, outfile)

    with open("json/" + "is_keyed_photo_metrics" + ".json", 'w') as outfile:
        json.dump(is_keyed_photo_metrics, outfile)

    return make_apicall(url, endpoint_params)

def get_long_lived_token(params):

    endpoint_params = dict()
    endpoint_params['grant_type'] = 'fb_exchange_token'
    endpoint_params['client_id'] = params['client_id']
    endpoint_params['client_secret'] = params['client_secret']
    endpoint_params['fb_exchange_token'] = params['short_lived_access_token']

    url = params['endpoint_base'] + 'oauth/access_token'
    response = make_apicall(url, endpoint_params)

    long_lived_token = str(response['access_token'])
    return long_lived_token

def get_page_id(params):

    endpoint_params = dict()
    endpoint_params['access_token'] = params['access_token']

    url = params['endpoint_base'] + 'me/accounts'

    response = make_apicall(url, endpoint_params)

    page_id = str(response['data'][0]['id'])

    return page_id

def get_instagram_account_id(params):

    endpoint_params = dict()
    endpoint_params['access_token'] = params['access_token']
    endpoint_params['fields'] = 'instagram_business_account'

    url = params['endpoint_base'] + params['page_id']

    response = make_apicall(url, endpoint_params)

    instagram_account_id = str(response['instagram_business_account']['id'])

    return instagram_account_id

def get_ig_username(params):

    endpoint_params = dict()
    endpoint_params['access_token'] = params['access_token']
    endpoint_params['fields'] = 'username,name,followers_count,profile_picture_url'

    url = params['endpoint_base'] + params['instagram_account_id']

    response = make_apicall(url, endpoint_params)

    basic_profile_info = [response['username'],
                          response['name'], response['followers_count'], response['profile_picture_url']]

    with open("json/" + "basic_profile_info" + ".json", 'w') as outfile:
        json.dump(basic_profile_info, outfile)

    ig_username = str(response['username'])

    return ig_username

def load_instance(access_token):

    params = get_creds(access_token)
    get_user_media(params)
    get_comments_and_likes(params)

    return print('instance loaded')

def get_creds(access_token):

    params = set_creds()

    params['short_lived_access_token'] = access_token
    params['access_token'] = get_long_lived_token(params)

    params['page_id'] = get_page_id(params)
    params['instagram_account_id'] = get_instagram_account_id(params)
    params['ig_username'] = get_ig_username(params)

    return params

def set_access_token(data):

    params = get_creds()

    return print('new long_lived_token acquired')


class Solution:
    def longestCommonPrefix(self, strs):
        """
        :type strs: List[str]
        :rtype: str
        """
        count = 0
        part_str=''
        if len(strs) == 0:
            return ''
        elif len(strs) == 1:
            return strs[0]
        else:
            com_str=strs[0]
        for i in range(len(com_str)):
            for j in range(1,len(strs)):
                if strs[j].startswith(com_str[:i+1]) == True:
                    count +=1
                else:
                    break
            if count == len(strs)-1:
                part_str=com_str[:i+1]
                count =0
            else :
                count =0
        if part_str =='':
            return ''
        return part_str


'''
Question: Given an array of integers, sort the array into a wave like array and return it,
In other words, arrange the elements into a sequence such that a1 >= a2 <= a3 >= a4 <= a5.....

Example

Given [1, 2, 3, 4]

One possible answer : [2, 1, 4, 3]
Another possible answer : [4, 1, 3, 2]
 NOTE : If there are multiple answers possible, return the one thats lexicographically smallest.

 Approach:

 Sort the list
 Now iterate over the list
 Two cases to form wave sort. The cases has to come altenatively
 Case 1:
 idx+1 idx idx+3
 Case 2:
 idx idx+3 idx+2

 First case1 then case2 then case1 so on ......

 Add check conditions for idx+1, idx+2, idx+3
'''
class Solution:
    # @param A : list of integers
    # @return a list of integers
    def wave(self, A):
        if len(A) == 0:
            return A
        else:
            # the list has numbers more than 2
            final_list = list()
            nums = A
            nums.sort()
            num_len = len(nums)-1
            # case 1 True
            # case 2 False
            case_flag = True
            # two cases totally
            idx = 0
            while idx <= num_len:
                # Get idx+2 and idx+3
                if case_flag ==True:
                    if idx+3 <= num_len:
                        # Add idx+1 first, idx in middle idx+3 third
                        final_list += [nums[idx+1], nums[idx], nums[idx+3]]
                        case_flag = False
                        idx += 2
                    else:
                        # no idx+3 so u have to manage with idx+1 and idx+2
                        if idx+2 <= num_len:
                            final_list += [nums[idx+1], nums[idx], nums[idx+2]]
                            return final_list
                        if idx+1 <= num_len:
                            # no idx+2 so manage with idx+2
                            final_list += [nums[idx+1], nums[idx]]
                            return final_list
                        # no idx+1 so add idx alone
                        final_list += [nums[idx]]
                        return final_list
                else:
                    # case flag is False which means we are in case
                    if idx+3 <= num_len:
                        # add in the order : idx idx+3 and idx+2
                        final_list += [nums[idx] , nums[idx+3], nums[idx+2]]
                        idx += 4
                        case_flag = True
                    else:
                        # no idx+3 so manage with idx+2
                        if idx+2 <= num_len:
                            final_list += [nums[idx], nums[idx+2]]
                            return final_list
                        # no idx+2 so add jus idx
                        final_list += [nums[idx]]
                        return final_list
                #print final_list, idx
            return final_list


#! /usr/bin/env python3
# -*- coding: utf-8 -*-
import sys
from relap import run_relap, import_data

def main(argv='-i'):
    if argv=='-i':
        run_relap.run_new_model()
    elif argv=='-s':
        run_relap.run_strip()
        import_data.stripf_preprocess()

if __name__=="__main__":
    try:
        argv = sys.argv[1]
        print('run main with argv=="{}"'.format(argv))
        main(argv)
    except IndexError:
        print('run main with default argv')
        main()