import hashlib
import json
import os
import pathlib
import shutil
import subprocess
from typing import Mapping, Any, List

class RunException(Exception):
    pass

class ExecuteException(Exception):
    pass

class style:
    reset = 0
    bold = 1
    dim = 2
    italic = 3
    underline = 4
    blink = 5
    rblink = 6
    reversed = 7
    conceal = 8
    crossed = 9

class fg:
    black = 30
    red = 31
    green = 32
    yellow = 33
    blue = 34
    magenta = 35
    cyan = 36
    gray = 37
    reset = 39

def color(value):
    return "\033[" + str(int(value)) + "m";

def print_check():
    print("%s✓ %s" % (color(fg.green)+color(style.bold),
        color(fg.reset)+color(style.reset)))

def bname(base, cmd, filename):
    hstring = cmd
    if filename:
        hstring += filename
    h = hashlib.sha224(hstring.encode()).hexdigest()[:7]
    if filename:
        bname = os.path.basename(filename)
        bname, _ = os.path.splitext(bname)
        return "%s-%s-%s" % (base, bname, h)
    else:
        return "%s-%s" % (base, h)

def _compare_eq_dict(
    left: Mapping[Any, Any], right: Mapping[Any, Any], verbose: int = 0
) -> List[str]:
    explanation = []  # type: List[str]
    set_left = set(left)
    set_right = set(right)
    common = set_left.intersection(set_right)
    same = {k: left[k] for k in common if left[k] == right[k]}
    if same and verbose < 2:
        explanation += ["Omitting %s identical items" % len(same)]
    elif same:
        explanation += ["Common items:"]
        explanation += pprint.pformat(same).splitlines()
    diff = {k for k in common if left[k] != right[k]}
    if diff:
        explanation += ["Differing items:"]
        for k in diff:
            explanation += [repr({k: left[k]}) + " != " + repr({k: right[k]})]
    extra_left = set_left - set_right
    len_extra_left = len(extra_left)
    if len_extra_left:
        explanation.append(
            "Left contains %d more item%s:"
            % (len_extra_left, "" if len_extra_left == 1 else "s")
        )
        explanation.extend(
            pprint.pformat({k: left[k] for k in extra_left}).splitlines()
        )
    extra_right = set_right - set_left
    len_extra_right = len(extra_right)
    if len_extra_right:
        explanation.append(
            "Right contains %d more item%s:"
            % (len_extra_right, "" if len_extra_right == 1 else "s")
        )
        explanation.extend(
            pprint.pformat({k: right[k] for k in extra_right}).splitlines()
        )
    return explanation

def fixdir(s):
    local_dir = os.getcwd()
    return s.replace(local_dir.encode(), "$DIR".encode())

def run(basename, cmd, out_dir, infile=None, extra_args=None):
    """
    Runs the `cmd` and collects stdout, stderr, exit code.

    The stdout, stderr and outfile are saved in the `out_dir` directory and
    all metadata is saved in a json file, whose path is returned from the
    function.

    The idea is to use this function to test the compiler by running it with
    an option to save the AST, ASR or LLVM IR or binary, and then ensure that
    the output does not change.

    Arguments:

    basename ... name of the run
    cmd ........ command to run, can use {infile} and {outfile}
    out_dir .... output directory to store output
    infile ..... optional input file. If present, it will check that it exists
                 and hash it.
    extra_args . extra arguments, not part of the hash

    Examples:

    >>> run("cat2", "cat tests/cat.txt > {outfile}", "output", "tests/cat.txt")
    >>> run("ls4", "ls --wrong-option", "output")

    """
    assert basename is not None and basename != ""
    pathlib.Path(out_dir).mkdir(parents=True, exist_ok=True)
    if infile and not os.path.exists(infile):
        raise RunException("The input file does not exist")
    outfile = os.path.join(out_dir, basename + "." + "out")
    cmd2 = cmd.format(infile=infile, outfile=outfile)
    if extra_args:
        cmd2 += " " + extra_args
    r = subprocess.run(cmd2, shell=True,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE)
    if not os.path.exists(outfile):
        outfile = None
    if len(r.stdout):
        stdout_file = os.path.join(out_dir, basename + "." + "stdout")
        open(stdout_file, "wb").write(fixdir(r.stdout))
    else:
        stdout_file = None
    if len(r.stderr):
        stderr_file = os.path.join(out_dir, basename + "." + "stderr")
        open(stderr_file, "wb").write(fixdir(r.stderr))
    else:
        stderr_file = None

    if infile:
        infile_hash = hashlib.sha224(open(infile, "rb").read()).hexdigest()
    else:
        infile_hash = None
    if outfile:
        outfile_hash = hashlib.sha224(open(outfile, "rb").read()).hexdigest()
        outfile = os.path.basename(outfile)
    else:
        outfile_hash = None
    if stdout_file:
        stdout_hash = hashlib.sha224(open(stdout_file, "rb").read()).hexdigest()
        stdout_file = os.path.basename(stdout_file)
    else:
        stdout_hash = None
    if stderr_file:
        stderr_hash = hashlib.sha224(open(stderr_file, "rb").read()).hexdigest()
        stderr_file = os.path.basename(stderr_file)
    else:
        stderr_hash = None
    data = {
        "basename": basename,
        "cmd": cmd,
        "infile": infile,
        "infile_hash": infile_hash,
        "outfile": outfile,
        "outfile_hash": outfile_hash,
        "stdout": stdout_file,
        "stdout_hash": stdout_hash,
        "stderr": stderr_file,
        "stderr_hash": stderr_hash,
        "returncode": r.returncode,
    }
    json_file = os.path.join(out_dir, basename + "." + "json")
    json.dump(data, open(json_file, "w"), indent=4)
    return json_file

def run_test(basename, cmd, infile=None, update_reference=False,
        extra_args=None):
    """
    Runs the test `cmd` and compare against reference results.

    The `cmd` is executed via `run` (passing in `basename` and `infile`) and
    the output is saved in the `output` directory. The generated json file is
    then compared against reference results and if it differs, the
    RunException is thrown.

    Arguments:

    basename ........... name of the run
    cmd ................ command to run, can use {infile} and {outfile}
    infile ............. optional input file. If present, it will check that
                         it exists and hash it.
    update_reference ... if True, it will copy the output into the reference
                         directory as reference results, overwriting old ones
    extra_args ......... Extra arguments to append to the command that are not
                         part of the hash

    Examples:

    >>> run_test("cat12", "cat {infile} > {outfile}", "cat.txt",
    ...     update_reference=True)
    >>> run_test("cat12", "cat {infile} > {outfile}", "cat.txt")
    """
    s = "    * %-6s " % basename
    print(s, end="")
    basename = bname(basename, cmd, infile)
    if infile:
        infile = os.path.join("tests", infile)
    jo = run(basename, cmd, os.path.join("tests", "output"), infile=infile,
            extra_args=extra_args)
    jr = os.path.join("tests", "reference", os.path.basename(jo))
    do = json.load(open(jo))
    if update_reference:
        shutil.copyfile(jo, jr)
        for f in ["outfile", "stdout", "stderr"]:
            if do[f]:
                f_o = os.path.join(os.path.dirname(jo), do[f])
                f_r = os.path.join(os.path.dirname(jr), do[f])
                shutil.copyfile(f_o, f_r)
        return
    if not os.path.exists(jr):
        raise RunException("The reference json file '%s' does not exist" % jr)
    dr = json.load(open(jr))
    if do != dr:
        e = _compare_eq_dict(do, dr)
        print("The JSON metadata differs against reference results")
        print("Reference JSON:", jr)
        print("Output JSON:   ", jo)
        print("\n".join(e))
        if do["outfile_hash"] != dr["outfile_hash"]:
            if do["outfile_hash"] is not None and dr["outfile_hash"] is not None:
                fo = os.path.join("tests", "output", do["outfile"])
                fr = os.path.join("tests", "reference", dr["outfile"])
                if os.path.exists(fr):
                    print("Diff against: %s" % fr)
                    os.system("diff %s %s" % (fr, fo))
                else:
                    print("Reference file '%s' does not exist" % fr)
        if do["stdout_hash"] != dr["stdout_hash"]:
            if do["stdout_hash"] is not None and dr["stdout_hash"] is not None:
                fo = os.path.join("tests", "output", do["stdout"])
                fr = os.path.join("tests", "reference", dr["stdout"])
                if os.path.exists(fr):
                    print("Diff against: %s" % fr)
                    os.system("diff %s %s" % (fr, fo))
                else:
                    print("Reference file '%s' does not exist" % fr)
        if do["stderr_hash"] != dr["stderr_hash"]:
            if do["stderr_hash"] is not None and dr["stderr_hash"] is not None:
                fo = os.path.join("tests", "output", do["stderr"])
                fr = os.path.join("tests", "reference", dr["stderr"])
                if os.path.exists(fr):
                    print("Diff against: %s" % fr)
                    os.system("diff %s %s" % (fr, fo))
                else:
                    print("Reference file '%s' does not exist" % fr)
            elif do["stderr_hash"] is not None and dr["stderr_hash"] is None:
                fo = os.path.join("tests", "output", do["stderr"])
                print("No reference stderr output exists. Stderr:")
                os.system("cat %s" % fo)
        raise RunException("The reference result differs")
    print_check()


def solution(s):
    answer = [0,0]

    while s != '1':
        cnt = s.count('0')
        tranS = s.replace('0','')
        s = bin(len(tranS))
        s = s[2:]
        answer[0] += 1
        answer[1] += cnt

    return answer

s = "1111111"
print(solution(s))


from sklearn.base import BaseEstimator, ClusterMixin, TransformerMixin
from sklearn.cluster import DBSCAN, KMeans, SpectralClustering
from sklearn.neighbors import KNeighborsClassifier
from sklearn.preprocessing import LabelBinarizer

class ClusterTransformer(TransformerMixin, BaseEstimator):
    """Turns sklearn clustering algorithm into a transformer component that
    you can use in a pipeline.
    If the clustering method cannot be used for prediction
    (aka. it does not have a predict method), then a nearest neighbour
    vot will be used to infer cluster labels for unseen samples.

    Parameters
    ----------
    model: ClusterMixin
        Sklearn clustering model.
    n_neighbors: int
        Number of neighbours to use for inference.
    metric: str
        Metric to use for determining nearest neighbours.

    Attributes
    ----------
    labeler: LabelBinarizer
        Component that turns cluster labels into one-hot embeddings.
    neighbors: KNeighborsClassifier
        Classifier to use for out of sample prediction.
    """

    def __init__(
        self, model: ClusterMixin, n_neighbors: int = 5, metric: str = "cosine"
    ):
        self.model = model
        self.labeler = LabelBinarizer()
        self.neighbors = KNeighborsClassifier(
            n_neighbors=n_neighbors, metric=metric
        )

    def fit(self, X, y=None):
        """Fits the clustering algorithm and label binarizer.

        Parameters
        ----------
        X: ndarray of shape (n_observations, n_features)
            Observations to cluster.
        y: None
            Ignored, exists for compatiblity.

        Returns
        -------
        self
        """
        labels = self.model.fit_predict(X)
        if not hasattr(self.model, "predict"):
            self.neighbors.fit(X, labels)
        self.labeler.fit(labels)
        return self

    def transform(self, X):
        """Infers cluster labels for given data points.

        Parameters
        ----------
        X: ndarray of shape (n_observations, n_features)
            Observations to cluster.

        Returns
        -------
        ndarray of shape (n_observations, n_clusters)
            One-hot encoding of cluster labels.
        """
        if hasattr(self.model, "predict"):
            labels = self.model.predict(X)
        else:
            labels = self.neighbors.predict(X)
        return self.labeler.transform(labels)

    def get_feature_names_out(self):
        """Returns the cluster classes for each dimension.

        Returns
        -------
        ndarray of shape (n_clusters)
            Cluster names.
        """
        return self.labeler.classes_

def DBSCANTransformer(
    eps: float = 0.5, min_samples: int = 5, metric: str = "cosine"
) -> ClusterTransformer:
    """Convenience function for creating a DBSCAN transformer.

    Parameters
    ----------
    eps : float, default 0.5
        The maximum distance between two samples for one to be considered
        as in the neighborhood of the other. This is not a maximum bound
        on the distances of points within a cluster. This is the most
        important DBSCAN parameter to choose appropriately for your data set
        and distance function.

    min_samples : int, default 5
        The number of samples (or total weight) in a neighborhood for a point
        to be considered as a core point. This includes the point itself.

    metric : str, default 'cosine'
        The metric to use when calculating distance between instances in a
        feature array.

    Returns
    -------
    ClusterTransformer
        Sklearn transformer component that wraps DBSCAN.
    """
    model = DBSCAN(eps=eps, min_samples=min_samples, metric=metric)
    return ClusterTransformer(model, metric="cosine")

def KMeansTransformer(n_clusters: int) -> ClusterTransformer:
    """Convenience function for creating a KMeans transformer.

    Parameters
    ----------
    n_clusters: int
        Number of clusters.

    Returns
    -------
    ClusterTransformer
        Sklearn transformer component that wraps KMeans.
    """
    model = KMeans(n_clusters=n_clusters)
    return ClusterTransformer(model, metric="cosine")

def SpectralClusteringTransformer(n_clusters: int) -> ClusterTransformer:
    """Convenience function for creating a Spectral Clustering transformer.

    Parameters
    ----------
    n_clusters: int
        Number of clusters.

    Returns
    -------
    ClusterTransformer
        Sklearn transformer component that wraps SpectralClustering.
    """
    model = SpectralClustering(n_clusters=n_clusters)
    return ClusterTransformer(model, metric="cosine")


import abc
import collections
from typing import List, Callable, Optional, OrderedDict, Tuple

import pandas as pd

class PreProcessingBase:
    def __init__(self,
                 df: pd.DataFrame,
                 actions: Optional[OrderedDict[Callable, Tuple]] = None):
        self._df = df
        self._actions = actions
        if self._actions is None:
            self._actions = collections.OrderedDict()

    @abc.abstractmethod
    def _get_actions(self) -> OrderedDict[Callable, Tuple]:
        raise NotImplementedError

    def setup(self):
        self._actions = self._get_actions()
        return self

    def run(self) -> pd.DataFrame:
        for action, args in self._actions.items():
            self._df = self._df.apply(action, args=args)

        return self._df


import time
import math
n=int(input())
start = time.time()
def prime_testimony(n):
    if n == 1:
        return False
    elif n==2 or n==3 :
        return True
    elif n%6 == 1 or n%6 == 5:
        for i in range(3, math.floor(math.sqrt(n)) + 1, 2):
            if n%i == 0:
                return False
        return True
    else:
        return False

print(prime_testimony(n))
print(time.time() - start)


import pandas as pd
import random
from tqdm.auto import tqdm
tqdm.pandas()
import re
from tqdm import tqdm
import numpy as np
import cv2
from albumentations import (
    Compose, OneOf, Normalize, Resize, HorizontalFlip, VerticalFlip, Rotate, RandomRotate90, CenterCrop
    )
from albumentations.pytorch import ToTensorV2
from InChI_extra_image_gen import add_noise

def split_form(text):
    PATTERN = re.compile('\d+|[A-Z][a-z]?|[^A-Za-z\d\/]|\/[a-z]')
    return ' '.join(re.findall(PATTERN, text))

def get_atom_counts(df):
    TARGETS = [
    'B', 'Br', 'C', 'Cl',
    'F', 'H', 'I', 'N',
    'O', 'P', 'S', 'Si']
    formula_regex = re.compile(r'[A-Z][a-z]?[0-9]*')
    element_regex = re.compile(r'[A-Z][a-z]?')
    number_regex = re.compile(r'[0-9]*')

    atom_dict_list = []
    for i in tqdm(df['Formula'].values):
        atom_dict = dict()
        for j in formula_regex.findall(i):
            atom = number_regex.sub("", j)
            dgts = element_regex.sub("", j)
            atom_cnt = int(dgts) if len(dgts) > 0 else 1
            atom_dict[atom] = atom_cnt
        atom_dict_list.append(atom_dict)

    atom_df = pd.DataFrame(atom_dict_list).fillna(0).astype(int)
    atom_df = atom_df.sort_index(axis = 1)
    for atom in TARGETS:
        df[atom] = atom_df[atom]
    return df

def train_file_path(image_id):
    #pay attention to the directory before /train, need to change accordingly.
    return "./bms-molecular-translation/train/{}/{}/{}/{}.png".format(
        image_id[0], image_id[1], image_id[2], image_id
    )

#Two ways to treat the input images. 1.crop and pad to fit the images' size to be constant. 2.resize images to certain w and h. Here is the crop function.
def crop_image(img,
               contour_min_pixel = 2,
               small_stuff_size  = 2,
               small_stuff_dist  = 5,
               pad_pixels       = 5):

    # idea: pad with contour_min_pixels just in case we cut off
    #       a small part of the structure that is separated by a missing pixel

    #findContours only find white obj in black background color.
    img = 255 - img

    #Make all pixels except pure background, i.e. pure black, white and distinguish them using method BINARY and OTSU in order to not missing any obj. OTSU plus BINARY basically make the obj more distinguishable compared with just BINARY.
    _, thresh   = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)

    #RETR_LIST lists all the contours without hierarchy of nested contours. CHAIN_APPROX_SIMPLE returns only the key pixels that form the contour, e.g., 4 points for a rectangle contour.
    contours, _ = cv2.findContours(thresh, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)[-2:]

    #Store the small contours.
    small_stuff = []

    x_min0, y_min0, x_max0, y_max0 = np.inf, np.inf, 0, 0
    for i in contours:
        if len(i) < contour_min_pixel:  # if NO. of pixels is too small, ignore contours under contour_min_size pixels
            continue
        #x,y are the top-left coordinate of the rectangle and w, h are contour's width and heigh
        x, y, w, h = cv2.boundingRect(i)
        if w <= small_stuff_size and h <= small_stuff_size:  # collect position of contours which are smaller than small_stuff_size.
            small_stuff.append([x, y, x+w, y+h])
            continue

        #find the largest bounding rectangle.
        x_min0 = min(x_min0, x)
        y_min0 = min(y_min0, y)
        x_max0 = max(x_max0, x + w)
        y_max0 = max(y_max0, y + h)

    x_min, y_min, x_max, y_max = x_min0, y_min0, x_max0, y_max0

    # enlarge the found crop box if it cuts out small stuff that is very close by
    for i in range(len(small_stuff)):

        #if the small stuff overlap with the big obj, count the small stuff into the obj, update the xmin max ymin max with the small stuff's.
        if small_stuff[i][0] < x_min0 and small_stuff[i][0] + small_stuff_dist >= x_min0:
             x_min = small_stuff[i][0]
        if small_stuff[i][1] < y_min0 and small_stuff[i][1] + small_stuff_dist >= y_min0:
             y_min = small_stuff[i][1]
        if small_stuff[i][2] > x_max0 and small_stuff[i][2] - small_stuff_dist <= x_max0:
             x_max = small_stuff[i][2]
        if small_stuff[i][3] > y_max0 and small_stuff[i][3] - small_stuff_dist <= y_max0:
             y_max = small_stuff[i][3]

    if pad_pixels > 0:  # make sure we get the crop within a valid range, pad_pixels is the range to ensure the crop is larger than the obj but not exceeding the canvas.
        y_min = max(0, y_min-pad_pixels)
        y_max = min(img.shape[0], y_max+pad_pixels)
        x_min = max(0, x_min-pad_pixels)
        x_max = min(img.shape[1], x_max+pad_pixels)

    img_cropped = img[y_min:y_max, x_min:x_max]

    #flip the black/white colors.
    # img_cropped = 255 - img_cropped

    return img_cropped

def pad_image(image, desired_size):
    h, w = image.shape[0], image.shape[1]
    delta_h = desired_size - h
    delta_w = desired_size - w
    top, bottom = delta_h//2, delta_h - (delta_h//2)
    left,right = delta_w//2, delta_w - (delta_w//2)
    img_padded = cv2.copyMakeBorder(image, top, bottom, left, right, cv2.BORDER_CONSTANT,
    value = [255, 255, 255])
    return img_padded

def preprocess_train_images(train_df, transform, CFG):
    #Goal of this func is to make all images the same size to fit the transformer model (crop and pad),
    #create a new column 'image' to record the original image data and the transformed image data if the trans flag is 'rotate90 or verticalflip'.
    #Here only one transformation is prepared because of the preliminary feeling that the scale of dataset is enough.
    assert set(['InChI_text', 'file_path', 'text_length']).issubset(train_df.columns), 'make sure the df has been preprocessed and certain columns are created.'

    trans_img = []
    ori_img = []
    transform_type = ['rotate90', 'verticalflip']
    df = train_df.copy()
    resize = Compose([Resize(CFG.image_size, CFG.image_size)])

    for i in tqdm(range(len(train_df))):
        img_path = train_df.loc[i, 'file_path']
        image = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE)
        if CFG.crop == True:
            image = crop_image(image,
               contour_min_pixel = 2,
               small_stuff_size  = 2,
               small_stuff_dist  = 5,
               pad_pixels       = 10)
        image = resize(image = image)['image']
        image = add_noise(image)
        #np.expand_dims is used here because the input images needs to have 3 dimensions with the last one as 1.
        #But imread(cv2.IMREAD_GRAYSCALE) can only give a 2D image.
        image = np.expand_dims(image, axis = -1)
        ori_img.append(image)
        if CFG.trans_type == 'rotate90 or verticalflip':
            trans_image = transform(transform_type[random.randint(0, 1)])(image = image)['image']
            trans_img.append(trans_image)
    df.insert(3, 'image', ori_img)
    if CFG.trans_type == 'rotate90 or verticalflip':
        train_df['image'] = trans_img
        temp = pd.concat([df, train_df]).sample(frac = 1).reset_index(drop = True)
        return temp
    else:
        return df

def get_transform(trans_type):
    #transform images, need to annotate trans flag.
    if trans_type == 'rotate90':
        return Compose([
            OneOf([
                Rotate([90, 90], p = 0.5),
                Rotate([-90, -90], p = 0.5),
            ], p = 1.0),
        ])
    elif trans_type == 'verticalflip':
        return Compose([
            OneOf([
                VerticalFlip()
            ], p = 1.0),
        ])

def get_aug(CFG):
    #the goal is to normalize the image data and convert np array to torch tensor before sending to the model
    return Compose([Normalize(mean = CFG.pixels_mean, std = CFG.pixels_std), ToTensorV2()])


import typing
from datetime import datetime, timedelta

import arrow

from ParadoxTrading.Utils.DataStruct import DataStruct

DATETIME_TYPE = typing.Union[str, datetime]

class SplitAbstract:
    def __init__(self):
        self.cur_bar: DataStruct = None
        self.cur_bar_begin_time: DATETIME_TYPE = None
        self.cur_bar_end_time: DATETIME_TYPE = None

        self.bar_list: typing.List[DataStruct] = []
        self.bar_begin_time_list: typing.List[DATETIME_TYPE] = []
        self.bar_end_time_list: typing.List[DATETIME_TYPE] = []

    def __len__(self) -> len:
        return len(self.getBarList())

    def getLastData(self) -> DataStruct:
        """
        get last

        :return:
        """
        return self.cur_bar.iloc[-1]

    def getCurBar(self) -> DataStruct:
        return self.cur_bar

    def getCurBarBeginTime(self) -> DATETIME_TYPE:
        return self.cur_bar_begin_time

    def getCurBarEndTime(self) -> DATETIME_TYPE:
        return self.cur_bar_end_time

    def getBarList(self) -> typing.List[DataStruct]:
        return self.bar_list

    def getBarBeginTimeList(self) -> typing.List[DATETIME_TYPE]:
        return self.bar_begin_time_list

    def getBarEndTimeList(self) -> typing.List[DATETIME_TYPE]:
        return self.bar_end_time_list

    def _get_begin_end_time(
            self, _cur_time: DATETIME_TYPE
    ) -> (DATETIME_TYPE, DATETIME_TYPE):
        raise NotImplementedError('You need to implement _get_begin_end_time!')

    def _create_new_bar(self, _data: DataStruct, _cur_time: DATETIME_TYPE):
        self.cur_bar = _data.clone()
        self.cur_bar_begin_time, self.cur_bar_end_time = \
            self._get_begin_end_time(_cur_time)
        self.bar_list.append(self.cur_bar)
        self.bar_begin_time_list.append(self.cur_bar_begin_time)
        self.bar_end_time_list.append(self.cur_bar_end_time)

    def addOne(self, _data: DataStruct) -> bool:
        """
        add one tick data into spliter

        Args:
            _data (DataStruct): one tick

        Returns:
            bool : whether created a new bar
        """

        assert len(_data) == 1
        cur_time = _data.index()[0]
        if self.cur_bar is None:
            self._create_new_bar(_data, cur_time)
            return True
        else:
            if cur_time < self.cur_bar_end_time:
                self.cur_bar.addDict(_data.toDict())
                return False
            else:
                self._create_new_bar(_data, cur_time)
                return True

    def addMany(self, _data: DataStruct):
        """
        add continue data into spliter

        Args:
            _data (DataStruct): continute data
        """
        for d in _data:
            self.addOne(d)

        return self

class SplitIntoSecond(SplitAbstract):
    def __init__(self, _second: int = 1):
        super().__init__()
        self.skip_s = _second

    def _get_begin_end_time(
            self, _cur_time: DATETIME_TYPE
    ) -> (DATETIME_TYPE, DATETIME_TYPE):
        base_s = _cur_time.second // self.skip_s * self.skip_s
        begin_datetime = _cur_time.replace(second=base_s, microsecond=0)
        end_datetime = begin_datetime + timedelta(seconds=self.skip_s)
        return begin_datetime, end_datetime

class SplitIntoMinute(SplitAbstract):
    def __init__(self, _minute: int = 1):
        super().__init__()
        self.skip_m = _minute

    def _get_begin_end_time(
            self, _cur_time: DATETIME_TYPE
    ) -> (DATETIME_TYPE, DATETIME_TYPE):
        base_m = _cur_time.minute // self.skip_m * self.skip_m
        begin_datetime = _cur_time.replace(
            minute=base_m, second=0, microsecond=0)
        end_datetime = begin_datetime + timedelta(minutes=self.skip_m)
        return begin_datetime, end_datetime

class SplitIntoHour(SplitAbstract):
    def __init__(self, _hour: int = 1):
        super().__init__()
        self.skip_h = _hour

    def _get_begin_end_time(
            self, _cur_time: DATETIME_TYPE
    ) -> (DATETIME_TYPE, DATETIME_TYPE):
        base_h = _cur_time.hour // self.skip_h * self.skip_h
        begin_datetime = _cur_time.replace(
            hour=base_h, minute=0, second=0, microsecond=0)
        end_datetime = begin_datetime + timedelta(hours=self.skip_h)
        return begin_datetime, end_datetime

class SplitIntoWeek(SplitAbstract):
    def _get_begin_end_time(
            self, _cur_time: DATETIME_TYPE
    ) -> (DATETIME_TYPE, DATETIME_TYPE):
        cur_date = datetime.strptime(_cur_time, '%Y%m%d')
        weekday = cur_date.weekday()
        begin_datetime: datetime = cur_date - timedelta(days=weekday)
        end_datetime: datetime = begin_datetime + timedelta(weeks=1)
        return (
            begin_datetime.strftime('%Y%m%d'),
            end_datetime.strftime('%Y%m%d')
        )

class SplitIntoMonth(SplitAbstract):
    def _get_begin_end_time(
            self, _cur_time: DATETIME_TYPE
    ) -> (DATETIME_TYPE, DATETIME_TYPE):
        cur_date = arrow.get(_cur_time, 'YYYYMMDD')
        begin_datetime = cur_date.replace(day=1)
        end_datetime = begin_datetime.shift(months=1)
        return (
            begin_datetime.format('YYYYMMDD'),
            end_datetime.format('YYYYMMDD')
        )

class SplitIntoYear(SplitAbstract):
    def _get_begin_end_time(
            self, _cur_time: DATETIME_TYPE
    ) -> (DATETIME_TYPE, DATETIME_TYPE):
        cur_date = arrow.get(_cur_time, 'YYYYMMDD')
        begin_datetime = cur_date.replace(day=1)
        end_datetime = begin_datetime.shift(years=1)
        return (
            begin_datetime.format('YYYYMMDD'),
            end_datetime.format('YYYYMMDD')
        )

class SplitVolumeBars(SplitAbstract):
    def __init__(
            self, _use_key='volume', _volume_size: int = 1,
    ):
        """

        :param _use_key: use which index to split volume
        :param _volume_size: split ticks
        """
        super().__init__()

        self.use_key = _use_key
        self.volume_size = _volume_size

        self.total_volume = 0

    def _get_begin_end_time(
            self, _cur_time: DATETIME_TYPE
    ) -> (DATETIME_TYPE, DATETIME_TYPE):
        return _cur_time, _cur_time

    def addOne(self, _data: DataStruct):
        assert len(_data) == 1
        cur_time = _data.index()[0]
        cur_volume = _data[self.use_key][0]
        if self.cur_bar is None:  # the first tick
            self._create_new_bar(_data, cur_time)
            self.total_volume = cur_volume
            return True

        if self.total_volume > self.volume_size:
            self._create_new_bar(_data, cur_time)
            self.total_volume = cur_volume
            return True

        self.cur_bar.addDict(_data.toDict())
        self.cur_bar_end_time = cur_time  # override end time
        self.bar_end_time_list[-1] = cur_time
        self.total_volume += cur_volume
        return False

class SplitTickImbalance(SplitAbstract):
    def __init__(
            self, _use_key='lastprice',
            _period=7, _init_T=1000
    ):
        """
        <Advances in Financial Machine Learning> - 2.3.2.1

        _use_key: use which index to calc bt
        _init_T: the length of first bar
        _period: period of EMA
        """
        super().__init__()

        self.use_key = _use_key
        self.last_value = None

        self.last_b = 1
        self.sum_b = 0  # sum of b
        self.num_b = 0  # total number of b

        self.T = _init_T  # len of Bar
        self.P = None  # probability of b == 1
        self.period = _period
        self.threshold = None

    def _get_begin_end_time(
            self, _cur_time: DATETIME_TYPE
    ) -> (DATETIME_TYPE, DATETIME_TYPE):
        return _cur_time, _cur_time

    def _update_b(self, _value):
        # update value, b and total_b
        if _value > self.last_value:
            self.last_b = 1
        elif _value < self.last_value:
            self.last_b = -1
        else:
            pass
        self.last_value = _value
        self.sum_b += self.last_b
        self.num_b += 1

    def _reset_b(self):
        self.sum_b = 0
        self.num_b = 0

    def _update_threshold(self):
        new_T = self.num_b
        new_P = (self.sum_b + self.num_b) / 2. / self.num_b
        self.T += (new_T - self.T) / self.period
        if self.P is None:  # init p
            self.P = new_P
        else:
            self.P += (new_P - self.P) / self.period
        self.threshold = self.T * abs(2 * self.P - 1)

    def addOne(self, _data: DataStruct) -> bool:
        # check data
        assert len(_data) == 1
        value = _data[self.use_key][0]
        cur_time = _data.index()[0]

        if self.cur_bar is None:  # init the first bar
            self.last_value = value
            self._create_new_bar(_data, cur_time)
            return True

        self._update_b(value)
        print(value, self.last_b, self.sum_b, self.num_b)

        flag = False
        if self.P is None:  # current is the first bar
            if self.num_b >= self.T:  # finish the first bar
                flag = True
        elif abs(self.sum_b) >= self.threshold:  # create new bar
            flag = True

        if flag:
            self._update_threshold()
            print(self.T, self.P, self.threshold)
            input()
            self._reset_b()
            self._create_new_bar(_data, cur_time)
            return True
        else:
            self.cur_bar.addDict(_data.toDict())
            self.cur_bar_end_time = cur_time  # override end time
            self.bar_end_time_list[-1] = cur_time
            return False


"""Testing an common Anode RGB LED"""

from time import sleep

from picozero import RGBLED

def main():
    led = RGBLED(red=2, blue=3, green=4, active_high=False)
    try:
        while True:
            led.color = 255, 0, 0
            sleep(1)
            led.color = 0, 0, 255
            sleep(1)
    finally:
        led.off()

if __name__ == "__main__":
    main()


#part-1
# file = open("day2Input.txt", "r")
# my_dict = {'X':1, 'Y':2, 'Z':3}
# score = 0
# for line in file:
#     opponent = line[0]
#     you = line[2]
#     score += my_dict[you]
#     if (opponent == 'A' and you == 'X') or (opponent == 'B' and you == 'Y') or (opponent == 'C' and you == 'Z'):
#         score+=3
#     elif (opponent == 'A' and you == 'Y') or(opponent=='B' and you=='Z')or (opponent=='C'and you=='X'):
#         score += 6
#     else:
#         score += 0
# print(score)

#part-2
file = open("day2Input.txt", "r")
dicto = {'X':1, 'Y':2,'Z':3}
my_dict = {'X':0, 'Y':3, 'Z':6}
score = 0
for line in file:
    opponent = line[0]
    you = line[2]
    score += dicto[you]
    #X means you need to lose
    if you == 'X':
        if opponent == 'A':
            you = 'Z'
        elif opponent == 'B':
            you = 'X'
        elif opponent == 'C':
            you = 'Y'
    #Y means you need to end the round in a draw
    elif you == 'Y':
        if opponent == 'A':
            you = 'X'
        elif opponent == 'B':
            you = 'Y'
        elif opponent == 'C':
            you = 'Z'

    #Z means you need to win
    else:
        if opponent == 'A':
            you='Y'
        elif opponent == 'B':
            you = 'Z'
        elif opponent == 'C':
            you = 'X'
    if (opponent == 'A' and you == 'X') or (opponent == 'B' and you == 'Y') or (opponent == 'C' and you == 'Z'):
        score += 3
    elif (opponent == 'A' and you == 'Y') or(opponent=='B' and you=='Z')or (opponent=='C'and you=='X'):
        score += 6
    else:
        score += 0
print(score)


import time
import base64
from google.cloud import pubsub_v1
from google.oauth2 import service_account

project_id = "<gcp_project_id>"
topic_name = "<topic_name>"

credentials = service_account.Credentials.from_service_account_file("<gcp_Service_account_file_path>")
print(credentials)

publisher = pubsub_v1.PublisherClient(credentials = credentials)

topic_path = publisher.topic_path(project_id, topic_name)

def callback(message_future):
    # When timeout is unspecified, the exception method waits indefinitely.
    print("1")
    if message_future.exception(timeout=30):
        print('Publishing message on {} threw an Exception {}.'.format(
            topic_name, message_future.exception()))
    else:
        print(message_future.result())

with open("15.jpg", "rb") as imageFile:
    str = base64.b64encode(imageFile.read())
#print(str)

data = "sample data"
# Data must be a bytestring
data = data.encode('utf-8')
# When you publish a message, the client returns a Future.
message_future = publisher.publish(topic_path, data=str)
message_future.add_done_callback(callback)
print(data)
print('Published message IDs:')

##############################################################################################

subscriber = pubsub_v1.SubscriberClient(credentials = credentials)
subscription_path = subscriber.subscription_path(
    project_id, "subscribe")

def callback1(message):
    print('Received message: {}'.format(message))
    message.ack()

subscriber.subscribe(subscription_path, callback=callback1)

# The subscriber is non-blocking. We must keep the main thread from
# exiting to allow it to process messages asynchronously in the background.
print('Listening for messages on {}'.format(subscription_path))

while True:
    time.sleep(60)


# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    # function to convert linked list to list for addition
    def toList(self, linked):
        convt = []
        while linked is not None:
            convt.append(linked.val)
            linked = linked.next
        return convt
    # function to add list of integers

    def addLists(self, num1, num2):
        sol = []
        for i in range(len(num1)):
            sol.append(num1[i]+num2[i])
        for i in range(len(sol)-1):
            if sol[i] >= 10:
                sol[i] = sol[i] - 10
                sol[i+1] = sol[i+1] + 1
        if sol[(len(sol)-1)] >= 10:
            sol[(len(sol)-1)] = sol[(len(sol)-1)] - 10
            sol = sol+[1]
        return sol
    # function to change list of integers back to linked list

    def cvtBack(self, lst):
        cur = dummy = ListNode(0)
        for e in lst:
            cur.next = ListNode(e)
            cur = cur.next
        return dummy.next

    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:
        first = self.toList(l1)
        second = self.toList(l2)
        # matching length
        diff = len(first) - len(second)
        if diff < 0:
            diff = -1 * diff
            first = first + [0]*diff
        else:
            second = second + [0]*diff
        result = self.addLists(first, second)
        answer = self.cvtBack(result)
        return (answer)


import datetime

import termux

from sync.misc.Config import config
from sync.misc.Logger import logger

class Notification:
    __instance__ = None

    def __init__(self):
        self.sync_all = {}
        self.watchers = {}
        self.global_status = "Active"
        now_date = datetime.datetime.now()
        self.last_start = f"Started: {now_date.strftime('%Y-%m-%d@%H:%M:%S')}"
        self.last_stop = f"Stopped: -"
        self.last_start_stop_time = now_date.strftime('%a. %H:%M:%S')
        self.last_full_sync = f"Fully synchronized: -"

    @staticmethod
    def get() -> "Notification":
        if Notification.__instance__ is None:
            Notification.__instance__ = Notification()
        return Notification.__instance__

    def set_full_sync_status(self, sync_all):
        self.sync_all = sync_all
        self.update()

    def set_watchers(self, watchers):
        self.watchers = watchers
        self.update()

    def set_global_status(self, global_status):
        self.global_status = global_status

    def set_inactive(self):
        self.set_global_status("Inactive")
        now_date = datetime.datetime.now()
        self.last_stop = f"Stopped: {now_date.strftime('%Y-%m-%d@%H:%M:%S')}"
        self.last_start_stop_time = now_date.strftime('%a. %H:%M:%S')
        self.update()

    def set_active(self):
        self.set_global_status("Active")
        now_date = datetime.datetime.now()
        self.last_start = f"Started: {now_date.strftime('%Y-%m-%d@%H:%M:%S')}"
        self.last_start_stop_time = now_date.strftime('%a. %H:%M:%S')
        self.update()

    def full_sync_done(self):
        self.last_full_sync = f"Fully synchronized: {datetime.datetime.now().strftime('%Y-%m-%d@%H:%M:%S')}"
        self.update()

    def exiting(self):
        self.set_global_status("Exited")
        now_date = datetime.datetime.now()
        self.last_start_stop_time = now_date.strftime('%a. %H:%M:%S')
        self.update()

    def update(self):
        notification_title = f"Termux-sync [{self.global_status}] [{self.last_start_stop_time}]"
        notification_id = 999
        notification_content = ""

        if config.debug:
            notification_content += self.last_stop + "\n"
            notification_content += self.last_start + "\n"
            notification_content += self.last_full_sync + "\n"
            notification_content += "\n"

        for sync_info in config.sync_info_list:
            item_line = f"{sync_info.label} "
            if sync_info.id in self.sync_all:
                item_line += f"{self.sync_all[sync_info.id]} | "
            else:
                item_line += f"- | "
            if sync_info.id in self.watchers:
                watcher = self.watchers[sync_info.id]
                item_line += watcher.files_info.get_status()
                if watcher.last_sync_date is not None:
                    last_sync_date = watcher.last_sync_date.strftime('%H:%M:%S')
                    item_line += f" ({last_sync_date})"
            else:
                item_line += " [Not watching]"
            notification_content += item_line + "\n"
        action = f"termux-open --content-type yaml {logger.log_file}"

        termux.Notification.notify(notification_title,
                                   notification_content,
                                   notification_id,
                                   args=("alert-once", "ongoing"),
                                   kwargs={"button1": "See logs", "button1-action": action})


from tkinter import *
from datetime import datetime, timedelta
import tkinter as tk
from tkinter import Entry, Label, StringVar, ttk, Checkbutton, Button, messagebox
import numpy as np
import pandas as pd

def generarCodigo(texto):
    sumar = 0
    codigo = texto[:3]
    if texto[len(texto) // 2] == " ":
        sumar = 1
    codigo += texto[len(texto) // 2 + sumar : len(texto) // 2 + 2 + sumar]
    codigo += texto[len(texto) - 1]
    codigo += str(len(texto))
    return codigo

def moda(lista):
    repetido = lista[0]
    for i in lista:
        if lista.count(i) > lista.count(repetido):
            repetido = i
    return repetido

def nombreIncorrecto(texto):
    invalidos = '1234567890!#$%&/()=?¡¿´*{¨]}[-_.:;,<>|°'
    for i in texto:
        if i in invalidos:
            return True
    return False

class Tabla:
    def __init__(self, root, dataFrame, anchos, fechas, bgColor, posX, posY):
        self.anchos = anchos
        self.fechas = fechas
        self.nuevoDatos = []
        self.componentes = []
        cont = 0
        self.df = dataFrame
        self.frm = ttk.Frame(root)
        for k in dataFrame:
            tmp = Entry(
                self.frm,
                width=anchos[cont],
                bg=bgColor,
                fg="black",
                font=("Arial", 12),
                highlightthickness=1,
                highlightbackground="#000000",
                highlightcolor="#000000",
            )
            tmp.grid(row=0, column=cont)
            tmp.insert(INSERT, k)
            cont += 1
        self.lista = list(dataFrame.to_records(index=False))
        self.filas = len(self.lista)
        self.columnas = cont
        for i in range(self.filas):
            row = []
            for j in range(self.columnas):
                aux = Entry(
                    self.frm,
                    width=anchos[j],
                    fg="black",
                    font=(
                        "Arial",
                        12,
                    ),
                    highlightthickness=1,
                    highlightbackground="#000000",
                    highlightcolor="#000000",
                )
                aux.grid(row=i + 1, column=j)
                if len(fechas) == 0:
                    aux.insert(INSERT, self.lista[i][j])
                else:
                    if j in fechas:
                        aux.insert(
                            INSERT,
                            pd.to_datetime(self.lista[i][j])
                            .date()
                            .strftime("%d/%m/%y"),
                        )
                    else:
                        aux.insert(INSERT, self.lista[i][j])
                aux.configure(state="readonly")
                row.append(aux)
            self.componentes.append(row)
        self.frm.pack()
        self.frm.place(x=posX, y=posY)

    def ingresarDatos(self, datos):
        self.lista.append(datos)
        for i in range(self.columnas):
            aux = Entry(
                self.frm,
                width=self.anchos[i],
                fg="black",
                font=(
                    "Arial",
                    12,
                ),
                highlightthickness=1,
                highlightbackground="#000000",
                highlightcolor="#000000",
            )
            aux.grid(row=self.filas + 1, column=i)
            aux.insert(INSERT, datos[i])
            aux.configure(state="readonly")
        self.df.loc[self.df.shape[0]] = datos
        self.filas += 1
        return

    def borrarUltimaFila(self):
        if self.filas < 1:
            messagebox.showerror(
                title="ERROR", message="No hay datos que puedan ser borrados"
            )
            return
        cont = 0
        for i in self.frm.winfo_children():
            if cont >= self.columnas * self.filas:
                i.destroy()
            cont += 1
        self.df = self.df[:-1]
        self.lista.pop()
        self.filas -= 1

class FrmIngresoDeLibros:
    def __init__(self, master, regresar):
        self.frm = ttk.Frame(master)
        self.nombreLibro = StringVar()
        self.cantidadLibro = StringVar()
        self.tabla = None
        self.agregarComponentes(master, regresar)

    def agregarComponentes(self, master, regresar):
        hoy = datetime.today().strftime("%d/%m/%y")
        Label(
            text="INGRESO DE LIBROS",
            font=("Arial", 24, "bold"),
            bg="#315E7A",
            fg="white",
            width="500",
            height="2",
        ).pack()
        Label(
            text=hoy,
            font=("Arial", 12),
            bg="#00E0FF",
            fg="white",
            width="20",
            height="1",
        ).pack()
        Label(text="Libro", font=("Arial", 12, "bold")).place(x=150, y=150)
        Entry(
            textvariable=self.nombreLibro,
            width="25",
            font=("Arial", 12),
            highlightthickness=2,
            highlightbackground="#000000",
            highlightcolor="#000000",
        ).place(x=250, y=150)
        Label(text="Cant", font=("Arial", 12, "bold")).place(x=520, y=150)
        Entry(
            textvariable=self.cantidadLibro,
            width="25",
            font=("Arial", 12),
            highlightthickness=2,
            highlightbackground="#000000",
            highlightcolor="#000000",
        ).place(x=590, y=150)
        Button(
            text="Borrar",
            font=("Arial", 12),
            width="20",
            bg="#D0A9F5",
            height="2",
            command=self.borrar,
        ).place(x=150, y=250)
        Button(
            text="Ingresar",
            font=("Arial", 12),
            width="20",
            bg="#D0A9F5",
            height="2",
            command=lambda: self.ingresar(master),
        ).place(x=400, y=250)
        Button(
            text="Regresar",
            font=("Arial", 12),
            width="20",
            bg="#D0A9F5",
            height="2",
            command=regresar,
        ).place(x=650, y=250)
        self.mostrarTabla(master)

    def borrar(self):
        self.tabla.borrarUltimaFila()
        archivo = self.tabla.df
        archivo2 = pd.read_excel("EstadoLibros.xlsx", sheet_name="Hoja1")
        archivo2 = archivo2[:-1]
        archivo.to_excel("Libros.xlsx", sheet_name="Hoja1", index=False)
        archivo2.to_excel("EstadoLibros.xlsx", sheet_name="Hoja1", index=False)

    def mostrarTabla(self, master):
        archivo = pd.read_excel("Libros.xlsx", sheet_name="Hoja1")
        anchos = [5, 40, 20, 20, 5]
        fechas = [2]
        self.tabla = Tabla(master, archivo, anchos, fechas, "#154673", 100, 350)

    def ingresar(self, master):
        n = len(self.tabla.lista) + 1
        nombre = self.nombreLibro.get()
        if nombre == "":
            messagebox.showerror(
                title="ERROR", message="El nombre ingresado es incorrecto"
            )
            return
        fecha = datetime.now().date().strftime("%d/%m/%y")
        try:
            stock = int(self.cantidadLibro.get())
        except ValueError:
            messagebox.showerror(
                title="ERROR", message="La cantidad ingresada es incorrecta"
            )
            return
        if stock <= 0:
            messagebox.showerror(
                title="ERROR", message="Debe ingresar una cantidad mayor a 0"
            )
            return
        if len(self.tabla.df[self.tabla.df["Nombre del Libro"] == nombre]) > 0:
            index = self.tabla.df.index[
                self.tabla.df["Nombre del Libro"] == nombre
            ].tolist()[0]
            valores = self.tabla.df[self.tabla.df["Nombre del Libro"] == nombre].values[
                0
            ]
            valores[3] += stock
            self.tabla.df.loc[index] = valores
            self.tabla.frm.destroy()
            archivo = self.tabla.df
            archivo.to_excel("Libros.xlsx", sheet_name="Hoja1", index=False)
            archivo2 = pd.read_excel("EstadoLibros.xlsx", sheet_name="Hoja1")
            valores2 = archivo2[archivo2["Nombre del Libro"] == nombre].values[0]
            valores2[5] += stock
            valores2[4] = valores2[5] - valores2[3]
            archivo2.loc[index] = valores2
            archivo2.to_excel("EstadoLibros.xlsx", sheet_name="Hoja1", index=False)
            self.mostrarTabla(master)
            messagebox.showinfo(
                message="El libro se ha actualizado correctamente",
                title="LIBRO ACTUALIZADO",
            )
            self.nombreLibro.set("")
            self.cantidadLibro.set("")
            return

        datos = (n, nombre, fecha, stock)
        self.nombreLibro.set("")
        self.cantidadLibro.set("")
        self.tabla.ingresarDatos(datos)
        archivo = self.tabla.df
        archivo.to_excel("Libros.xlsx", sheet_name="Hoja1", index=False)
        archivo2 = pd.read_excel("EstadoLibros.xlsx", sheet_name="Hoja1")
        archivo2.loc[archivo2.shape[0]] = [n, nombre, "Disponible", 0, stock, stock]
        archivo2.to_excel("EstadoLibros.xlsx", sheet_name="Hoja1", index=False)

class FrmRegistroEstudiante:
    def __init__(self, master, regresar):
        self.frm = Frame(master)
        self.nombre = StringVar()
        self.apellido = StringVar()
        self.lectorDelMes = StringVar()
        self.libroMasSolicitado = StringVar()
        self.cbxOperacion = None
        self.cbxLibro = None
        self.tabla = None
        self.ultimaOperacion = ""
        self.ultimoLibro = ""
        self.hallarDatos()
        self.agregarComponentes(master, regresar)

    def hallarDatos(self):
        excel = pd.read_excel("HistorialLibros.xlsx", sheet_name="Hoja1")
        nombres = excel["Nombre"]
        apellidos = excel["Apellido"]
        nombreCompleto = []
        for i in range(len(nombres)):
            nombreCompleto.append(nombres[i] + " " + apellidos[i])
        self.lectorDelMes.set(moda(nombreCompleto))
        libros = excel["Nombre del Libro"]
        self.libroMasSolicitado.set(moda(list(libros)))

    def agregarComponentes(self, master, regresar):
        hoy = datetime.today().strftime("%d/%m/%y")
        Label(
            text="REGISTRO DEL ESTUDIANTE",
            font=("Arial", 24, "bold"),
            bg="#DF7401",
            fg="white",
            width="500",
            height="2",
        ).pack()
        Label(
            text=hoy,
            font=("Arial", 12),
            bg="#F5DA81",
            fg="white",
            width="25",
            height="1",
        ).pack()
        Label(text="Nombre", font=("Arial", 12, "bold")).place(x=150, y=150)
        Entry(
            textvariable=self.nombre,
            width="20",
            font=("Arial", 12),
            highlightthickness=2,
            highlightbackground="#000000",
            highlightcolor="#000000",
        ).place(x=250, y=150)
        Label(text="Apellido", font=("Arial", 12, "bold")).place(x=150, y=200)
        Entry(
            textvariable=self.apellido,
            width="20",
            font=("Arial", 12),
            highlightthickness=2,
            highlightbackground="#000000",
            highlightcolor="#000000",
        ).place(x=250, y=200)
        Label(text="Operacion", font=("Arial", 12, "bold")).place(x=520, y=150)
        self.cbxOperacion = ttk.Combobox(
            state="readonly",
            values=["Retiro", "Devolucion"],
            width=15,
            font=("Arial", 12),
        )
        self.cbxOperacion.place(x=630, y=150)
        Label(text="Libro", font=("Arial", 12, "bold")).place(x=520, y=200)
        self.cbxLibro = ttk.Combobox(values=["a"], width=20, font=("Arial", 12))
        self.cbxLibro.place(x=630, y=200)
        Button(
            text="Borrar",
            font=("Arial", 12),
            width="20",
            bg="#F7BE81",
            height="2",
            command=lambda: self.borrar(master),
        ).place(x=150, y=260)
        Button(
            text="Aceptar",
            font=("Arial", 12),
            width="20",
            bg="#F7BE81",
            height="2",
            command=lambda: self.aceptar(master),
        ).place(x=400, y=260)
        Button(
            text="Regresar",
            font=("Arial", 12),
            width="20",
            bg="#F7BE81",
            height="2",
            command=regresar,
        ).place(x=650, y=260)
        Label(text="Lector del mes", font=("Arial", 12, "bold")).place(x=50, y=350)
        Entry(
            textvariable=self.lectorDelMes,
            width="25",
            font=("Arial", 12),
            highlightthickness=2,
            highlightbackground="#000000",
            highlightcolor="#000000",
            state="readonly",
        ).place(x=180, y=350)
        Label(text="Libro mas solicitado", font=("Arial", 12, "bold")).place(
            x=450, y=350
        )
        Entry(
            textvariable=self.libroMasSolicitado,
            width="30",
            font=("Arial", 12),
            highlightthickness=2,
            highlightbackground="#000000",
            highlightcolor="#000000",
            state="readonly",
        ).place(x=620, y=350)
        self.mostrarTabla(master)
        self.cbxOperacion.current(0)
        self.cbxLibro.configure(values=list(self.tabla.df["Nombre del Libro"]))
        self.cbxLibro.current(0)

    def mostrarTabla(self, master):
        archivo = pd.read_excel("EstadoLibros.xlsx", sheet_name="Hoja1")
        anchos = [5, 40, 20, 10, 10, 10]
        fechas = []
        self.tabla = Tabla(master, archivo, anchos, fechas, "#F5DA81", 50, 400)

    def borrar(self, master):
        if len(self.ultimaOperacion) == 0:
            messagebox.showerror(title='ERROR', message='No hay registros anteriores para borrar')
            return
        excel = self.tabla.df
        index = self.tabla.df.index[self.tabla.df["Nombre del Libro"] == self.ultimoLibro].tolist()[0]
        valores = self.tabla.df[self.tabla.df["Nombre del Libro"] == self.ultimoLibro].values[0]
        if self.ultimaOperacion == "Retiro":
            valores[4] += 1
            valores[3] -= 1
            if valores[4] > 0:
                valores[2] = 'Disponible'
            historial = pd.read_excel("HistorialLibros.xlsx", sheet_name="Hoja1")
            historial = historial[:-1]
            historial.to_excel("HistorialLibros.xlsx", sheet_name="Hoja1", index=False)
        else:
            valores[3] += 1
            valores[4] -= 1
            if valores[4] == 0:
                valores[2] = 'No Disponible'
        excel.loc[index] = valores
        excel.to_excel("EstadoLibros.xlsx", sheet_name="Hoja1", index=False)
        self.tabla.frm.destroy()
        self.mostrarTabla(master)
        self.hallarDatos()
        self.ultimaOperacion = ""
        self.ultimoLibro = ""

    def aceptar(self, master):
        nombre = self.nombre.get()
        apellido = self.apellido.get()
        operacion = self.cbxOperacion.get()
        libro = self.cbxLibro.get()
        excel = self.tabla.df
        mensaje = ""
        if len(nombre) == 0:
            mensaje += "Debe ingresar el nombre del alumno\n"
        if len(apellido) == 0:
            mensaje += "Debe ingresar el apelldio del alumno\n"
        if len(mensaje) > 0:
            messagebox.showerror(title="ERROR", message=mensaje)
            return
        mensaje = ""
        if nombreIncorrecto(nombre) is True:
            mensaje += 'El nombre del alumno es incorrecto\n'
        if nombreIncorrecto(apellido) is True:
            mensaje += 'El apellido del alumno es incorrecto\n'
        if len(mensaje) > 0:
            messagebox.showerror(title='ERROR', message=mensaje)
            return
        if len(self.tabla.df[self.tabla.df["Nombre del Libro"] == libro]) > 0:
            index = self.tabla.df.index[
                self.tabla.df["Nombre del Libro"] == libro
            ].tolist()[0]
            valores = self.tabla.df[self.tabla.df["Nombre del Libro"] == libro].values[
                0
            ]
            if operacion == "Retiro":
                if valores[4] > 0:
                    valores[3] += 1
                    valores[4] -= 1
                    if valores[4] == 0:
                        valores[2] = 'No Disponible'
                    historial = pd.read_excel(
                        "HistorialLibros.xlsx", sheet_name="Hoja1"
                    )
                    n = len(list(historial.to_records(index=False))) + 1
                    codigo = generarCodigo(libro)
                    hoy = datetime.today()
                    entrega = timedelta(7)
                    datos = [
                        n,
                        nombre,
                        apellido,
                        libro,
                        codigo,
                        hoy.strftime("%d/%m/%y"),
                        datetime.date(hoy + entrega).strftime("%d/%m/%y"),
                    ]
                    historial.loc[historial.shape[0]] = datos
                    historial.to_excel(
                        "HistorialLibros.xlsx", sheet_name="Hoja1", index=False
                    )
                    self.nombre.set("")
                    self.apellido.set("")
                    messagebox.showinfo(
                        title="RETIRO EXITOSO",
                        message="El libro ha sido retirado satisfactoriamente",
                    )
                else:
                    messagebox.showerror(
                        title="ERROR", message="No quedan mas libros disponibles"
                    )
            else:
                if valores[4] < valores[5]:
                    valores[4] += 1
                    valores[3] -= 1
                    if valores[4] > 0:
                        valores[2] = 'Disponible'
                    self.nombre.set("")
                    self.apellido.set("")
                    messagebox.showinfo(
                        title="DEVOLUCION EXITOSA",
                        message="El libro ha sido devuelto satisfactoriamente",
                    )
                else:
                    messagebox.showerror(
                        title="ERROR", message="No existen devoluciones pendientes"
                    )
            self.ultimaOperacion = operacion
            self.ultimoLibro = libro
            excel.loc[index] = valores
            excel.to_excel("EstadoLibros.xlsx", sheet_name="Hoja1", index=False)
            self.tabla.frm.destroy()
            self.mostrarTabla(master)
            self.hallarDatos()
        else:
            messagebox.showerror(
                title="ERROR", message="El libro que estas solicitando no existe"
            )

class FrmRetirosDevoluciones:
    def __init__(self, master, regresar):
        self.cbxLibro = None
        self.tabla = None
        self.agregarComponentes(master, regresar)

    def agregarComponentes(self, master, regresar):
        Label(text="Libro", font=("Arial", 12, "bold")).place(x=50, y=40)
        self.cbxLibro = ttk.Combobox(values=["a"], width=30, font=("Arial", 12))
        self.cbxLibro.place(x=150, y=40)
        Button(
            text="Buscar",
            font=("Arial", 12),
            width="20",
            bg="#6C3483",
            height="2",
            command=lambda: self.actualizarTabla(master),
        ).place(x=500, y=20)
        Button(
            text="Regresar",
            font=("Arial", 12),
            width="20",
            bg="#6C3483",
            height="2",
            command=regresar,
        ).place(x=750, y=20)
        excel = pd.read_excel("Libros.xlsx", sheet_name="Hoja1")
        self.cbxLibro.configure(values=list(excel["Nombre del Libro"]))

    def actualizarTabla(self, master):
        if self.tabla != None:
            self.tabla.frm.destroy()
        libro = self.cbxLibro.get()
        if len(libro) == 0:
            messagebox.showerror(title='ERROR', message='Debe ingresar el nombre del libro que desea consultar')
            return
        excel = pd.read_excel("HistorialLibros.xlsx", sheet_name="Hoja1")
        if len(excel[excel["Nombre del Libro"] == libro]) > 0:
            filtrado = excel[excel["Nombre del Libro"] == libro]
            anchos = [5, 15, 15, len(libro), 10, 13, 13]
            fechas = []
            self.tabla = Tabla(
            master, filtrado, anchos, fechas, "#A569BD", 43 - len(libro), 100
            )
        else:
            messagebox.showerror(title='ERROR', message='No existen registros del libro ingresado')

class BibliotecaEscolar:
    def __init__(self):
        self.root = tk.Tk()
        self.root.title("Biblioteca Escolar")
        screen_width = self.root.winfo_screenwidth()
        screen_height = self.root.winfo_screenheight()
        w = 1000
        h = 600
        x = (screen_width/2) - (500)
        y = (screen_height/2) - (300)
        self.root.geometry('%dx%d+%d+%d' % (w, h, x, y))
        self.root.resizable(False, False)
        self.agregarComponentes()
        self.formulario = None
        self.root.mainloop()

    def regresar(self):
        for widget in self.root.winfo_children():
            widget.destroy()
        self.agregarComponentes()

    def limpiarFormulario(self, frm):
        for widget in frm.winfo_children():
            widget.destroy()

    def agregarComponentes(self):
        hoy = datetime.today().strftime("%d-%m-%y")
        Label(
            text="BIBLIOTECA ESCOLAR",
            font=("Arial", 24, "bold"),
            bg="#27AE60",
            fg="white",
            width="500",
            height="2",
        ).pack()
        Label(
            text=hoy,
            font=("Arial", 12),
            bg="#82E0AA",
            fg="black",
            width="25",
            height="1",
        ).pack()
        Button(
            text="Registrar Libro",
            font=("Arial", 16),
            width="20",
            bg="#315E7A",
            height="4",
            fg="white",
            command=self.abrirFrmRegistrar,
        ).place(x=150, y=230)
        Button(
            text="Solicitudes Libro",
            font=("Arial", 16),
            width="20",
            bg="#DF7401",
            height="4",
            fg="white",
            command=self.abrirFrmSolicitud,
        ).place(x=600, y=230)
        Button(
            text="Salir del programa",
            font=("Arial", 16),
            width="20",
            bg="#A93226",
            height="4",
            fg="white",
            command=self.cerrarPrograma,
        ).place(x=600, y=400)
        Button(
            text="Retiros y devoluciones",
            font=("Arial", 16),
            width="20",
            bg="#5B2C6F",
            height="4",
            fg="white",
            command=self.abrirFrmRetirosDevoluciones,
        ).place(x=150, y=400)

    def abrirFrmRegistrar(self):
        self.limpiarFormulario(self.root)
        self.formulario = FrmIngresoDeLibros(self.root, self.regresar)

    def abrirFrmSolicitud(self):
        self.limpiarFormulario(self.root)
        self.formulario = FrmRegistroEstudiante(self.root, self.regresar)

    def abrirFrmRetirosDevoluciones(self):
        self.limpiarFormulario(self.root)
        self.formulario = FrmRetirosDevoluciones(self.root, self.regresar)

    def cerrarPrograma(self):
        self.root.destroy()

a = BibliotecaEscolar()


n = int(input())
l = list(map(int,input().split()))
l.sort(reverse=True)
oddl = []
evenl = []
for i in l:
    if i%2 == 0:
        evenl.append(i)
    else:
        oddl.append(i)
ans = -1
if 2 <= len(oddl):
    ans = max(ans,oddl[0]+oddl[1])
if 2 <= len(evenl):
    ans = max(ans,evenl[0]+evenl[1])
print(ans)


# import random
# import time

#* Génération de la liste
# TAILLE = int(1e5)
# BORNE_SUP = int(1e2)
# liste_a_trier = [random.randint(0,BORNE_SUP) for _ in range(TAILLE)]
# print(liste_a_trier)

def fusion(A,p,q,r):
    """
    Opére la fusion de la liste A[p,q] et A[q,r]
    """
    # on stocke les deux listes
    liste1 = A[p:q] + [float("inf")]
    liste2 = A[q:r] + [float("inf")]
    # print(liste1)
    # print(liste2)
    i, j = 0, 0
    for k in range(p,r):
        if liste1[i] < liste2[j]:
            A[k] = liste1[i]
            i+=1
        else:
            A[k] = liste2[j]
            j+=1
    # print(A)

def tri_fusion(A, p, r):
    """
    A est la liste
    p est l'index du premier élément de
    r est l'index du dernier élément
    """
    if p < r-1: # si la liste comporté de plus d'un élément
        q = (p+r)//2  # Milieu
        # print(f"{A[p:q]} + {A[q+1:r]} | p={p} | q={q} | r={r}")
        tri_fusion(A, p, q) # On trie la première partie
        tri_fusion(A, q, r) #On trie la deuxième partie
        fusion(A,p,q,r) # On fusionne le tout

if __name__ == '__main__':
    # print(liste_a_trier)
    # triée = sorted(liste_a_trier)
    # print(f"True = {triée}")
    # start = time.time()
    # tri_fusion(liste_a_trier, 0, len(liste_a_trier))
    # print(f"{time.time()-start}")

    n = int(input())
    numbers = list(map(int, input().split()))
    tri_fusion(numbers, 0, n)
    print(" ".join([str(x) for x in numbers]))


from helpers import ReadLines
from typing import Tuple, List

class DayFive(ReadLines):
    def __init__(
        self, file_path="/home/jonathan/projects/2020-advent-of-code/five/input.txt"
    ):
        super().__init__(file_input=file_path)
        self.seat_ids = sorted(
            [DayFive.identify_seat(seat_code)[2] for seat_code in self.inputs]
        )

    @staticmethod
    def _process_code(code: List[str], _range: Tuple[int, int]) -> int:
        """
        I'm leaving this method in, because it's quite neat - but it has been rendered useless by the more practical _binary_count method below
        """
        if len(code) == 1:
            keys = {"L": 0, "F": 0, "R": 1, "B": 1}
            return _range[keys[code[0]]]
        else:
            next_letter = code.pop(0)
            mid_point = int((_range[1] + 1 - _range[0]) / 2)
            if next_letter == "F" or next_letter == "L":
                new_range = _range[0], _range[0] + mid_point - 1
            elif next_letter == "B" or next_letter == "R":
                new_range = _range[0] + mid_point, _range[1]
            return DayFive._process_code(code, new_range)

    @staticmethod
    def _binary_count(seat_code: str):
        letter_key = {"F": "0", "L": "0", "B": "1", "R": "1"}
        binary_string_code = "".join([letter_key[letter] for letter in seat_code])
        return int(binary_string_code, 2)

    @staticmethod
    def identify_seat(seat_reference: str) -> Tuple[int, int, int]:
        row = DayFive._binary_count(seat_reference[:7])
        column = DayFive._binary_count(seat_reference[-3:])
        seat_id = row * 8 + column
        return row, column, seat_id

    def highest_id(self):
        return max(self.seat_ids)

    def find_missing_id(self) -> int:
        all_ids = set([i for i in range(min(self.seat_ids), max(self.seat_ids) + 1)])
        seat_ids = set(self.seat_ids)
        return all_ids.difference(seat_ids).pop()


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

import os
import time
import hashlib
import sys
import struct

def getPIN(username):
    ''' According to code from https://github.com/nowind/sx_pi
    '''
    current_time = time.time()
    time_divided_by_five = int(current_time) // 5
    time_char = [0] * 4
    temp = [0] * 32
    time_hash = [0] * 4
    PIN27 = [0] * 6
    PIN = ""
    md5 = hashlib.md5()

    for i in xrange(0, 4):
        time_char[i] = time_divided_by_five >> (8 * (3 - i)) & 0xFF
    before_md5 = struct.pack('>I', time_divided_by_five) + \
        (username.split('@')[0] + "singlenet01").encode('ascii')
    md5.update(before_md5)
    after_md5 = md5.hexdigest()

    for i in xrange(0, 32):
        temp[i] = time_char[(31 - i) / 8] & 1
        time_char[(31 - i) / 8] = time_char[(31 - i) / 8] >> 1

    for i in xrange(0, 4):
        time_hash[i] = temp[i] * 128 + temp[4 + i] * 64 + temp[8 + i] * \
            32 + temp[12 + i] * 16 + temp[16 + i] * 8 + temp[20 + i] * \
            4 + temp[24 + i] * 2 + temp[28 + i]

    temp[1] = (time_hash[0] & 3) << 4
    temp[0] = (time_hash[0] >> 2) & 0x3F
    temp[2] = (time_hash[1] & 0xF) << 2
    temp[1] = (time_hash[1] >> 4 & 0xF) + temp[1]
    temp[3] = time_hash[2] & 0x3F
    temp[2] = ((time_hash[2] >> 6) & 0x3) + temp[2]
    temp[5] = (time_hash[3] & 3) << 4
    temp[4] = (time_hash[3] >> 2) & 0x3F

    for i in xrange(0, 6):
        PIN27[i] = temp[i] + 0x020
        if PIN27[i] >= 0x40:
            PIN27[i] += 1

    for i in xrange(0, 6):
        PIN += chr(PIN27[i])

    PIN = '\r\n' + PIN + after_md5[0] + after_md5[1] + username

    return PIN

def write_conf():
    pin = getPIN(sys.argv[1])

    with open('provider_tpl', 'r') as fp:
        template = fp.read()
    conf = template + '\"' + pin + '\"'

    with open('/etc/ppp/peers/dsl-provider', 'w') as fp:
        fp.write(conf)

    with open('pap_tpl', 'r') as fp:
        template = fp.read()
    conf = template + '\"' + getPIN(sys.argv[1]) + \
        '\" * \"' + sys.argv[2] + '\"'

    with open('/etc/ppp/pap-secrets', 'w') as fp:
        fp.write(conf)

if __name__ == '__main__':
    write_conf()
    os.system('pon dsl-provider')


from collections import Set
import random

from cardboard import events

__all__ = ["UnorderedZone", "OrderedZone", "zone"]

# TODO: Clarify / make zone operations atomic
ENTER, LEAVE = events.ENTERED_ZONE, events.LEFT_ZONE

def _zone(name):
    """
    Create a zone classmethod from the zone name.

    """

    @classmethod
    def zone(cls, game, contents=(), owner=None):
        return cls(game, name=name, contents=contents, owner=owner)
    return zone

class ZoneMixin(object):
    def __init__(self, game, name, contents=(), owner=None):
        self.game = game
        self.name = name
        self.owner = owner

        self._contents = set(contents)

    def __contains__(self, e):
        return e in self._contents

    def __str__(self):
        return self.name

    def __repr__(self):
        return "<Zone: {}>".format(self)

    def update(self, i, silent=False):
        """
        Add multiple elements at the same time.

        Analogous to list.extend and set.update.
        """

        for e in i:
            self.add(e, silent=silent)

    def move(self, e, silent=False):
        """
        Remove a card from its current zone and place it in this zone.

        Raises a ValueError for cards that are already present.

        """

        if e in self:
            raise ValueError("'{}' is already in the {} zone.".format(e, self))

        e.zone.remove(e, silent=silent)
        self.add(e, silent=silent)

class UnorderedZone(ZoneMixin):

    battlefield = _zone(u"battlefield")
    exile = _zone(u"exile")
    hand = _zone(u"hand")

    ordered = False

    def __iter__(self):
        return iter(self._contents)

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

    def add(self, e, silent=False):
        if not silent and self.owner is not None and self.owner != e.owner:
            # TODO: log things that misbehaved
            return getattr(e.owner, self.name).add(e)

        if e in self:
            if self.owner is not None:
                s = "in {}'s {}".format(self.owner, self.name)
            else:
                s = "on the {}".format(self.name)

            raise ValueError("{} is already {}.".format(e, s))

        self._contents.add(e)

        if not silent:
            self.game.events.trigger(event=ENTER, card=e, zone=self)

    def pop(self, silent=False):
        try:
            e = self._contents.pop()
            return e
        finally:
            if not silent:
                self.game.events.trigger(event=LEAVE, card=e, zone=self)

    def remove(self, e, silent=False):
        try:
            self._contents.remove(e)
        except KeyError:
            raise ValueError("'{}' is not in the {} zone.".format(e, self))
        else:
            if not silent:
                self.game.events.trigger(event=LEAVE, card=e, zone=self)

class OrderedZone(ZoneMixin):

    graveyard = _zone(u"graveyard")
    library = _zone(u"library")
    stack = _zone(u"stack")

    ordered = True

    def __init__(self, game, name, contents=(), owner=None):
        self._order = list(contents)

        super(OrderedZone, self).__init__(
            game=game, name=name, contents=self._order, owner=owner
        )

    def __getitem__(self, i):
        # TODO / Beware: Zone slicing
        return self._order[i]

    def __iter__(self):
        return iter(self._order)

    def __len__(self):
        # don't plan on allowing duplicates, but just in case, use order
        return len(self._order)

    def __reversed__(self):
        return reversed(self._order)

    def add(self, e, silent=False):
        # a safeguard against cards that are accidentally being moved to
        # another zone other than their owners (TODO: log misbehavers)
        if not silent and self.owner is not None and self.owner != e.owner:
            return getattr(e.owner, self.name).add(e)

        if e in self:
            if self.owner is not None:
                s = "in {}'s {}".format(self.owner, self.name)
            else:
                s = "on the {}".format(self.name)

            raise ValueError("{} is already {}.".format(e, s))

        self._contents.add(e)
        self._order.append(e)

        if not silent:
            self.game.events.trigger(event=ENTER, card=e, zone=self)

    def count(self, e):
        return self._order.count(e)

    def index(self, e):
        return self._order.index(e)

    def pop(self, i=None, silent=False):
        if i is None:
            e = self._order.pop()
        else:
            e = self._order.pop(i)

        self._contents.remove(e)

        if not silent:
            self.game.events.trigger(event=LEAVE, card=e, zone=self)

        return e

    def remove(self, e, silent=False):
        if e not in self:
            raise ValueError("'{}' is not in the {} zone.".format(e, self))

        self._contents.remove(e)
        self._order.remove(e)

        if not silent:
            self.game.events.trigger(event=LEAVE, card=e, zone=self)

    def reverse(self):
        self._order.reverse()

    def shuffle(self):
        random.shuffle(self._order)

zone = {"battlefield" : UnorderedZone.battlefield,
        "exile" : UnorderedZone.exile,
        "graveyard" : OrderedZone.graveyard,
        "hand" : UnorderedZone.hand,
        "library" : OrderedZone.library,
        "stack" : OrderedZone.stack}


# 세준이는 양수와 +, -, 그리고 괄호를 가지고 식을 만들었다. 그리고 나서 세준이는 괄호를 모두 지웠다.
# 그리고 나서 세준이는 괄호를 적절히 쳐서 이 식의 값을 최소로 만들려고 한다.
# 괄호를 적절히 쳐서 이 식의 값을 최소로 만드는 프로그램을 작성하시오.

import sys
formula = sys.stdin.readline().split('-')
result = []
for i in formula:
    cnt = 0
    s = i.split('+')
    for j in s:
        cnt += int(j)
    result.append(cnt)
resultnum = int(result[0]) * 2
for i in result:
    resultnum -= i
print(resultnum)


import pygame

pygame.init()

pygame.display.set_caption("WannabePong")

size = 800, 600
screen = pygame.display.set_mode(size)
width, height = size
speed = [1, 1]
bgc = 255, 255, 255
fontControls = pygame.font.SysFont("monospace", 16)
font = pygame.font.SysFont("monospace", 26)
fontCount = pygame.font.SysFont("monospace", 42)
pelota = pygame.image.load("pelota.png")
pelotaRect = pelota.get_rect()
palaRoja = pygame.image.load("palaRoja.png")
palaRojaRect = palaRoja.get_rect()
palaAzul = pygame.image.load("palaAzul.png")
palaAzulRect = palaAzul.get_rect()
divisor = pygame.image.load("divisor.png")
divisorRect = divisor.get_rect()
strikesRojo = 0
strikesAzul = 0
countdown = 10
run = True

divisorRect.move_ip(400, 0)
palaRojaRect.move_ip(1, 300)
palaAzulRect.move_ip(773, 300)

while countdown > 0:
  count = fontCount.render("{0}".format(countdown), 1, (0,0,0))
  redControls = fontControls.render("Moves with W and S keys", 1, (0,0,0))
  blueControls = fontControls.render("Moves with UP and DOWN arrows", 1, (0,0,0))
  screen.fill(bgc)
  screen.blit(redControls, (5, 50))
  screen.blit(blueControls, (505, 50))
  screen.blit(count, (388, 250))
  pygame.display.flip()
  pygame.time.wait(1000)
  countdown -= 1

while run:
  pygame.time.delay(2)
  pelotaRect = pelotaRect.move(speed)
  keys = pygame.key.get_pressed()
  strikesRojoDisplay = font.render("Strikes: {0}".format(strikesRojo), 1, (0,0,0))
  strikesAzulDisplay = font.render("Strikes: {0}".format(strikesAzul), 1, (0,0,0))
  winnerRojo = font.render("RED WINS!", 1, (0,0,0))
  winnerAzul = font.render("BLUE WINS!", 1, (0,0,0))

  for event in pygame.event.get():
    if event.type == pygame.QUIT:
      run = False
  if keys[pygame.K_w] and palaRojaRect.top <= 0:
    palaRojaRect = palaRojaRect.move(0, 0)
  elif keys[pygame.K_w]:
    palaRojaRect = palaRojaRect.move(0, -1)
  if keys[pygame.K_s] and palaRojaRect.bottom >= height:
    palaRojaRect = palaRojaRect.move(0, 0)
  elif keys[pygame.K_s]:
    palaRojaRect = palaRojaRect.move(0, 1)
  if keys[pygame.K_UP] and palaAzulRect.top <= 0:
    palaAzulRect = palaAzulRect.move(0, 0)
  elif keys[pygame.K_UP]:
    palaAzulRect = palaAzulRect.move(0, -1)
  if keys[pygame.K_DOWN] and palaAzulRect.bottom >= height:
    palaAzulRect = palaAzulRect.move(0, 0)
  elif keys[pygame.K_DOWN]:
    palaAzulRect = palaAzulRect.move(0, 1)
  if palaRojaRect.colliderect(pelotaRect):
    speed[0] = -speed[0]
  if palaAzulRect.colliderect(pelotaRect):
    speed[0] = -speed[0]
  if pelotaRect.left <= 0 or pelotaRect.right >= width:
    speed[0] = -speed[0]
    if pelotaRect.left <= 0:
      strikesRojo += 1
    elif pelotaRect.right >= width:
      strikesAzul += 1
  if pelotaRect.top <= 0 or pelotaRect.bottom >= height:
    speed[1] = -speed[1]
  if strikesRojo == 3 or strikesAzul == 3:
    run = False

  screen.fill(bgc)
  screen.blit(divisor, divisorRect)
  screen.blit(pelota, pelotaRect)
  screen.blit(palaRoja, palaRojaRect)
  screen.blit(palaAzul, palaAzulRect)
  screen.blit(strikesRojoDisplay, (5, 10))
  screen.blit(strikesAzulDisplay, (633, 10))
  pygame.display.flip()

screen.fill(bgc)
if strikesRojo == 3:
  screen.blit(winnerAzul, (333, 250))
  pygame.display.flip()
elif strikesAzul == 3:
  screen.blit(winnerRojo, (333, 250))
  pygame.display.flip()
pygame.time.wait(5000)
pygame.QUIT()


def quick_sort(a_list):
    if len(a_list) < 2:
        return a_list
    else:
        pivot = a_list[0]
        less = quick_sort([i for i in a_list if i < pivot])
        greater = quick_sort([i for i in a_list if i > pivot])
        return less + [pivot] + greater

print(quick_sort([7,6,3,99]))


# 형태소 분석

from konlpy.tag import Okt
from docutils.parsers.rst.directives import encoding
okt = Okt()
#result = okt.pos('고추 등 매운음식을 오랫동안 너무 많이 먹었을 경우 인지능력과 기억력을 저하시킬 위험이 높다는 연구결과가 나왔다.')
#result = okt.morphs('고추 등 매운음식을 오랫동안 너무 많이 먹었을 경우 인지능력과 기억력을 저하시킬 위험이 높다는 연구결과가 나왔다.')
#result = okt.nouns('고추 등 매운음식을 오랫동안 너무 많이 먹었을 경우 인지능력과 기억력을 저하시킬 위험이 높다는 연구결과가 나왔다.')
#print(result)

import urllib
from bs4 import BeautifulSoup
from urllib import parse

para = parse.quote("이순신")
print(para)
url = "https://ko.wikipedia.org/wiki/" + para
page = urllib.request.urlopen(url)
soup = BeautifulSoup(page.read(), 'lxml')
print(soup)

wordlist = []

for item in soup.select("#mw-content-text > div > p"):
    if item.string != None:
        #print(item.string)
        ss = item.string
        wordlist += okt.nouns(ss)

print('wordlist 출력')
print(wordlist)
print('단어 수 : ' + str(len(wordlist)))

word_dict = {}
for i in wordlist:
    if i in word_dict:
        word_dict[i] += 1
    else:
        word_dict[i] = 1

print('\n\n word_dict 출력')
print(word_dict)

print('중복 단어 제거')
setdata = set(wordlist)
print(setdata)
print('발견된 단어 수 (중복x) : ' + str(len(setdata)))

# csv 파일로 저장
import csv
import pandas as pd

try:
    f = csv.writer(open('ws1.csv', 'w', encoding='utf-8'))
    f.writerow(word_dict)
except Exception as e:
    print('err : ', e)

# df1 = pd.read_csv('ws1.csv', encoding='utf-8')
# print(df1)

with open('ws1.csv', 'r', encoding='utf-8')as f:
    print(f.read())

print()
from pandas import Series, DataFrame
li_data = Series(wordlist)
#print(li_data)
print(li_data.value_counts()[:5])
print()
li_data = Series(word_dict)
print(li_data.value_counts()[:5])

print('-----------------')
df = DataFrame(wordlist, columns = ['단어'])
print(df.head())

###############################################################


def get_next_pos(row, col, direction):
    if direction == 'up':
        return row - 1, col
    if direction == 'down':
        return row + 1, col
    if direction == 'left':
        return row, col - 1
    if direction == 'right':
        return row, col + 1

def is_inside(row, col, size):
    return 0 <= row < size and 0 <= col < size

def get_around_kids(matrix, row, col):
    result = []
    if is_inside(row, col - 1, len(matrix)) and matrix[row][col - 1] == 'X' or matrix[row][col - 1] == 'V':
        result.append([row, col - 1])
    if is_inside(row, col + 1, len(matrix)) and matrix[row][col + 1] == 'X' or matrix[row][col + 1] == 'V':
        result.append([row, col + 1])
    if is_inside(row - 1, col, len(matrix)) and matrix[row - 1][col] == 'X' or matrix[row - 1][col] == 'V':
        result.append([row - 1, col])
    if is_inside(row + 1, col, len(matrix)) and matrix[row + 1][col] == 'X' or matrix[row + 1][col] == 'V':
        result.append([row + 1, col])

    return result

gifts = int(input())
size = int(input())

santa_row = 0
santa_col = 0
nice_kids = 0

matrix = []
for row in range(size):
    row_elements = input().split()
    for col in range(size):
        if row_elements[col] == 'S':
            santa_row = row
            santa_col = col
        elif row_elements[col] == 'V':
            nice_kids += 1
    matrix.append(row_elements)

nice_kids_gifted = 0

while gifts > 0:
    line = input()
    if line == 'Christmas morning':
        break
    matrix[santa_row][santa_col] = '-'
    santa_row, santa_col = get_next_pos(santa_row, santa_col, line)

    if matrix[santa_row][santa_col] == 'V':
        gifts -= 1
        nice_kids_gifted += 1
    elif matrix[santa_row][santa_col] == 'C':
        around_kids = get_around_kids(matrix, santa_row, santa_col)
        for kid_row, kid_col in around_kids:
            if matrix[kid_row][kid_col] == 'V':
                nice_kids_gifted += 1
            gifts -= 1
            matrix[kid_row][kid_col] = '-'
            if gifts == 0:
                break

    matrix[santa_row][santa_col] = 'S'

if nice_kids_gifted != nice_kids and gifts == 0:
    print("Santa ran out of presents!")
for row in matrix:
    print(*row, sep=' ')
if nice_kids_gifted == nice_kids:
    print(f"Good job, Santa! {nice_kids} happy nice kid/s.")
else:
    print(f"No presents for {nice_kids - nice_kids_gifted} nice kid/s.")


''' Strategy to be backtested. '''

import backtrader as bt

# Create a Stratey
class TestStrategy(bt.Strategy):
    ''' Base class to be subclassed for user defined strategies. '''

    # Moving average parameters
    params = (('pfast',2),('pslow',184),)

    def __init__(self):

        self.dataclose = self.datas[0].close
        self.datahigh = self.datas[0].high
        self.datalow = self.datas[0].low

		# Order variable will contain ongoing order details/status
        self.order = None

        # Instantiate moving averages
        self.slow_sma = bt.indicators.MovingAverageSimple(self.datas[0],
                        period=self.params.pslow)
        self.fast_sma = bt.indicators.MovingAverageSimple(self.datas[0],
                        period=self.params.pfast)

        self.bar_executed = 0

    def log(self, txt, dt=None):
        ''' Logging function for this strategy. '''

        dt = dt or self.datas[0].datetime.date(0)
        print(f'{dt.isoformat()}, {txt}')

    def next(self):
        '''
        This method will be called for all remaining data points when
        the minimum period for all datas/indicators have been meet.
        '''

        # Check for open orders
        if self.order:
            return

        # Check if we are in the market
        if not self.position:
            # We are not in the market, look for a signal to OPEN trades

            if self.fast_sma[0] > self.slow_sma[0]:
                self.log(f'BUY CREATED: {self.dataclose[0]:2f}')
                # Keep track of the created order to avoid a 2nd order
                self.order = self.buy()
            elif self.fast_sma[0] < self.slow_sma[0]:
                self.log(f'SELL CREATED: {self.dataclose[0]}')
                # Keep track of the created order to avoid a 2nd order
                self.order = self.sell()

    def notify_order(self, order):
        ''' Receives an order whenever there has been a change in one. '''

        if order.status in [order.Submitted, order.Accepted]:
            # An active Buy/Sell order has been submitted/accepted - Nothing to do
            return

        # Check if an order has been completed
        # Attention: broker could reject order if not enough cash
        if order.status in [order.Completed]:
            if order.isbuy():
                self.log(f'BUY EXECUTED: {order.executed.price}')
            elif order.issell():
                self.log(f'SELL EXECUTED: {order.executed.price}')
            self.bar_executed = len(self)

        elif order.status in [order.Canceled, order.Margin, order.Rejected]:
            self.log('Order Canceled/Margin/Rejected')

        # Reset orders
        self.order = None


import csv
import functools
import json
import math
import random

def cycle_call_parametrized(string_q: int, left_b: int, right_b: int):
    def cycle_call(func):
        # print(f'LALA')

        def wrapper_(*args, **kwargs):
            # creating a csv-file:
            generate_csv(string_q, left_b, right_b)
            roots = dict()
            with open('info.csv', 'r', encoding='utf-8') as f:
                reader = csv.reader(f, dialect='excel')
                for i, row in enumerate(reader):
                    if row:
                        a, b, c = row
                        a, b, c, = int(a), int(b), int(c)
                        roots[i // 2] = str(func(a, b, c))
            return roots

        return wrapper_

    return cycle_call

def jsonize(func):
    def wrapper_(*args, **kwargs):
        # getting info:
        roots = func(args, kwargs)
        with open('info.json', 'w', encoding='utf-8') as f:
            json.dump(roots, f, indent='\n')
    return wrapper_

@jsonize
@cycle_call_parametrized(100, 100, 1000)
def solve_quadratic_equation(a: int, b: int, c: int):
    """solves a * x^2 + b * x + c = 0 equation..."""
    sqrt_d = (b ** 2 - 4 * a * c) ** .5
    x1, x2 = (-b + sqrt_d) / (2 * a), (-b - sqrt_d) / (2 * a)
    return x1, x2 if x1 != x2 else x1

def generate_csv(string_q: int, left_b: int, right_b: int):  # 100 -->> 1000 strings...
    with open('info.csv', 'w', encoding='utf-8') as f:
        writer = csv.writer(f, dialect='excel', quotechar='|', quoting=csv.QUOTE_MINIMAL)
        for ind in range(string_q + 1):
            k = [random.randint(left_b, right_b + 1) for _ in [0, 1, 2]]
            # print(f'k: {k}')
            writer.writerow(k)

# generate_csv(100, 100, 1000)

solve_quadratic_equation()
solve_quadratic_equation()


def FiveCnt(K):
  cnt = 0
  while K:
    cnt += K//5
    K //= 5
  return cnt

def TwoCnt(K):
  cnt = 0
  while K:
    cnt += K//2
    K //= 2
  return cnt

N, M = map(int, input().split())
print(min(FiveCnt(N)-FiveCnt(N-M)-FiveCnt(M), TwoCnt(N)-TwoCnt(N-M)-TwoCnt(M)))


def calcRedundantBits(m):

    for i in range(m):
        if 2**i >= m + i + 1:
            return i

def posRedundantBits(data, r):

    # Redundancy bits are placed at the positions
    # which correspond to the power of 2.
    j = 0
    k = 1
    m = len(data)
    res = ""

    # If position is power of 2 then insert '0'
    # Else append the data
    for i in range(1, m + r + 1):
        if i == 2**j:
            res = res + "0"
            j += 1
        else:
            res = res + data[-1 * k]
            k += 1

    # The result is reversed since positions are
    # counted backwards. (m + r+1 ... 1)
    return res[::-1]

def calcParityBits(arr, r):
    n = len(arr)

    # For finding rth parity bit, iterate over
    # 0 to r - 1
    for i in range(r):
        val = 0
        for j in range(1, n + 1):

            # If position has 1 in ith significant
            # position then Bitwise OR the array value
            # to find parity bit value.
            if j & (2**i) == (2**i):
                val = val ^ int(arr[-1 * j])
                # -1 * j is given since array is reversed

        # String Concatenation
        # (0 to n - 2^r) + parity bit + (n - 2^r + 1 to n)
        arr = arr[: n - (2**i)] + str(val) + arr[n - (2**i) + 1 :]
    return arr

# Enter the data to be transmitted
print("Code by : Swarup Kharul (20BCT0073)")
data = input("Enter the data: ")
# data = '1011001'

# Calculate the no of Redundant Bits Required
m = len(data)
r = calcRedundantBits(m)

# Determine the positions of Redundant Bits
arr = posRedundantBits(data, r)

# Determine the parity bits
arr = calcParityBits(arr, r)

# Data to be transferred
print("Generated Code Word is " + arr)


INTRODUCTION = '''
              \U0001F6E1 Health Insurance Risk Calculator\U0001F6E1
\U0001F534*************************************************************\U0001F534
  Welcome to the Health Insurance Risk Calculator, where we'll
  give you enough information to get an idea of how much you
  owe us. We'll ask a series of basic question about your
  personal information that will determine your risk level
  and whether or not you are insurable.
\U0001F534*************************************************************\U0001F534
'''
print(INTRODUCTION + '\n\n' + 'Questions:')

def ValidNum(Response):
    if Response.isnumeric():
        return True
    else:
        print('This is not a number, try again!')
        return False

def ValidString(Response):
    if Response.isnumeric():
        print('This is a number, try again!')
        return False
    else:
        return True

TotPoints = 0

i = 1
while i < 2:
    i+=1
    UserR = input('\nWhat is your age?\n')
    age = UserR

    if ValidNum(UserR):
        i+=300000
        if int(UserR) < 30 and int(UserR) > 0:
            TotPoints += 0
        elif int(UserR) < 45:
            TotPoints += 10
        elif int(UserR) < 60:
            TotPoints += 20
        else:
            TotPoints += 30
    else:
        i-=1

i=1
while i<2:
    i+-1
    UserR = input('\nWhat is your height? Answer in typical 0\'0\" format.\n')
    UserHeight = UserR

    if UserR.find('\'') == 1 and UserR.endswith('\"'):
        feet = UserR.split('\'')
        ft = feet[0]

        inches = feet[1].split('\"')
        inch = inches[0]

        if ValidNum(ft) and ValidNum(inch):
            if int(ft) > 2 and int(ft) < 9 and int(inch) > -1 and int(inch) < 12:
                height = (float(ft)*12) + float(inch)
                i+=431745817387613
            else:
                print('This is not a valid input, try again!')
                i-=1
        else:
            i-=1
    else:
        print('This is not a valid input, try again!')
        i-=1

BMI = 0
i=1
while i<2:
    i+=1

    weight = input('''\nWhat is your weight in lbs?
(Only write the number, no \"lbs\" following it.)\n''')
    UserWeigth = weight

    if ValidNum(weight):
        if int(weight) > 5 and int(weight) < 750:
            i+=9232798
            BMI = (703.0*float(weight))/(float(height)*float(height))
        else:
            print('This is not a valid weight, try again!')
            i-=1
    else:
        i-=1

if BMI >= 18.5 and BMI <= 24.9:
    TotPoints +=0
elif BMI >= 25 and BMI <= 29.9:
    TotPoints += 30
elif BMI >= 30 and BMI <= 34.9:
    TotPoints += 75

BP = '''
                     ***BLOOD PRESSURE CATEGORIES***

BP Category                   Systopic                        Diastolic
                       | (mm Hg Upper Number) |         | (mm Hg Lower Number)
                       |                      |         |
Normal                 |     Less than 120    |   and   |   Less than 80
                       |                      |         |
Elevated               |       120-129        |   and   |   Less than 80
                       |                      |         |
High BP                |       130-139        |   or    |       80-89
(Hypertension Stage 1) |                      |         |
                       |                      |         |
Hight BP               |    140 or higher     |   or    |   90 or higher
(Hypertension Stage 2) |                      |         |
                       |                      |         |
Hyptensive Crisis      |  Higher than 180     |  and/or |  Higher than 120
'''
print(BP)

i=1
while i<2:
    i+=1
    UserR = input('''\nWhat is your BP, input your answer as normal, elevated,
stage 1, stage 2, or crisis? Select from the chart above.\n''')
    UserBP = UserR

    if ValidString(UserR):
        if str(UserR).lower() == 'normal':
            TotPoints += 0
        elif str(UserR).lower() == 'elevated':
            TotPoints += 15
        elif str(UserR).lower() == 'stage 1':
            TotPoints += 30
        elif str(UserR).lower() == 'stage 2':
            TotPoints += 75
        elif str(UserR).lower() == 'crisis':
            TotPoints += 100
        else:
            i-=1
            print('This is not a valid response, try again!')
    else:
        i-=1

i=1
while i<2:
    i+=1
    UserR = input('\nDoes Diabetes run in your family? Answer with a simple yes or no.\n')
    UserD = 'Does Diabetes run in the family - ' + UserR

    if ValidString(UserR):
        if UserR.lower() == 'yes':
            i+=18971
            TotPoints += 10
        elif UserR.lower() == 'no':
            i+=187237
        else:
            print('That\'s not a \"yes\" or \"no\" answer, try again!')
            i-=1
    else:
        i-=1

i=1
while i<2:
    i+=1
    UserR = input('\nDoes Cancer run in your family? Answer with a simple yes or no.\n')
    UserC = 'Does Cancer run in the family - ' + UserR

    if ValidString(UserR):
        if UserR.lower() == 'yes':
            i+=18971
            TotPoints += 10
        elif UserR.lower() == 'no':
            i+=187237
        else:
            print('That\'s not a \"yes\" or \"no\" answer, try again!')
            i-=1
    else:
        i-=1

i=1
while i<2:
    i+=1
    UserR = input('\nDoes Alzheimer\'s run in your family? Answer with a simple yes or no.\n')
    UserA = 'Does Alzhermer\'s run in the family - ' + UserR

    if ValidString(UserR):
        if UserR.lower() == 'yes':
            i+=18971
            TotPoints += 10
        elif UserR.lower() == 'no':
            i+=187237
        else:
            print('That\'s not a \"yes\" or \"no\" answer, try again!')
            i-=1
    else:
        i-=1

print('''\n***For the following questions you can enter \"done\" to
immediately see you evaluation.***''')

isDone = False

UserR = input('\nIs there anything else you\'d like to tell us about your health?\n')

if UserR.lower() == 'done':
    isDone = True

if not isDone:
    UserR = input('\nHow\'s your day going?\n')
else:
    pass

if UserR.lower() == 'done':
    isDone = True

if not isDone:
    UserR = input('\nDo you have any suggestion for how we can improve?\n')
else:
    pass

print('\nAge: ' + age)
print('Height: ' + UserHeight)
print('Weight: ' + UserWeigth)
print('BMI: ' + str(BMI))
print(UserD)
print(UserC)
print(UserA)

print('\nTotal Risk Score(Higher = Worse): ' + str(TotPoints))
RiskC = ''

if TotPoints <= 20:
    RiskC = 'Low Risk'
elif TotPoints <= 50:
    RiskC = 'Moderate Risk'
elif TotPoints <= 75:
    RiskC = 'High Risk'
else:
    RiskC = 'Unisurable'

print('Your Risk Category: ' + RiskC + '\n')