import argparse

import cv2
import matplotlib.pyplot as plt
import numpy as np
import torch
from torch.nn import functional as F

from experiment_config import ExperimentCfg
from lib import common
from models import environment_model, i2a_model

def get_heatmap(net, state_vec, act):
    # produces a heatmap of a net, when it takes a given action act in the state state_v
    # it returns the heatmap, the probabilities of all actions, as well as the best action for the state_v
    # model_activations = SaveActivations(net.conv)

    logits_action_v, _ = net(state_vec)
    probs_vec = F.softmax(logits_action_v, dim=1)
    probs = probs_vec.data.cpu().numpy()
    best_action = np.argmax(probs)
    logits_action_v[0][
        act].backward()  # TODO: Is this working correctly if multiple backward passes are made from the same network output?
    grad = net.get_activations_gradient()
    pooled_gradients = torch.mean(grad, dim=[0, 2, 3])
    activations = net.get_activations(state_vec).detach()
    for i in range(64):
        activations[:, i, :, :] *= pooled_gradients[i]
    heatmap = torch.mean(activations, dim=1).squeeze()
    heatmap = np.maximum(heatmap, 0)
    heatmap /= torch.max(heatmap)

    return heatmap, probs, best_action

def get_heatmaps_for_all_actions(net, state_vec, actions):
    # 8, 8 is because the gradient shape is 8,8 in the config for grid of 5
    heatmaps = np.ndarray((1, len(actions), 8, 8))
    probabilities = np.ndarray((1, len(actions), 1, 4))
    best_actions = np.ndarray((1, len(actions)))

    for act_idx in range(len(actions)):
        heatmap, probs, best_action = get_heatmap(net, state_vec, actions[act_idx])
        heatmaps[0, act_idx] = heatmap
        probabilities[0, act_idx] = probs
        best_actions[0, act_idx] = best_action

    return heatmaps, probabilities, best_actions

def get_arguments():
    arg_parser = argparse.ArgumentParser()
    arg_parser.add_argument("--SEED", type=int, default=20, help="Random seed to use, default=%d" % 20)
    arg_parser.add_argument("--FORCE_SEED", type=int, default=False, help="force to use SEED")
    arg_parser.add_argument("--CUDA", default=False, action="store_true", help="Enable cuda")
    arg_parser.add_argument("-g", "--GRID_SIZE", type=int, default=5, help="The size of the grid, default=5",
                            required=True)
    arg_parser.add_argument("-f", "--FRAME_SIZE", type=int, default=14,
                            help="resolution of the grid, including the borders", required=True)
    arg_parser.add_argument("-r", "--REPLACEMENT", required=True,
                            help="env with replacement of the squares in back in the grid")
    arg_parser.add_argument("-mode", "--MODE", default="i2a", help="i2a or a2c are possible values")

    # I2A agents with rollout sizes from 1 to 4
    arg_parser.add_argument("-if1", "--I2A_FILE1",
                            default="/home/valy/OneDrive/repos/I2A-all/master/no-repl/5_14/Jan31_17-56-31_valy_i2a_14_5_1_0.0008_0.0001_False/best_0004.000_3250.dat",
                            required=False, help="I2A policy file for rollout size 1")
    arg_parser.add_argument("-if2", "--I2A_FILE2",
                            default="/home/valy/OneDrive/repos/I2A-all/master/no-repl/5_14/Jan31_21-37-42_valy_i2a_14_5_2_0.0008_0.0001_False/best_0004.000_3000.dat",
                            required=False, help="I2A policy file for rollout size 2")
    arg_parser.add_argument("-if3", "--I2A_FILE3",
                            default="/home/valy/OneDrive/repos/I2A-all/master/no-repl/5_14/Jan31_21-37-47_valy_i2a_14_5_3_0.0008_0.0001_False/best_0004.000_4750.dat",
                            required=False, help="I2A policy file for rollout size 3")
    arg_parser.add_argument("-if4", "--I2A_FILE4",
                            default="/home/valy/OneDrive/repos/I2A-all/master/no-repl/5_14/Jan31_20-33-00_valy_i2a_14_5_4_0.0008_0.0001_False/best_0004.000_4000.dat",
                            required=False, help="I2A policy file for rollout size 4")

    # I2A rollout policy files for rollout sizes from 1 to 4
    arg_parser.add_argument("-irp1", "--I2A_RP_FILE1",
                            default="/home/valy/OneDrive/repos/I2A-all/master/no-repl/5_14/Jan31_17-56-31_valy_i2a_14_5_1_0.0008_0.0001_False/best_0004.000_3250.dat.policy",
                            required=False, help="I2A Rollout policy file for rollout size 1")
    arg_parser.add_argument("-irp2", "--I2A_RP_FILE2",
                            default="/home/valy/OneDrive/repos/I2A-all/master/no-repl/5_14/Jan31_21-37-42_valy_i2a_14_5_2_0.0008_0.0001_False/best_0004.000_3000.dat.policy",
                            required=False, help="I2A Rollout policy file for rollout size 2")
    arg_parser.add_argument("-irp3", "--I2A_RP_FILE3",
                            default="/home/valy/OneDrive/repos/I2A-all/master/no-repl/5_14/Jan31_21-37-47_valy_i2a_14_5_3_0.0008_0.0001_False/best_0004.000_4750.dat.policy",
                            required=False, help="I2A Rollout policy file for rollout size 3")
    arg_parser.add_argument("-irp4", "--I2A_RP_FILE4",
                            default="/home/valy/OneDrive/repos/I2A-all/master/no-repl/5_14/Jan31_20-33-00_valy_i2a_14_5_4_0.0008_0.0001_False/best_0004.000_4000.dat.policy",
                            required=False, help="I2A Rollout policy file for rollout size 4")

    arg_parser.add_argument("-a", "--A2C_FILE", default="/home/valy/OneDrive/repos/I2A-all/master/no-repl/5_14/Jan31_15-57-28_valy_a2c_14_5_0.0008_0.0001_False/best_0004.000_6000.dat", required=False, help="A2C file used to train the EM")
    arg_parser.add_argument("-ef", "--EM_FILE",
                            default="/home/valy/OneDrive/repos/I2A-all/master/no-repl/5_14/Jan31_16-40-11_valy_em_14_5_0.0008_0.0001_False/best_9.1968e-08_223449.dat", required=False,
                            help="Env Model File")
    arg_parser.add_argument("-lr", required=True, type=float, help="learning rate")

    return arg_parser

def build_a2c_nets_from_files(cfg, use_grad_cam=True):
    net_files = [cfg.I2A_RP_FN1, cfg.I2A_RP_FN2, cfg.I2A_RP_FN3, cfg.I2A_RP_FN4]
    nets = []

    for file in range(4):
        net = common.getNet(cfg)
        net.load_state_dict(torch.load(net_files[file], map_location=lambda storage, loc: storage))
        net.eval()
        net.grad_cam = use_grad_cam
        nets.append(net)

    return nets

def build_a2c_net_from_file(cfg, use_grad_cam=True):
    net_file = cfg.A2C_FN
    net = common.getNet(cfg)
    net.load_state_dict(torch.load(net_file, map_location=lambda storage, loc: storage))
    net.eval()
    net.grad_cam = use_grad_cam

    return net

def build_i2a_nets_from_file(cfg, net_env_model, i2a_rp, use_grad_cam=True):
    net_files = [cfg.I2A_FN1, cfg.I2A_FN2, cfg.I2A_FN3, cfg.I2A_FN4]
    nets = []

    for file in range(len(net_files)):
        i2a = i2a_model.I2A(cfg.OBS_SHAPE, cfg.ACT_N, net_env_model, i2a_rp[file], cfg).to(cfg.DEVICE)
        i2a.load_state_dict(torch.load(net_files[file], map_location=lambda storage, loc: storage))
        i2a.eval()
        i2a.grad_cam = use_grad_cam
        nets.append(i2a)

    return nets

def build_em_net_from_file(cfg):
    net_env_model = environment_model.EnvironmentModel(cfg.OBS_SHAPE, cfg.ACT_N, cfg)
    net_env_model.load_state_dict(torch.load(cfg.EM_FN, map_location=lambda storage, loc: storage))
    net_env_model = net_env_model.to(cfg.DEVICE)
    net_env_model.eval()

    return net_env_model

def init_cfg_and_env():
    # parses command line arguments and build an ExperimentCfg object to contain them
    prs = get_arguments()
    cfg = ExperimentCfg()

    cfg.make_grad_cam_config(prs)

    environment = common.makeCustomizedGridEnv(cfg)
    obs_shape = environment.observation_space.shape
    act_n = environment.action_space.n
    cfg.OBS_SHAPE = obs_shape
    cfg.ACT_N = act_n

    return prs, cfg, environment

def get_heatmaps(nets, state_vec):
    acts = [0, 1, 2, 3]
    heatmaps = np.ndarray((len(nets), len(acts), 8, 8))
    probs_vec = np.ndarray((len(nets), len(acts), 1, 4))
    best_actions = np.ndarray((len(nets), len(acts)))

    # get a heatmap for every net, for every action in a given state
    for net_idx in range(len(nets)):
        for act_to_execute in range(len(acts)):
            heatmap, probs, best_action = get_heatmap(nets[net_idx], state_vec, act_to_execute)
            heatmaps[net_idx, act_to_execute] = heatmap
            probs_vec[net_idx, act_to_execute] = probs
            best_actions[net_idx, act_to_execute] = best_action

    return heatmaps, probs_vec, best_actions

if __name__ == "__main__":

    # initialize all configuration from arguments, and initialize environment
    parser, config, env = init_cfg_and_env()

    # load A2C net from file and set grad cam to True, so we can access fw pass activations and backward pass gradients
    net_a2c = build_a2c_net_from_file(config)

    # load environment network from file
    net_em = build_em_net_from_file(config)

    # load from files the rollout policy nets used by the I2A agents
    nets_i2a_rp = build_a2c_nets_from_files(config)

    # load from file the I2A agents with different rollout sizes
    nets_i2a = build_i2a_nets_from_file(config, net_em, nets_i2a_rp)

    state = env.reset()
    action_label = ["Up", "Down", "Left", "Right"]
    actions = [0, 1, 2, 3]

    while 1 == 1:
        state_v = torch.tensor(np.array([state], copy=False)).to(config.DEVICE)

        # get heatmap for the a2c net, for all actions
        heatmaps_a2c, probs_a2c, actions_a2c = get_heatmaps_for_all_actions(net_a2c, state_v, actions)
        heatmaps_i2a, probs_i2a, actions_i2a = get_heatmaps(nets_i2a, state_v)

        fig, axes = plt.subplots(5, 6, figsize=(10, 4))
        # print(action_label[act], probs_a2c.squeeze()[act])
        # print(heatmap_a2c.squeeze())
        stateImg = np.moveaxis(env.renderEnv(), 0, -1)

        # show the current state in the first column of every row
        [axes[x, 0].imshow(stateImg, interpolation="nearest") for x in range(5)]

        # for every i2a net with different rollout sizes (1 to 4), for every row, we display the heatmap for all
        # actions (1:4). first column is already occupied with displaying the current state. also, the first row
        # shows heatmaps for the baseline A2C net, for all actions
        for i2a_net_idx in range(4):
            for act in range(len(actions)):
                heatmap_i2a = cv2.resize(heatmaps_i2a[i2a_net_idx, act],
                                         (config.FRAME_SIZE, config.FRAME_SIZE),
                                         interpolation=cv2.INTER_NEAREST)
                heatmap_i2a = np.uint8(255 * heatmap_i2a)
                heatmap_i2a = cv2.applyColorMap(heatmap_i2a, cv2.COLORMAP_JET)
                superimposed_img = heatmap_i2a * 0.2 + stateImg
                cv2.imwrite(f"./map{i2a_net_idx}_{act}.jpg", superimposed_img)
                img = cv2.imread(f"./map{i2a_net_idx}_{act}.jpg")
                axes[i2a_net_idx+1, act+1].imshow(img)

        # show heatmaps for A2C agent for every action, in the first row
        for act in range(len(actions)):
            heatmap_a2c = cv2.resize(heatmaps_a2c[0, act],
                                     (config.FRAME_SIZE, config.FRAME_SIZE),
                                     interpolation=cv2.INTER_NEAREST)
            heatmap_a2c = np.uint8(255 * heatmap_a2c)
            heatmap_a2c = cv2.applyColorMap(heatmap_a2c, cv2.COLORMAP_JET)
            superimposed_img = heatmap_a2c * 0.2 + stateImg
            cv2.imwrite(f"./map{act}.jpg", superimposed_img)
            img = cv2.imread(f"./map{act}.jpg")
            axes[0, act+1].imshow(img)

        # show the axes labels

        plt.show()

        a = int(input())
        state, done, _, _ = env.step(a)
        if done:
            state, done, _ = env.reset()
        if a == 7:
            break


"""
Set up client keyring
"""
import logging

from teuthology import misc as teuthology
from teuthology.orchestra import run
from ceph_manager import write_conf

log = logging.getLogger(__name__)

def create_keyring(ctx, cluster_name):
    """
    Create key ring on remote client
    """
    log.info('Create client keyring...')
    #clients = ctx.cluster.only(teuthology.is_type('client', cluster_name))
    #testdir = teuthology.get_testdir(ctx)
    for role in ctx.config.get('roles'):
        for remote in teuthology.get_clients(ctx,role):
            client_keyring = "/etc/ceph/xtao-client.{id}.keyring".format(id=remote[0])
            remote[1].run(
                args=[
                    'ceph',
                    'auth',
                    'get-or-create',
                    'client.{id}'.format(id=remote[0]),
                    'mon',
                    'allow rwx',
                    'mds',
                    'allow *',
                    'osd',
                    'allow *',
                    '-o',
                    client_keyring,
                    '--cluster',
                    cluster_name,
               ]
            )
            write_conf(ctx,'client.{id}'.format(id=remote[0]),'keyring',write_value=client_keyring,write_add=True)

# Liyan add this function
def clear_keyring(ctx,cluster_name):
    """
    Clear key ring on remote client
    """
    log.info('Clear client keyring...')
    for role in ctx.config.get('roles'):
        for remote in teuthology.get_clients(ctx,role):
            client_keyring = "/etc/ceph/xtao-client.{id}.keyring".format(id=remote[0])
            remote[1].run(
                'ceph',
                'auth',
                'del',
                'client.{id}'.format(id=remote[0]),
                '--cluster',
                cluster_name,
            )
            write_conf(ctx,'client.{id}'.format(id=remote[0]),'keyring',write_add=False)
            remote[1].run(
                args=[
                    'rm',
                    '-rf',
                    client_keyring,
                ]
            )


import os
import re
from typing import Mapping, MutableMapping, NamedTuple, Optional, Sequence, Tuple

from fs.base import FS

import simfile
from .types import Simfile
from ._private import extensions
from ._private.nativeosfs import NativeOSFS
from ._private.path import FSPath

__all__ = ["Assets"]

class AssetDefinition(NamedTuple):
    presets: Sequence[str] = ()
    extensions: Sequence[str] = ()
    match_by_extension: bool = False

    def matches(self, path: str) -> bool:
        root, _ = os.path.splitext(path)
        if any(re.search(preset, root.lower()) for preset in self.presets):
            return True
        if self.match_by_extension and extensions.match(path, *self.extensions):
            return True
        return False

ASSET_DEFINITIONS: Mapping[str, AssetDefinition] = {
    "BANNER": AssetDefinition(
        extensions=extensions.IMAGE,
        # NOTE: according to StepMania's source code, the end pattern should be
        # " bn" with a space, not "bn". But it matches "bn.png" and I don't
        # know why, so I'm changing it to reflect the observed behavior.
        presets=["banner", "bn$"],
    ),
    "BACKGROUND": AssetDefinition(
        extensions=extensions.IMAGE,
        presets=["background", "bg$"],
    ),
    "CDTITLE": AssetDefinition(
        extensions=extensions.IMAGE,
        presets=["cdtitle"],
    ),
    "JACKET": AssetDefinition(
        extensions=extensions.IMAGE,
        presets=["^jk_", "jacket", "albumart"],
    ),
    "CDIMAGE": AssetDefinition(
        extensions=extensions.IMAGE,
        presets=["-cd$"],
    ),
    "DISC": AssetDefinition(
        extensions=extensions.IMAGE,
        presets=[" disc$", " title$"],
    ),
    "MUSIC": AssetDefinition(
        extensions=extensions.AUDIO,
        match_by_extension=True,
    ),
}

class Assets:
    """
    Asset loader for a simfile directory.

    This loader uses the same heuristics as StepMania to determine a
    default path for assets not specified in the simfile. For example, if
    the BACKGROUND property is missing or blank, StepMania will look for an
    image whose filename contains "background" or ends with "bg".

    The simfile will be loaded from the :code:`simfile_dir` unless an
    explicit :code:`simfile` argument is supplied. This is intended mostly
    as an optimization for when the simfile has already been loaded from
    disk.

    All asset paths are absolute and normalized. Keyword arguments are
    passed down to :func:`simfile.open` (and are only valid if
    :code:`simfile` is not provided).
    """

    @property
    def music(self):
        return self._asset_property("MUSIC")

    @property
    def banner(self):
        return self._asset_property("BANNER")

    @property
    def background(self):
        return self._asset_property("BACKGROUND")

    @property
    def cdtitle(self):
        return self._asset_property("CDTITLE")

    @property
    def jacket(self):
        return self._asset_property("JACKET")

    @property
    def cdimage(self):
        return self._asset_property("CDIMAGE")

    @property
    def disc(self):
        return self._asset_property("DISC")

    def __init__(
        self,
        simfile_dir: str,
        *,
        simfile: Optional[Simfile] = None,
        filesystem: FS = NativeOSFS(),
        **kwargs,
    ):
        if simfile and kwargs:
            raise TypeError(
                "Assets can't take both a simfile and kwargs (kwargs are only "
                "useful if no explicit simfile is provided)"
            )
        self.simfile_dir = simfile_dir
        self.filesystem = filesystem
        self._dirlist = self.filesystem.listdir(simfile_dir)
        self._cache: MutableMapping[str, Optional[str]] = {}
        self._path = FSPath(filesystem)

        if simfile:
            self.simfile = simfile
        else:
            from simfile.dir import SimfileDirectory

            self.simfile = SimfileDirectory(
                simfile_dir,
                filesystem=filesystem,
            ).open(**kwargs)

    def _get_case_insensitive_path(self, path: str) -> Optional[str]:
        containing_dir, filename = self._path.split(path)
        filename_lower = filename.lower()

        if self.filesystem.isdir(containing_dir):
            for item in self.filesystem.listdir(containing_dir):
                if item.lower() == filename_lower:
                    return self._path.join(containing_dir, item)

    def _asset_property(self: "Assets", prop: str) -> Optional[str]:
        if prop in self._cache:
            return self._cache[prop]

        specified_path = self.simfile.get(prop)
        if specified_path:
            full_path = self._path.join(self.simfile_dir, specified_path)
            case_insensitive_path = self._get_case_insensitive_path(full_path)
            if case_insensitive_path:
                return self._cache_path(prop, case_insensitive_path, absolute=True)

        asset_definition = ASSET_DEFINITIONS[prop]
        for file_in_simfile_dir in self._dirlist:
            if asset_definition.matches(file_in_simfile_dir):
                return self._cache_path(prop, file_in_simfile_dir)

        return self._cache_path(prop, None)

    def _cache_path(
        self, key: str, value: Optional[str], *, absolute: bool = False
    ) -> Optional[str]:
        if value is not None:
            if absolute:
                self._cache[key] = self._path.normpath(value)
            else:
                self._cache[key] = self._path.normpath(
                    self._path.join(self.simfile_dir, value),
                )
        else:
            self._cache[key] = None
        return self._cache[key]


from keras.layers import Dense, Flatten, Dropout, ZeroPadding3D
from keras.layers.recurrent import LSTM
from keras.models import Sequential, load_model
from keras.optimizers import Adam, RMSprop
from keras.layers.wrappers import TimeDistributed
from keras.layers.convolutional import (Conv2D, MaxPooling3D, Conv3D,MaxPooling2D)
from collections import deque
import sys

class ResearchModels():
    def __init__(self, nb_classes, seq_length, input_shape,
                 saved_model=None, features_length=2048):

        # Set defaults.
        self.seq_length = seq_length
        self.load_model = load_model
        self.saved_model = saved_model
        self.nb_classes = nb_classes
        self.feature_queue = deque()
        self.input_shape = input_shape

    def lstm(self):
        """Build a simple LSTM network. We pass the extracted features from
        our CNN to this model predomenently."""
        # Model.
	    #print(self.input_shape)
        model = Sequential()
        model.add(LSTM(2048, return_sequences=True, input_shape=self.input_shape,dropout=0.5))
        model.add(Flatten())
        model.add(Dense(1024, activation='relu'))
        model.add(Dense(512, activation='relu'))
        model.add(Dropout(0.5))
        model.add(Dense(self.nb_classes, activation='softmax'))
        return model

    def trainingModel(self, input_shape):
        metrics = ['accuracy']
        self.input_shape = input_shape
        self.model = self.lstm()
        # Now compile the network.
        optimizer = Adam(lr=0.00005)
        self.model.compile(loss='categorical_crossentropy', optimizer=optimizer,
                           metrics=metrics)
        print(self.model.summary())

    def loadModelFromPath(self, weight_path):
        model = self.lstm()
        model.load_weights(weight_path)
        return model


from app.controllers.base_controller import BaseController
from app.models.base_model import BaseModel
from app.services import spotservice

class SpotController(BaseController):

	@staticmethod
	def index():
		spots = spotservice.get()
		return BaseController.send_response_api(BaseModel.as_list(spots), 'spots retrieved successfully')

	@staticmethod
	def update(request, id):
		beacon_id = request.json['beacon_id'] if 'beacon_id' in request.json else None
		stage_id = request.json['stage_id'] if 'stage_id' in request.json else None

		payloads = {
			'beacon_id': beacon_id,
			'stage_id': stage_id,
		}

		result = spotservice.update(payloads, id)

		if not result['error']:
			return BaseController.send_response_api(result['data'], 'spot succesfully updated')
		else:
			return BaseController.send_error_api(None, result['data'])


import os.path
import pathlib
import logging
import gi

gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, GdkPixbuf, GObject, Pango, Gdk
from ks_includes.screen_panel import ScreenPanel
from ks_includes.KlippyRest import KlippyRest
from datetime import datetime

try:
    from zoneinfo import ZoneInfo
except ImportError:
    from backports.zoneinfo import ZoneInfo

def format_date(date):
    try:
        return datetime.strptime(date, '%Y-%m-%dT%H:%M:%S.%f').replace(tzinfo=ZoneInfo('UTC'))
    except ValueError:
        try:
            return datetime.strptime(date, '%Y-%m-%dT%H:%M:%S').replace(tzinfo=ZoneInfo('UTC'))
        except ValueError:
            return None

class SpoolmanVendor:
    id: int
    name: str
    registered: datetime = None

    def __init__(self, **entries):
        self.__dict__.update(entries)
        for date in ["registered"]:
            if date in entries:
                self.__setattr__(date, format_date(entries[date]))

class SpoolmanFilament:
    article_number: str
    color_hex: str
    comment: str
    density: float
    diameter: float
    id: int
    material: str
    name: str
    price: float
    registered: datetime = None
    settings_bed_temp: int
    settings_extruder_temp: int
    spool_weight: float
    vendor: SpoolmanVendor = None
    weight: float

    def __init__(self, **entries):
        self.__dict__.update(entries)
        if "vendor" in entries:
            self.vendor = SpoolmanVendor(**(entries["vendor"]))
        for date in ["registered"]:
            if date in entries:
                self.__setattr__(date, format_date(entries[date]))

class SpoolmanSpool(GObject.GObject):
    archived: bool
    id: int
    remaining_length: float
    remaining_weight: float
    used_length: float
    used_weight: float
    lot_nr: str
    filament: SpoolmanFilament = None
    first_used: datetime = None
    last_used: datetime = None
    registered: datetime = None
    _icon: Gtk.Image = None
    theme_path: str = None
    _spool_icon: str = None

    def __init__(self, **entries):
        GObject.GObject.__init__(self)
        self.__dict__.update(entries)
        if "filament" in entries:
            self.filament = SpoolmanFilament(**(entries["filament"]))
        for date in ["first_used", "last_used", "registered"]:
            if date in entries:
                self.__setattr__(date, format_date(entries[date]))

    @property
    def name(self):
        result = self.filament.name
        if self.filament.vendor:
            result = " ".join([self.filament.vendor.name, "-", result])
        return result

    @property
    def icon(self):
        if self._icon is None:
            if SpoolmanSpool._spool_icon is None:
                klipperscreendir = pathlib.Path(__file__).parent.resolve().parent
                _spool_icon_path = os.path.join(
                    klipperscreendir, "styles", SpoolmanSpool.theme_path, "images", "spool.svg"
                )
                if not os.path.isfile(_spool_icon_path):
                    _spool_icon_path = os.path.join(klipperscreendir, "styles", "spool.svg")
                SpoolmanSpool._spool_icon = pathlib.Path(_spool_icon_path).read_text()

            loader = GdkPixbuf.PixbufLoader()
            color = self.filament.color_hex if hasattr(self.filament, 'color_hex') else '000000'
            loader.write(
                SpoolmanSpool._spool_icon.replace('var(--filament-color)', f'#{color}').encode()
            )
            loader.close()
            self._icon = loader.get_pixbuf()
        return self._icon

class Panel(ScreenPanel):
    apiClient: KlippyRest
    _active_spool_id: int = None

    @staticmethod
    def spool_compare_id(model, row1, row2, user_data):
        spool1 = model.get_value(row1, 0)
        spool2 = model.get_value(row2, 0)
        return spool1.id - spool2.id

    @staticmethod
    def spool_compare_date(model, row1, row2, user_data):
        spool1 = model.get_value(row1, 0)
        spool2 = model.get_value(row2, 0)
        return 1 if (spool1.last_used or datetime.min).replace(tzinfo=None) > \
                    (spool2.last_used or datetime.min).replace(tzinfo=None) else -1

    def _on_material_filter_clear(self, sender, combobox):
        self._filters["material"] = None
        self._filterable.refilter()
        self._filter_expander.set_expanded(False)
        combobox.set_active_iter(self._materials.get_iter_first())

    def _on_material_filter_changed(self, sender):
        treeiter = sender.get_active_iter()
        if treeiter is not None:
            model = sender.get_model()
            self._filters["material"] = model[treeiter][0]
            self._filterable.refilter()

    def __init__(self, screen, title):
        super().__init__(screen, title)
        self.apiClient = screen.apiclient
        if self._config.get_main_config().getboolean("24htime", True):
            self.timeFormat = '%Y-%m-%d %H:%M'
        else:
            self.timeFormat = '%Y-%m-%d %I:%M %p'

        SpoolmanSpool.theme_path = screen.theme
        GObject.type_register(SpoolmanSpool)
        self._filters = {}
        self._model = Gtk.TreeStore(SpoolmanSpool.__gtype__)
        self._materials = Gtk.ListStore(str, str)

        self._filterable = self._model.filter_new()
        self._filterable.set_visible_func(self._filter_spools)

        sortable = Gtk.TreeModelSort(self._filterable)
        sortable.set_sort_func(0, self.spool_compare_id)
        sortable.set_sort_func(1, self.spool_compare_date)

        self.scroll = self._gtk.ScrolledWindow()
        if self._screen.vertical_mode:
            self.scroll.set_property("overlay-scrolling", True)
        else:
            self.scroll.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)

        sbox = Gtk.Box(spacing=0)
        sbox.set_vexpand(False)

        clear_active_spool = self._gtk.Button("cancel", _("Clear"), "color2", self.bts, Gtk.PositionType.LEFT, 1)
        clear_active_spool.get_style_context().add_class("buttons_slim")
        clear_active_spool.connect('clicked', self.clear_active_spool)

        refresh = self._gtk.Button("refresh", style="color1", scale=.66)
        refresh.get_style_context().add_class("buttons_slim")
        refresh.connect('clicked', self.load_spools)

        sort_btn_id = self._gtk.Button(None, _("ID"), "color4", self.bts, Gtk.PositionType.RIGHT, 1)
        sort_btn_id.connect("clicked", self.change_sort, "id")
        sort_btn_id.get_style_context().add_class("buttons_slim")

        sort_btn_used = self._gtk.Button(None, _("Last Used"), "color3", self.bts, Gtk.PositionType.RIGHT, 1)
        sort_btn_used.connect("clicked", self.change_sort, "last_used")
        sort_btn_used.get_style_context().add_class("buttons_slim")

        switch = Gtk.Switch()
        switch.set_hexpand(False)
        switch.set_vexpand(False)
        switch.set_active(self._config.get_config().getboolean("spoolman", "hide_archived", fallback=True))
        switch.connect("notify::active", self.switch_config_option, "spoolman", "hide_archived", self.load_spools)

        name = Gtk.Label()
        name.set_markup(_("Archived"))
        name.set_halign(Gtk.Align.START)
        name.set_valign(Gtk.Align.CENTER)
        name.set_line_wrap(True)
        name.set_line_wrap_mode(Pango.WrapMode.WORD_CHAR)

        archived = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
        archived.set_valign(Gtk.Align.CENTER)
        archived.add(name)
        archived.add(switch)

        sbox.pack_start(sort_btn_id, True, True, 0)
        sbox.pack_start(sort_btn_used, True, True, 0)
        sbox.pack_start(clear_active_spool, True, True, 0)
        sbox.pack_start(refresh, True, True, 0)
        sbox.pack_start(archived, False, False, 5)
        sbox.set_hexpand(True)
        sbox.set_vexpand(False)

        filter_box = Gtk.ListBox()
        filter_box.set_selection_mode(Gtk.SelectionMode.NONE)
        self._filter_expander = Gtk.Expander(label=_("Filter"))
        self._filter_expander.add(filter_box)

        row = Gtk.ListBoxRow()
        hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=5)
        row.add(hbox)

        label = Gtk.Label(_("Material"))
        _material_filter = Gtk.ComboBox.new_with_model(self._materials)
        _material_filter.connect("changed", self._on_material_filter_changed)
        cellrenderertext = Gtk.CellRendererText()
        _material_filter.pack_start(cellrenderertext, True)
        _material_filter.add_attribute(cellrenderertext, "text", 1)
        _material_filter.set_hexpand(True)

        _material_reset_filter = self._gtk.Button("cancel", _("Clear"), "color2", self.bts, Gtk.PositionType.LEFT, 1)
        _material_reset_filter.get_style_context().add_class("buttons_slim")
        _material_reset_filter.connect('clicked', self._on_material_filter_clear, _material_filter)

        hbox.pack_start(label, False, True, 0)
        hbox.pack_start(_material_filter, True, True, 0)
        hbox.pack_end(_material_reset_filter, False, True, 0)

        filter_box.add(row)

        self.main = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0)
        self.main.set_vexpand(True)
        self.main.pack_start(sbox, False, False, 0)
        self.main.pack_start(self._filter_expander, False, True, 0)
        self.main.pack_start(self.scroll, True, True, 0)

        self.load_spools()
        self.get_active_spool()
        self._treeview = Gtk.TreeView(model=sortable)
        self._treeview.set_headers_visible(False)
        self._treeview.set_show_expanders(False)

        text_renderer = Gtk.CellRendererText()
        pixbuf_renderer = Gtk.CellRendererPixbuf()
        pixbuf_renderer.set_padding(5, 5)
        checkbox_renderer = Gtk.CellRendererToggle()
        column_id = Gtk.TreeViewColumn(cell_renderer=text_renderer)
        column_id.set_cell_data_func(
            text_renderer,
            lambda column, cell, model, it, data:
            self._set_cell_background(cell, model.get_value(it, 0)) and
            cell.set_property('text', f'{model.get_value(it, 0).id}')
        )
        column_id.set_sort_column_id(0)

        column_icon = Gtk.TreeViewColumn(cell_renderer=pixbuf_renderer)
        column_icon.set_cell_data_func(
            pixbuf_renderer,
            lambda column, cell, model, it, data:
            self._set_cell_background(cell, model.get_value(it, 0)) and
            cell.set_property('pixbuf', model.get_value(it, 0).icon)
        )

        column_spool = Gtk.TreeViewColumn(cell_renderer=text_renderer)
        column_spool.set_expand(True)
        column_spool.set_cell_data_func(
            text_renderer,
            lambda column, cell, model, it, data:
            self._set_cell_background(cell, model.get_value(it, 0)) and
            cell.set_property('markup', self._get_filament_formated(model.get_value(it, 0)))
        )

        column_last_used = Gtk.TreeViewColumn(cell_renderer=text_renderer)
        column_last_used.set_visible(False)
        column_last_used.set_sort_column_id(1)

        column_material = Gtk.TreeViewColumn(cell_renderer=text_renderer)
        column_material.set_cell_data_func(
            text_renderer,
            lambda column, cell, model, it, data:
            self._set_cell_background(cell, model.get_value(it, 0)) and
            cell.set_property('text', model.get_value(it, 0).filament.material)
        )

        checkbox_renderer.connect("toggled", self._set_active_spool)
        column_toggle_active_spool = Gtk.TreeViewColumn(cell_renderer=checkbox_renderer)
        column_toggle_active_spool.set_cell_data_func(
            checkbox_renderer,
            lambda column, cell, model, it, data:
            self._set_cell_background(cell, model.get_value(it, 0)) and
            cell.set_property('active', model.get_value(it, 0).id == self._active_spool_id)
        )

        self._treeview.append_column(column_id)
        self._treeview.append_column(column_icon)
        self._treeview.append_column(column_spool)
        self._treeview.append_column(column_last_used)
        self._treeview.append_column(column_material)
        self._treeview.append_column(column_toggle_active_spool)

        self.current_sort_widget = sort_btn_id
        sort_btn_used.clicked()

        self.scroll.add(self._treeview)
        self.content.add(self.main)

    def _filter_spools(self, model, i, data):
        spool: SpoolmanSpool = model[i][0]
        matches = True
        if ("material" in self._filters) and (self._filters["material"] is not None):
            matches &= spool.filament.material == self._filters["material"]
        return matches

    def _set_cell_background(self, cell, spool: SpoolmanSpool):
        cell.set_property('cell-background-rgba', Gdk.RGBA(1, 1, 1, .1) if spool.id == self._active_spool_id else None)
        return True

    def _get_filament_formated(self, spool: SpoolmanSpool):
        if spool.id == self._active_spool_id:
            result = f'<big>{spool.name}</big>\n'
        else:
            result = f'<big>{spool.name}</big>\n'
        if spool.last_used:
            result += f'{_("Last used")}: {spool.last_used.astimezone():{self.timeFormat}}\n'
        if hasattr(spool, "remaining_weight"):
            result += f'{_("Remaining weight")}: {round(spool.remaining_weight, 2)} g\n'
        if hasattr(spool, "remaining_length"):
            result += f'{_("Remaining length")}: {round(spool.remaining_length / 1000, 2)} m\n'

        return result.strip()

    def _set_active_spool(self, sender, path):
        model = self._treeview.get_model()
        it = model.get_iter(path)
        spool = model.get_value(it, 0)
        if spool.id == self._active_spool_id:
            self.clear_active_spool()
        else:
            self.set_active_spool(spool)

    def change_sort(self, widget, sort_type):
        self.current_sort_widget.set_image(None)
        self.current_sort_widget = widget
        if sort_type == "id":
            logging.info("Sorting by ID")
            column = 0
        elif sort_type == "last_used":
            logging.info("Sorting by Last Used")
            column = 1
        else:
            logging.error("Unknown sort type")
            return
        if self._treeview.get_column(column).get_sort_order() == Gtk.SortType.DESCENDING:
            new_sort_order = Gtk.SortType.ASCENDING
        else:
            new_sort_order = Gtk.SortType.DESCENDING
        self._treeview.get_column(column).set_sort_order(new_sort_order)
        self._treeview.get_model().set_sort_column_id(column, new_sort_order)
        icon = "arrow-down" if new_sort_order == Gtk.SortType.DESCENDING else "arrow-up"
        widget.set_image(self._gtk.Image(icon, self._gtk.img_scale * self.bts))

    def process_update(self, action, data):
        if action == "notify_active_spool_set":
            self._active_spool_id = data['spool_id']
            self._treeview.get_model().foreach(lambda store, treepath, treeiter:
                                               store.row_changed(treepath, treeiter)
                                               )
            self._treeview.queue_draw()

    def load_spools(self, data=None):
        hide_archived = self._config.get_config().getboolean("spoolman", "hide_archived", fallback=True)
        self._model.clear()
        self._materials.clear()
        spools = self.apiClient.post_request("server/spoolman/proxy", json={
            "request_method": "GET",
            "path": f"/v1/spool?allow_archived={not hide_archived}",
        })
        if not spools or "result" not in spools:
            self._screen.show_error_modal("Exception when trying to fetch spools")
            return

        materials = []
        for spool in spools["result"]:
            spoolObject = SpoolmanSpool(**spool)
            self._model.append(None, [spoolObject])
            if not hasattr(spoolObject.filament, 'material'):
                spoolObject.filament.material = ''
            elif spoolObject.filament.material not in materials:
                materials.append(spoolObject.filament.material)

        materials.sort()
        self._materials.append([None, _("All")])
        for material in materials:
            self._materials.append([material, material])

    def clear_active_spool(self, sender: Gtk.Button = None):
        result = self.apiClient.post_request("server/spoolman/spool_id", json={})
        if not result:
            self._screen.show_error_modal("Exception when setting active spool")
            return

    def set_active_spool(self, spool: SpoolmanSpool):
        result = self.apiClient.post_request("server/spoolman/spool_id", json={
            "spool_id": spool.id
        })
        if not result:
            self._screen.show_error_modal("Exception when setting active spool")
            return

    def get_active_spool(self) -> SpoolmanSpool:
        result = self.apiClient.send_request("server/spoolman/spool_id")
        if not result:
            self._screen.show_error_modal("Exception when getting active spool")
            return
        self._active_spool_id = result["result"]["spool_id"]
        return self._active_spool_id


# Stone, Paper, Sissors Game in Python...

import random

def gamewin(comp , you):
    if comp == "Stone":
        if you == "Paper":
            return True
        elif you == "Sisor":
            return False
    elif comp == "Paper":
        if you == "Sissor":
            return True
        elif you == "Stone":
            return  False
    elif comp == "Sissor":
        if you == "Stone":
            return True
        elif you == "Paper":
            return False

print("comp will chose from Stone(S) , Paper(P) and Sissors(R)" )
randNo = random.randint(1,3)

if randNo == 1:
    comp = "Stone"
elif randNo == 2:
    comp = "Paper"
else:
    comp = "Sissor"

you = input("Choose a sing from Stone(S) , Paper(p) and Sissors(R)")
a = gamewin(comp , you)

print(f"The computer choosed : {comp}")
print(f"You choosed : {you}")

if comp == you:
    print("the game is a tie")
elif a:
    print("You win")
else:
    print("you loose")
gamewin(comp , you)


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

# Программа для скачивания пакетов из yum-репозитория с определенными в конфиге условиями.
#
# Имена репозиториев, имена пакетов для каждого из репозиториев и набор версий для каждого из этих
# пакетов образуют нагруженное множесто repo_name_ver.
# Внутреннеее нагруженное множество в виде отношения имен пакетов к набору версий для каждого пакета,
# является нагрузкой к множеству репозиториев.

import glob
import json
import os
import shutil
import sys
import yum
import subprocess
from distutils.version import LooseVersion

# Имя конфига.
config = "/etc/rpm-gpg-repository-mirroring.conf"

# Получить словарь репозиторий->версия из конфига для условия, которое отсекает работу с версиями
# ниже чем в данной настройке.
def get_dict_repo(config):
	with open(config, "r") as f:
		for line in f:
			if "REPOS" in line:
				fields = line.strip().split("=")
				dict_repo=json.loads(fields[1])
				return dict_repo

# Получить дополнительное ограничение к условию выше:
# работать только с пакетами по истории не старше чем с глубиной,
# определяемой в словаре имемя_пакета->глубина_версии.
def get_dict_cut(config):
	with open(config, "r") as f:
		for line in f:
			if "CUT_AFTER" in line:
				fields = line.strip().split("=")
				name_count=json.loads(fields[1])
				return name_count

# Получить ограничение по количеству свежих версий в рамках всех пакетов репозитория.
# Действует для отдельного специального набора репозиторев,
# в которых не применяются два правила выше.
# репозиторий->глубина
def get_name_uni_count(config):
	with open(config, "r") as f:
		for line in f:
			if "NUMBER_PACKAGE_IN_REPO" in line:
				fields = line.strip().split("=")
				name_uni_count=json.loads(fields[1])
				return name_uni_count

# Объемлющий каталог для хранения скачиваемого.
def get_download_dir(config):
	with open(config) as f:
		for line in f:
			if "DOWNLOAD_DIR" in line:
				fields = line.strip().split("=")
				dir=fields[1]
				return dir

# Отдельная функция для записи файлов.
# Получает pkg и repo, которые нужно сохранять.
# TODO: repo вероятно излишен и может быть получен другим путём.
def save_po(pkg, repo):
	# Подготовка пути для сохранения.
	remote = pkg.returnSimple('relativepath')
	local = os.path.basename(remote)
	# Скачка в темповую директорию	- без этого хака лезла ошибка..
	local_wp = os.path.join(tmp, local)
	# Настройка yum-api для скачки.
	pkg.localpath = local_wp
	# Проверка существования файла, чтобы не качать снова.
	if os.path.isfile(download_dir + '/' + repo + '/' + str(pkg) + '.rpm'):
		return
	# Получение-скачивание необходимого пакета через yum-api.
	path = pkg.repo.getPackage(pkg, copy_local=1, cache = False)
	# Перемещение его из темповой директории.
	shutil.move(os.path.join(tmp, local), os.path.join(download_dir + '/' + repo, str(pkg) + '.rpm'))

# Причваение настроек в конфиге и инициализация глобального словаря.
name_count = get_dict_cut(config)
repo_name_ver = {}
repo_ver = get_dict_repo(config)
download_dir = get_download_dir(config)

# В этом цикле, часть логики совпадает со следующем.
# Отсутствующие здесь неспецифичные комментарии расположены в следующем цикле,
# где сторонней логики меньше, и понимать эту часть проще.
#
# Обработка логики первых двух настроек: прохождение по репозиторию объединяющему их.
if repo_ver is not None:
	for repo in repo_ver:
		yb = yum.YumBase()
		if not yb.setCacheDir():
			print >>sys.stderr, "Can't create a tmp. cachedir. "
			sys.exit(1)
		yb.repos.disableRepo('*')
		yb.repos.enableRepo(repo)

		if not os.path.exists(download_dir + '/' + repo):
			os.makedirs(download_dir + '/' + repo)
		tmp = download_dir + '/' + repo + '/tmp'
		if not os.path.exists(tmp):
			os.makedirs(tmp)
		else:
			files = glob.glob(tmp + '/*')
			for f in files:
				os.remove(f)

		repo_name_ver[repo] = {}
		ignore = False
		prev_name = None
		for pkg in sorted(yb.pkgSack.returnPackages(), reverse=True):
			if ignore == True and prev_name == pkg.name:
				continue
			if prev_name != pkg.name:
				ignore = False

			pkg.repo.copy_local = True
			pkg.repo.cache = 0

			# Если попали в имя, нужное второй настроке.
			if name_count is not None and pkg.name in name_count:
				# Текущая глубина всё ещё существует.
				if name_count[pkg.name] > 0:
					# Добавится или инициализируется запись в глобальный словарь.
					if pkg.name not in repo_name_ver[repo]:
						repo_name_ver[repo][pkg.name] = []
					repo_name_ver[repo][pkg.name].append(pkg.version + '-' + pkg.release)
					# Надо уменьшить текущую историю для будущего отслеживания.
					name_count[pkg.name] -= 1
					# Скачать.
					save_po(pkg, repo)
				# Имя всё еще остлеживаемое, но предел текущий глубины.
				else:
					# Удалить запись из переменной-словаря.
					name_count.pop(pkg.name, None)
					# Игнорировать следующие глубины в случае если попадётся то же имя.
					ignore = True
			# Если не попали под вторую настройку, а она взаимоисключает первую.
			else:
				# Для избранных номеров версий игнорировать все версии что ниже определенной.
				if LooseVersion(pkg.version) >= LooseVersion(repo_ver[repo]):
					if pkg.name not in repo_name_ver[repo]:
						repo_name_ver[repo][pkg.name] = []
					repo_name_ver[repo][pkg.name].append(pkg.version + '-' + pkg.release)
					save_po(pkg, repo)
			prev_name = pkg.name
		process = subprocess.Popen("/usr/bin/createrepo --update {0}/{1}".format(download_dir, repo), shell=True, stdout=subprocess.PIPE)
		output, error = process.communicate()
		print(output)

# Работа с репозиториями, к которым применяется третье ограничение на отсечение по количеству свежих версий.
#
# Получение значения настроек.
name_uni_count = get_name_uni_count(config)
# Для каждого репозитория как индекса словаря.
if name_uni_count is not None:
	for repo in name_uni_count:
		# Количество последних фиксируемых версий, полученное как значение от индекса.
		# Не константа - изменяется, чтобы определить остановку в работе.
		uni_tmp = name_uni_count[repo]

		# Необходимая инициализация для репозитория.
		yb = yum.YumBase()
		if not yb.setCacheDir():
			print >>sys.stderr, "Can't create a tmp. cachedir. "
			sys.exit(1)
		# Уточнение конкретного ограничивающего имени.
		yb.repos.disableRepo('*')
		yb.repos.enableRepo(repo)

		# Создание каталога для сохранения, если не существует.
		if not os.path.exists(download_dir + '/' + repo):
			os.makedirs(download_dir + '/' + repo)
		# Вычисление пути для специального временного каталога для скачки.
		tmp = download_dir + '/' + repo + '/tmp'
		# Создание этого каталога, если необходимо. Или очистка всех файлов внутри.
		if not os.path.exists(tmp):
			os.makedirs(tmp)
		else:
			files = glob.glob(tmp + '/*')
			for f in files:
				os.remove(f)
		# Необходимая инициализация словаря.
		repo_name_ver[repo] = {}
		# Флаг для необходимого своевременного перехода к следующему имени при логическом забеге вперёд.
		ignore = False
		# Переменная для сохранения предыдущего имени пакета.
		prev_name = None
		# Итерация по отсортированным по свежести пакетам.
		for pkg in sorted(yb.pkgSack.returnPackages(), reverse=True):
			# Переместиться на следующую итерацию, если работается в рамках одного имени и надо игнорировать.
			if ignore == True and prev_name == pkg.name:
				continue
			# Здесь уже пришло новое имя пакета и с ним надо начинать работать, а не игнорировать изначально.
			if prev_name != pkg.name:
				ignore = False

			# Необходимые условия для yum-api чтобы гарантировать что пакет именно скачается.
			pkg.repo.copy_local = True
			pkg.repo.cache = 0

			# Пока ещё есть глубина для работы.
			if uni_tmp > 0:
				# Проверяется, присутствует ли уже имя в словаре и внутренний словарь инициализируется.
				if pkg.name not in repo_name_ver[repo]:
					repo_name_ver[repo][pkg.name] = []
				# Либо добавляется в набор необходимых версий для скачки.
				repo_name_ver[repo][pkg.name].append(pkg.version + '-' + pkg.release)
				# Текущее меньшение глубины.
				uni_tmp -= 1
				# Скачка файла.
				save_po(pkg, repo)
			# Достигнут лимит на отслеживаемые версии.
			# Возможно их меньше присутствует в репозитории чем надо отследить.
			# Интересоваться больше не имеет смысла.
			# Надо игнорировать итерации вперёд в рамках одного имени, то есть переходить к следующему имени.
			else:
				# Приведение переменной к первоначальному значению из конфига для последующих итераций.
				uni_tmp = name_uni_count[repo]
				ignore = True
			# Запоминание имени пакета для следующей итерации для сравнения на идентичность чтобы игнорировать.
			prev_name = pkg.name
		process = subprocess.Popen("/usr/bin/createrepo --update {0}/{1}".format(download_dir, repo), shell=True, stdout=subprocess.PIPE)
		output, error = process.communicate()
		print(output)

# Более красивая распечатка словаря.
def pretty(d, indent=0):
   for key, value in d.items():
      print('\t' * indent + str(key))
      if isinstance(value, dict):
         pretty(value, indent+1)
      else:
         print('\t' * (indent+1) + str(value))

pretty(repo_name_ver)
#print repo_name_ver


# -*- coding: utf-8 -*-
"""
    Created by w at 2022/11/29.
    Description:
    Changelog: all notable changes to this file will be documented
"""
import unittest
import json
from requests import request
from example.config import uat_kibana_host

class TestEs(unittest.TestCase):
    """
    """

    def setUp(self) -> None:
        pass

    @unittest.skip("直接跳过测试")
    def test_kibana_list(self):
        base_url = uat_kibana_host
        url: str = f"{base_url}/api/saved_objects/_find"

        headers: dict = {
            "Content-Type": "application/json",
            "kbn-xsrf": "True",
        }
        params = {
            "type": "index-pattern",
            "page": 1,
            "per_page": 1,
        }
        index_pattern_response = request(
            headers=headers, url=url, method="get", params=params
        )
        index_pattern_json = index_pattern_response.json()
        print(index_pattern_json)

    @unittest.skip("直接跳过测试")
    def test_kibana_create(self):
        index_pattern: str = "myth"
        base_url = uat_kibana_host
        url: str = f"{base_url}/api/saved_objects/index-pattern/{index_pattern}?overwrite=false"

        headers: dict = {
            "Content-Type": "application/json",
            "kbn-xsrf": "True",
        }
        index_pattern_title: str = "myth*"
        data = {
            "attributes": {
                "title": index_pattern_title,
                "timeFieldName": "generated_time",
            }
        }

        index_pattern_response = request(
            headers=headers, url=url, method="post", data=json.dumps(data)
        )
        index_pattern_json = index_pattern_response.json()
        if index_pattern_json["statusCode"] == 409:
            msg = f"{index_pattern_json['error']},{index_pattern_json['message']}"
        print(index_pattern_json)

    @unittest.skip("直接跳过测试")
    def test_kibana(self):
        from kibana_api import Kibana

        client = Kibana(base_url=uat_kibana_host)
        objects_response = client.object().all(type="index-pattern")  # Type in specific
        objects_json = objects_response.json()
        print(objects_json)
        pattern_json = {
            "title": "myth*",
            "timeFieldName": "generated_time",  # timefiledname is important, it taken as a reference to time
            "fields": "[]",
        }
        index_pattern_response = client.object().create(
            "index-pattern", attribs=pattern_json
        )
        index_pattern_json = index_pattern_response.json()
        print(index_pattern_json)

    @unittest.skip("直接跳过测试")
    def test_es(self):
        from elasticsearch import Elasticsearch
        from example.config import kibana_host

        client = Elasticsearch(hosts=kibana_host)
        index = "myth_sched_log_tag-2022.12.06-reindex"
        # client.indices.create(index=index)
        # data = client.indices.get(index=index)
        # data = client.indices.exists(index=index)
        # print(data)
        # client.indices.delete(index=index)
        # indices = client.indices.get_alias()
        # print(indices)
        # if index in indices:
        #     print(1)
        # else:
        #     print(2)
        # for index in indices:
        #     print(index, client.indices.exists(index=index))
        # if not client.indices.exists(index=index):
        #     continue
        # data = client.indices.get(index="wsy_src_chat-2022.12.06-reindex")
        # 模板
        # data = client.indices.get_template()

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


import turtle
import random

colors  = ["red","green","blue","pink","yellow","dark red","lime","dark blue","medium violet red", "cyan","saddle brown","dark gray","dark orange","magenta"]
#dark_colors
dark_colors = ["white","red","green","blue","pink","yellow"]

#line_length
length = 5

def remote_tangent_circles(circle_turtle,color,dis_range,radius):

    circle_turtle.color(color)
    for i in range(dis_range):
        circle_turtle.circle(radius*i)

    circle_turtle.up()
    circle_turtle.goto(0,0)
    circle_turtle.down()

def remote_concentric_circles(circle_turtle,dis_range,radius):

    for i in range(dis_range):
        color = random.choice(dark_colors)
        circle_turtle.color(color)
        circle_turtle.circle(radius*i)
        circle_turtle.up()
        circle_turtle.sety((radius*i)*(-1))
        circle_turtle.down()

    circle_turtle.up()
    circle_turtle.goto(0,0)
    circle_turtle.down()

if __name__ == "__main__":

    remote_circle = turtle.Turtle()
    remote_circle_screen = turtle.Screen()
    remote_circle_screen.bgcolor('black')

    remote_circle.width(1)      #set the circle width
    remote_circle.speed(0)      #set speed delay to 0

    remote_concentric_circles(remote_circle,30,10)

    remote_circle.width(2)      #change the circle width

    for j in range(8):
        for i in range (10):
            remote_tangent_circles(remote_circle,dark_colors[j],10,(10 + j))
            remote_circle.right(360/10)

    remote_circle.width(3)
    remote_concentric_circles(remote_circle,60,3)

    remote_circle.width(2)

    #start drawing the lines
    for count in range(60):
        remote_circle.forward(length)
        remote_circle.right(135)
        remote_circle.color('black')
        length = length + 5

    #Reset the Original Position
    remote_circle.penup()
    remote_circle.home()
    remote_circle.pendown()

    turtle.Screen().exitonclick()


from django.contrib.auth.decorators import login_required
from django.urls import path

from . import views

app_name = 'tasks'

urlpatterns = [
    path('', views.index, name='index'),
    path('inspections/',
         login_required(views.PersonalInspectionListView.as_view()),
         name='inspections'),
    path('inspections/new/', views.new_inspection, name='new_inspection'),
    path('inspections/<int:insp_id>/edit/',
         views.edit_inspection, name='edit_inspection'),
    path('inspection/<int:insp_id>/delete',
         views.del_inspection, name='del_inspection'),
    path('inspections/all/',
         login_required(views.AllInspectionListView.as_view()),
         name='all_inspections')
]


import json
import numpy as np
import pygame
from time import sleep, perf_counter
from math import isnan
from os.path import exists
from ast import literal_eval
import sys
import signal
import random

EMERGENCY_END = False
closable = True

def signal_handler(signal, frame):
    global EMERGENCY_END
    global closable
    EMERGENCY_END = True
    print("STOPPED")
    sleep(1)
    sys.exit()

def get_lifeId(array):
    lifeId = ''
    for y in range(array.shape[0]):
        for x in range(array.shape[1]):
            lifeId += str(array[y, x])
    return lifeId

def get_array(lifeId):
    lifeId = str(lifeId)
    for n in range(0, 51, 5):
        if n * n == len(lifeId):
            lst = []
            for i in range(n):
                lst.append([])
            index = 0
            for digit in lifeId:
                lst[index].append(int(digit))
                if len(lst[index]) == n:
                    index += 1
    array = np.array(lst)
    return array

def get_lists(lifeId):
    lifeId = str(lifeId)
    for n in range(0, 51, 5):
        if n * n == len(lifeId):
            lst = []
            for i in range(n):
                lst.append([])
            index = 0
            for digit in lifeId:
                lst[index].append(int(digit))
                if len(lst[index]) == n:
                    index += 1
    return lst

class LifeGame:
    def __init__(self, height=100, width=100, border=3, delay=1, cell_size=5, log=False):
        global EMERGENCY_END
        self.height, self.width, self.border, self.delay, self.cell_size, self.log = height, width, border, delay, cell_size, log
        self.reset()
        self.screen = None

        self.results = {}

    def reset(self):

        self.a = np.zeros((self.height, self.width), dtype=int)
        self.new_a = np.zeros((self.height, self.width), dtype=int)

    def set(self, lifeId, yx=(0, 0)):
        if yx == (0, 0):
            yx = (round(self.height / 2), round(self.width / 2))
        y, x = yx
        figure = get_array(lifeId)
        # print(figure.tolist())
        self.a[y:y + figure.shape[0], x:x + figure.shape[1]] = figure

    def base_alive_gen(self):
        mid = round(self.width / 2)
        self.a[mid - 1, mid] = self.a[mid, mid] = self.a[mid + 1, mid] = 1

    def random_gen(self):
        self.a = np.random.randint(2, size=(self.height, self.width))

    def check_border(self):
        for y in range(self.a.shape[0]):
            for x in range(self.a.shape[1]):
                if x + self.border >= self.a.shape[1] or x - self.border <= 0 or y + self.border >= self.a.shape[
                    0] or y - self.border <= 0:
                    self.a[y, x] = 0
        self.new_a = self.a.copy()

    def check_cell(self, y, x):
        cell = self.new_a[y, x]
        '''
		   123
		   405
		   678
		'''
        adj = [
            self.a[y + 1, x], self.a[y + 1, x + 1], self.a[y + 1, x - 1],
            self.a[y, x + 1], self.a[y, x - 1],
            self.a[y - 1, x], self.a[y - 1, x + 1], self.a[y - 1, x - 1]
        ]
        if cell:
            if sum(adj) != 2 and sum(adj) != 3:
                self.new_a[y, x] = 0
                not self.log or print(f"Cell in x{x}, y{y} is dead")

        # une cellule vivante possédant deux ou trois cellules voisines vivantes le reste, sinon elle meurt
        else:
            if sum(adj) == 3:
                self.new_a[y, x] = 1
                not self.log or print(f"Cell in x{x}, y{y} is born")
        # une cellule morte possédant exactement trois cellules voisines vivantes devient vivante (elle naît)

    def init_pygame(self):
        pygame.init()
        width = self.a.shape[1] * self.cell_size
        height = self.a.shape[0] * self.cell_size
        self.screen = pygame.display.set_mode((width, height))

    def show_map(self):
        # Crée une surface rectangulaire pour chaque case de la carte
        cell_surf = pygame.Surface((self.cell_size, self.cell_size))
        for y, row in enumerate(self.new_a):
            for x, cell in enumerate(row):
                rect = pygame.Rect(x * self.cell_size, y * self.cell_size, self.cell_size, self.cell_size)
                if cell:
                    cell = (255, 255, 255)
                else:
                    cell = (0, 0, 0)
                cell_surf.fill(cell)
                self.screen.blit(cell_surf, rect)

        pygame.display.flip()

    def test(self, figure, yx=(0, 0), show=True):
        global EMERGENCY_END
        if yx == (0, 0):
            yx = (round(self.height / 2), round(self.width / 2))
        y, x = yx
        if isinstance(figure, str):
            figure = get_array(figure)

        if isinstance(figure, int):
            print("pass test", figure)
            for comb in range(2 ** 25):
                if comb == figure:
                    figure = np.zeros((5, 5), dtype=int)
                    for f_y in range(5):
                        for f_x in range(5):
                            figure[f_y, f_x] = (comb >> (f_y * f_x + f_x)) & 1
                            self.a[y:y + figure.shape[0], x:x + figure.shape[1]] = figure
                    break
        elif isinstance(figure, list):
            figure = np.array(figure)
            self.a[y:y + figure.shape[0], x:x + figure.shape[1]] = figure
        elif isinstance(figure, np.ndarray):
            self.a[y:y + figure.shape[0], x:x + figure.shape[1]] = figure
        result = self.run(show=show)
        return result

    def test_all_in(self, f_height=5, f_width=5, yx=(0, 0), range_list=range(6), show=True, log_day=True):
        global EMERGENCY_END
        if yx == (0, 0):
            yx = (round(self.height / 2), round(self.width / 2))
        new = np.zeros((f_height, f_width), dtype=int)
        counter = 0
        for comb in range(2 ** (f_height * f_width)):
            if comb in range_list:
                if show:
                    self.reset()
                for y in range(f_height):
                    for x in range(f_width):
                        new[y, x] = (comb >> (y * x + x)) & 1
                y, x = yx

                if sum(sum(new)) > 0:
                    self.a[y:y + new.shape[0], x:x + new.shape[1]] = new
                    print(f"Test number {comb} is running [lifeID]|{get_lifeId(new)}|")
                    result = self.results[get_lifeId(new)] = self.run(show=show, log_day=log_day)
                    print(f"Test number {comb} is termined : {result}")
                    if result[2] > 5:
                        yield {get_lifeId(new): result}

                counter += 1
                if counter == range_list[-1] + 1:
                    break

    def live(self):
        global EMERGENCY_END
        self.init_pygame()
        day = 1
        base_n_cell = last_n_cell = sum(sum(np.where(self.a, 1, 0)))
        count = 0

        while True:
            pygame.display.update()
            n_cell = sum(sum(np.where(self.a, 1, 0)))
            if n_cell != 0:
                purcent = round((n_cell - last_n_cell) / last_n_cell * 100)
            else:
                purcent = 0
            print(f"Day {day}, cells {n_cell}, evolution {'+' if last_n_cell <= n_cell else ''}{purcent}%")
            self.new_a = self.a.copy()

            for y in range(self.new_a.shape[0]):
                for x in range(self.new_a.shape[1]):
                    # print(x, y, a.shape)
                    if (y, x) == self.a.shape or x in [0, self.a.shape[1] - 1] or y in [0, self.a.shape[0] - 1]:
                        self.new_a[y, x] = 0
                    else:
                        self.check_cell(y, x)
            self.a = self.new_a.copy()
            self.show_map()
            sleep(self.delay)
            day += 1
            last_n_cell = n_cell
            if EMERGENCY_END:
                break

    def run(self, show=True, log_day=True):
        if show:
            self.init_pygame()
        day = 1
        pre_states = []
        base_n_cell = last_n_cell = sum(sum(np.where(self.a, 1, 0)))
        count = 0
        infinite = False

        while True:
            global EMERGENCY_END
            n_cell = sum(sum(np.where(self.a, 1, 0)))
            if n_cell != 0:
                purcent = round((n_cell - last_n_cell) / last_n_cell * 100)
            else:
                purcent = 0
            if log_day:
                print(f"Day {day}, cells {n_cell}, evolution {'+' if last_n_cell <= n_cell else ''}{purcent}%")

            self.new_a = self.a.copy()

            for y in range(self.new_a.shape[0]):
                for x in range(self.new_a.shape[1]):
                    # print(x, y, a.shape)
                    if (y, x) == self.a.shape or x in [0, self.a.shape[1] - 1] or y in [0, self.a.shape[0] - 1]:
                        self.new_a[y, x] = 0
                    else:
                        self.check_cell(y, x)
            self.a = self.new_a.copy()
            if show:
                self.show_map()

            if self.delay:
                sleep(self.delay)

            if last_n_cell == n_cell:
                count += 1
            else:
                count = 0

            last_n_cell = n_cell
            day += 1
            if EMERGENCY_END:
                print("=== STOPPED ===")
                return [base_n_cell, n_cell, day, infinite]

            if count == 5 or self.a.tolist() in pre_states:
                infinite = True
                print("=== TERMINED ===")
                return [base_n_cell, n_cell, day, infinite]
            elif n_cell == 0:
                print("=== TERMINED ===")
                return [base_n_cell, n_cell, day, infinite]

            pre_states.append(self.a.tolist())
            pre_states = pre_states[-50:]

def serial_test(range_list=range(21), height=150, width=150, cell_size=5, show=True, save=False, fast=False):
    global closable
    data = {}
    lifeGame = LifeGame(delay=0, height=height, width=width, cell_size=cell_size)

    closable = False
    for result in lifeGame.test_all_in(range_list=range_list, log_day=not fast, show=show):
        data.update(result)
        print("(added result)")
        if EMERGENCY_END:
            break

    # open("lifeSave.json", 'w+').write(json.dumps(data))

    print("Analyze of results..")
    top = {}

    def convert(o):
        if isinstance(o, np.int32):
            return int(o)
        raise TypeError
    if save:
        try:
            not exists("lifeSave.json") or data.update(json.loads(open("lifeSave.json", 'r').read()))
            data = json.dumps(data, default=convert)
        except Exception as error:
            print(f"error json: {error}\nwriting brut data...")
            not exists("lifeSave.json") or data.update(literal_eval(open("lifeSave", 'r').read()))
            open("lifeSave", 'w+').write(str(data))
        else:
            open("lifeSave.json", 'w+').write(data)
    closable = True

    for value in data.values():
        value = value[2]
        for key in data.keys():
            if data[key][2] == value:
                if value not in top.keys():
                    top[value] = []
                top[value].append(key)

    for best in list(reversed(sorted(list(top.keys()))))[:3]:
        print(f"\n===== {best} day =====")
        c = 0
        for i, element in enumerate(top[best]):
            print(c * '\t' + element)
            for line in get_lists(element):
                print(c * '\t' + str(line))
            c += 1

def resume_test(limit=50):
    if exists("lifeSave.json"):
        data = json.loads(open("lifeSave.json", 'r').read())
    elif exists("lifeSave"):
        data = literal_eval(open("lifeSave", 'r').read())
    else:
        data = {}
    test_number = len(data)
    serial_test(range_list=range(test_number, test_number + limit))

def main(lifeID=None, space=0):
    width = 150
    height = 150
    cell_size = 5
    lifeGame = LifeGame(delay=0, height=height, width=width, cell_size=cell_size)
    lifeGame.init_pygame()
    if lifeID:
        for y in range(0, height, 5+space):
            for x in range(0, width, 5+space):
                if x!= 0 or y!= 0:
                    lifeGame.set(lifeId=lifeID, yx=(y, x))
    else:
        lifeID = ''
        for i in range(25):
            lifeID += str(random.randint(0, 1))
        print(lifeID)
        for y in range(0, height, 5+space):
            for x in range(0, width, 5+space):
                if x!= 0 or y!= 0:
                    lifeGame.set(lifeId=lifeID, yx=(y, x))
    lifeGame.show_map()
    lifeGame.run()

if __name__ == "__main__":
    signal.signal(signal.SIGINT, signal_handler)
    args = sys.argv[1:]
    if "main" in args:
        if len(args) == 2:
            main(args[1])
        else:
            main()
    else:
        if len(args) == 0:
            args = ['']
        if "save" in args:
            save = True
        else:
            save = False
        if "fast" in args:
            fast = True
        else:
            fast = False
        if "nogui" in args:
            show = False
        else:
            show = True
        if args[0] == "test":
            lifeGame = LifeGame(delay=0, height=150, width=150, )
            if len(args) > 2:
                if args[1] == "id":
                    lifeId = args[2]
                    lifeGame.test(lifeId, show=show)
                elif args[1] == "number":
                    lifeGame.test(int(args[2]), show=show)
        elif args[0] == "resume":
            if len(args) > 1:

                if len(args) > 2:
                    test_number = int(args[1])
                    serial_test(range_list=range(test_number, int(args[2])), show=show, save=save, fast=fast)
                elif "+" in args[1]:
                    limit = int(args[1][1:])
                    print(f"resume to +{limit}")
                    resume_test(limit=limit)
                else:
                    test_number = int(args[1])
                    serial_test(range_list=range(test_number, test_number + 50), show=show, save=save, fast=fast)
            else:
                resume_test()
        elif args[0] == "random":
            lifeGame = LifeGame(delay=0, height=150, width=150, cell_size=5)
            lifeGame.random_gen()
            lifeGame.run(show=show)
        elif args[0] == "live":
            lifeGame = LifeGame(delay=0, height=150, width=150)
            if len(args) > 2:
                if args[1] == "id":
                    lifeId = args[2]
                    lifeGame.set(lifeId)
                    lifeGame.live()
            else:
                lifeGame.base_alive_gen()
                lifeGame.live()
        else:
            lifeGame = LifeGame(delay=0.5, height=50, width=50, cell_size=15)
            lifeGame.base_alive_gen()
            lifeGame.live()


import numpy as np
import p131A as cd
import p132A as kruskal
from queue import PriorityQueue
from typing import Tuple
import random
import time

def complete_graph(n_nodes: int, max_weight=50)-> Tuple[int, list]:
    l_g = []

    for u in range(n_nodes):
        for v in range(u+1, n_nodes):
            w = random.randint(1, max_weight)
            l_g.append((u, v, w))

    return (n_nodes, l_g)

def time_kruskal(n_graphs: int, n_nodes_ini: int, n_nodes_fin: int, step: int)-> list:
    l_times = []
    n_nodes = n_nodes_ini

    while n_nodes <= n_nodes_fin:
        total = 0

        for i in range(n_graphs):
            n, l_g = complete_graph(n_nodes)
            start = time.time()
            kruskal.kruskal(n_nodes, l_g)
            end = time.time()
            total += end - start

        l_times.append((n, (total / n_graphs)))
        n_nodes += step

    return l_times

def time_kruskal_2(n_graphs: int, n_nodes_ini: int, n_nodes_fin: int, step: int)-> list:
    l_times = []
    n_nodes = n_nodes_ini

    while n_nodes <= n_nodes_fin:
        total = 0

        for i in range(n_graphs):
            n, l_g = complete_graph(n_nodes)
            tw, tree, time = kruskal.kruskal_2(n_nodes, l_g)
            total += time

        l_times.append((n, (total / n_graphs)))
        n_nodes += step

    return l_times

if __name__ == "__main__":
    n_graphs = 10
    n_nodes_ini = 3
    n_nodes_fin = 10
    step = 1

    l_times = time_kruskal(n_graphs, n_nodes_ini, n_nodes_fin, step)
    l_times2 = time_kruskal_2(n_graphs, n_nodes_ini, n_nodes_fin, step)

    print(l_times)
    print(l_times2)


import urllib.request
def get(domain, path):
    url = "http://" + domain + "/" + path
    with urllib.request.urlopen(url) as f:
        return f.info(), f.read()

for data in get("filkom.ub.ac.id", "/"):
    print(data)
for data in get("filkom.ub.ac.id", "/apps"):
    print(data)


from django.urls import path
from . import views

from .views import FunctionCreateView, FunctionListView, FunctionDetailView, FunctionDeleteView

urlpatterns = [
        path('',views.home,name='app-home'),
        # calculus tool urls
        path('calculus_tool/',FunctionListView.as_view(),name='calculus_tool'),
        path('calculus_tool/function/',FunctionCreateView.as_view(),name='function-create'),
        path('calculus_tool/<int:pk>/',FunctionDetailView.as_view(),name='function-detail'),
        path('calculus_tool/<int:pk>/delete/',FunctionDeleteView.as_view(),name='function-delete'),
        ]


import cv2
import argparse
import math

# ===================================================================

keep_processing = True

# parse command line arguments for camera ID or video file

parser = argparse.ArgumentParser(
    description='Lower the resolution of camera/video image to demonstrate aliasing')

parser.add_argument(
    "--camera",
    type=int,
    help="specify camera to use",
    default=0)

parser.add_argument(
    'video_file',
    metavar='video_file',
    type=str,
    nargs='?',
    help='specify optional video file')

args = parser.parse_args()

# ===================================================================

# define video capture object

print("Starting camera stream")
cap = cv2.VideoCapture()

# define display window name

window_name = "Live Camera Input - Image Resolution"  # window name

# if command line arguments are provided try to read video_file
# otherwise default to capture from attached H/W camera

if (((args.video_file) and (cap.open(str(args.video_file))))
        or (cap.open(args.camera))):

    # create window by name (note flags for resizable or not)

    cv2.namedWindow(window_name, cv2.WINDOW_NORMAL)

    # add some track bar controllers for settings

    scale_percent = 80
    cv2.createTrackbar(
        "Scale (percent)",
        window_name,
        scale_percent,
        100,
        lambda x:x)

    while (keep_processing):

        # if video file or camera successfully open then read frame from video

        if (cap.isOpened):
            ret, frame = cap.read()

            # when we reach the end of the video (file) exit cleanly

            if (ret == 0):
                keep_processing = False
                continue

        # start a timer (to see how long processing and display takes)

        start_t = cv2.getTickCount()

        # *******************************

        # parameters for rescaling the image

        width_original = int(frame.shape[1])
        height_original = int(frame.shape[0])
        dim_original = (width_original, height_original)

        # get parameter from track bars
        scale_percent = cv2.getTrackbarPos("Scale (percent)", window_name)

        width = int(width_original * scale_percent/100)
        height = int(height_original * scale_percent/100)
        dim = (width, height)

        # parameters for overlaying text labels on the displayed images

        font = cv2.FONT_HERSHEY_COMPLEX
        bottomLeftCornerOfText = (10,height_original-15)
        fontScale = 1
        fontColor = (123,49,126)
        lineType  = 6

        # rescale image

        frame_lowered = cv2.resize(frame, dim, interpolation=cv2.INTER_AREA)
        frame_up_res_again = cv2.resize(frame_lowered, dim_original, interpolation=cv2.INTER_AREA)

        # overlay corresponding labels on the images

        cv2.putText(frame, f'Original Input - {width_original}x{height_original}',
            bottomLeftCornerOfText,
            font,
            fontScale,
            fontColor,
            lineType)
        cv2.putText(frame_up_res_again, f'Low Resolution - {width}x{height}',
            bottomLeftCornerOfText,
            font,
            fontScale,
            fontColor,
            lineType)

        # stack the images into a grid

        output = cv2.hconcat([frame, frame_up_res_again])

        # *******************************

        # display image

        cv2.imshow(window_name, output)

        # stop the timer and convert to ms. (to see how long processing and
        # display takes)

        stop_t = ((cv2.getTickCount() - start_t) /
                  cv2.getTickFrequency()) * 1000

        # start the event loop - essential

        # cv2.waitKey() is a keyboard binding function (argument is the time in
        # ms). It waits for specified milliseconds for any keyboard event.
        # If you press any key in that time, the program continues.
        # If 0 is passed, it waits indefinitely for a key stroke.
        # (bitwise and with 0xFF to extract least significant byte of
        # multi-byte response)

        # wait 40ms or less depending on processing time taken (i.e. 1000ms /
        # 25 fps = 40 ms)

        key = cv2.waitKey(max(2, 40 - int(math.ceil(stop_t)))) & 0xFF

        # It can also be set to detect specific key strokes by recording which
        # key is pressed

        # e.g. if user presses "x" then exit

        if (key == ord('x')):
            keep_processing = False

    # close all windows

    cv2.destroyAllWindows()

else:
    print("No video file specified or camera connected.")

# ===================================================================


from flask import Flask, render_template, request
import pickle
import numpy as np

app = Flask(__name__)

# Load the trained model from the pickle file
with open("diabetes_ml_model.pkl", "rb") as file:
    model = pickle.load(file)

@app.route('/')
def home():
    return render_template('index.html')

@app.route('/predict', methods=['POST'])
def predict():
    try:
        # Extract features from the form
        features = [float(x) for x in request.form.values()]
        input_features = np.array(features).reshape(1, -1)

        # Make a prediction
        prediction = model.predict(input_features)

        # Display the result
        return render_template('index.html', prediction_text=f'The prediction is {prediction[0]}')

    except Exception as e:
        return render_template('index.html', prediction_text=f'Error: {str(e)}')

# Run the app if the script is executed directly
if __name__ == '__main__':
    app.run(debug=False, host='0.0.0.0')


#peut-être griser à la place de discard
discarded = ["Y. Wang2019_T_Haze"]

def pop_discarded(spectrum):
    discarded_list = []
    for key in spectrum.keys():
        if key in discarded:
            discarded_list.append(key)

    for key in discarded_list:
        print("Discarding " + key + "...")
        spectrum.pop(key)

def split_discarded(spectrum):
    data = {}
    discarded_data = {}

    return data, discarded_data


import sqlite3

arquivo = "banco.bd"

def iniciar_bdplanner():
  bdplanner = None
  try:
    bdplanner = sqlite3.connect(arquivo_banco)

  except sqlite3.Error as e:
    print("Erro na conexão",e)

  return bdplanner

def criar_tabela(bdplanner,sql_criar_tabela):
  try:
    cursor = bdplanner.cursor()
    cursor.execute(sql_criar_tabela)
  except sqlite3.Error as e:
    print("Erro ao criar a tabela",e)

    def inserir_usuario(bdplanner, sql_inserir_usuario):
      try:
        cursor = bdplanner.cursor()
        cursor.execute(sql_inserir_usuario)
        bdplanner.commit()
        print('Conexão estabelecida')
      except sqlite3.Error as e:
        print('Erro na inserção de dados:', e)

def buscar_usuario(bdplanner, sql_buscar_usuario):
  usuario = None
  try:
    cursor = bdplanner.cursor()
    cursor.execute(sql_buscar_usuario)
    usuario = cursor.fetchall()
    print('exibição de dados concedida.')
  except sqlite3.Error as e:
    print('Erro exibindo os dados:', e)
  finally:
    return usuario


#! /usr/bin/env python

import os
import sys
import logging
import re
import csv
import itertools
import copy

import gekgo_util
from gekgo_util import RunLogger, get_dict_reader
from data_classes import Sample, SampleDatabase, Tissue, DnaExtraction
from update_extraction_data import get_samples_with_dna

_LOG = RunLogger(name=__file__,
        log_to_stderr=True,
        log_to_file=False)

def parse_data(lane_qubit_file,
               plate_well_file,
               delimiter='\t'):
    qubit_samples = parse_lane_qubit_data(lane_qubit_file, delimiter=delimiter)
    well_samples = parse_well_data(plate_well_file, delimiter=delimiter)
    for k, sample in well_samples.iteritems():
        assert k in qubit_samples.keys()
        assert sample.extraction.qubit == qubit_samples[k].extraction.qubit
        assert qubit_samples[k].extraction.plate == None
        assert sample.extraction.plate != None
        assert qubit_samples[k].extraction.row == None
        assert sample.extraction.row != None
        assert qubit_samples[k].extraction.column == None
        assert sample.extraction.column != None
        assert qubit_samples[k].extraction.dilution == None
        assert sample.extraction.dilution != None
        qubit_samples[k].extraction.plate = sample.extraction.plate
        qubit_samples[k].extraction.row = sample.extraction.row
        qubit_samples[k].extraction.column = sample.extraction.column
        qubit_samples[k].extraction.dilution = sample.extraction.dilution
    return qubit_samples

def parse_lane_qubit_data(file_obj, delimiter='\t', samples=SampleDatabase()):
    dr, src = get_dict_reader(file_obj, delimiter=delimiter)
    for n, line_dict in enumerate(dr):
        field_series = line_dict['field_series'].strip()
        field_number = line_dict['field_number'].strip()
        qubit = line_dict['qubit'].strip()
        if qubit == '' or qubit == None:
            qubit = None
        else:
            qubit = float(qubit)
        lane = line_dict['lane'].strip()
        if lane == '' or lane == None:
            raise Exception('problem parsing lane data from row {0}'.format(
                    n))
        extraction = DnaExtraction(
                qubit = qubit,
                gel_lane = int(lane))
        s = Sample(field_series = line_dict['field_series'],
                   field_number = line_dict['field_number'])
        s.extraction = extraction
        samples.add(s)
    return samples

def parse_well_data(file_obj, delimiter='\t', samples=SampleDatabase()):
    dr, src = get_dict_reader(file_obj, delimiter=delimiter)
    for n, line_dict in enumerate(dr):
        field_series = line_dict['field_series'].strip()
        field_number = line_dict['field_number'].strip()
        plate = line_dict['plate'].strip()
        col = line_dict['col'].strip().upper()
        row = line_dict['row'].strip()
        qubit = line_dict['qubit'].strip()
        if not plate in ['1', '2', '3']:
            raise Exception('unexpected plate value {0} at row {1}'.format(
                    plate, n))
        if not row in ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']:
            raise Exception('unexpected row value {0} at row {1}'.format(
                    row, n))
        if not col in [str(x) for x in range(1, 13)]:
            raise Exception('unexpected col value {0} at col {1}'.format(
                    col, n))
        if qubit == '' or qubit == None:
            raise Exception('could not parse qubit value at row {0}'.format(n))
        extraction = DnaExtraction(
                qubit = float(qubit),
                plate = int(plate),
                column = int(col),
                row = row.upper(),
                dilution = 5.0)
        s = Sample(field_series = line_dict['field_series'],
                   field_number = line_dict['field_number'])
        s.extraction = extraction
        samples.add(s)
    return samples

def get_samples_for_libraries(sample_db):
    samples = SampleDatabase()
    for k, sample in sample_db.iteritems():
        if sample.extraction.plate != None:
            new_sample = copy.deepcopy(sample)
            samples.add(new_sample)
    return samples

def check_database(db):
    tally = 0
    for k, sample in db.iteritems():
        if not sample.tissue_sample:
            assert not sample.extraction
            assert sample.tissue_sample.found == False
            assert sample.extraction.extracted == False
            assert sample.tissue_sample.material == None
            assert sample.tissue_sample.preservative == None, ('{0}: {1!r}'.format(
                    sample.field_id, sample.tissue_sample.preservative))
            assert sample.tissue_sample.tube_data == {}
            assert sample.extraction.protocol == None
            assert sample.extraction.notes == None
            assert sample.extraction.rnase == False
            assert sample.extraction.gel_lane == None
            assert sample.extraction.plate == None, 'plate was {0!r} for {1}'.format(
                    sample.extraction.plate, k)
            assert sample.extraction.row == None
            assert sample.extraction.column == None
            assert sample.extraction.dilution == None
        else:
            tally += 1
    _LOG.info('{0} samples with dna!'.format(tally))
    return 0

def main():
    # inputs
    path_to_qubit_data = os.path.join(gekgo_util.LABWORK_DIR,
            "sources",
            "gel_lane_and_qubit.txt")
    path_to_well_data = os.path.join(gekgo_util.LABWORK_DIR,
            "sources",
            "plate_well_info.txt")
    # outputs
    plate_data_out_path = os.path.join(gekgo_util.LABWORK_DIR,
            "msg_library_samples.txt")
    dna_data_out_path = os.path.join(gekgo_util.LABWORK_DIR,
            "samples_with_dna.txt")

    # load database
    db = SampleDatabase(path=gekgo_util.DB_PATH)
    # test if script has been run
    for k, sample in db.iteritems():
        if sample.extraction.gel_lane != None or \
           sample.extraction.plate != None or \
           sample.extraction.row != None or \
           sample.extraction.column != None or \
           sample.extraction.dilution != None:
            _LOG.error('Database already has concentration and plate data!\n'
                'I.e., this script has already been successfully used.\n'
                'Write a different script to update info, as this script\n'
                'may be out-of-date and could delete data')
            sys.exit(-1)

    new_extraction_data = parse_data(
            lane_qubit_file = path_to_qubit_data,
            plate_well_file = path_to_well_data)

    for k, sample in new_extraction_data.iteritems():
        assert k in db.keys()
        db[k].extraction.gel_lane = sample.extraction.gel_lane
        db[k].extraction.qubit = sample.extraction.qubit
        db[k].extraction.plate = sample.extraction.plate
        db[k].extraction.row = sample.extraction.row
        db[k].extraction.column = sample.extraction.column
        db[k].extraction.dilution = sample.extraction.dilution
        if k == 'KU-FS 16':
            db[k].tissue_sample.found = True
            db[k].tissue_sample.material = 'liver'
            db[k].tissue_sample.preservative = 'frozen'
            db[k].extraction.extracted = True
            db[k].extraction.protocol = 'guanidine thiocyanate'
            db[k].extraction.rnase = True

    rc = check_database(db)
    if rc == 0:
        db.commit()

    library_samples = get_samples_for_libraries(db)
    # import code; code.interact(local=locals());
    library_samples.write_flat_file(
            path=plate_data_out_path)

    dna_samples = get_samples_with_dna(db)
    dna_samples.write_flat_file(
            path=dna_data_out_path)

if __name__ == '__main__':
    main()


class Solution:
    def findShortestSubArray(self, nums: List[int]) -> int:
        arr = {}
        vals = []
        for i in range(len(nums)):
            if nums[i] not in arr.keys():
                vals.append([1, i, i])
                arr[nums[i]] = len(vals) - 1
            else:
                vals[arr[nums[i]]][0] += 1
                vals[arr[nums[i]]][2] = i
        def helper(x):
            return x[0], (x[1]-x[2])
        vals = sorted(vals, key=helper, reverse=True)
        return vals[0][2] - vals[0][1] + 1


import logging

import aligned_alleles
import allele_basic

class AlleleUnifier:
    def __init__(self, allele_storage, logger):
        """
        @type allele_storage: aligned_alleles.AlignedAlleleStorage
        """
        self.allele_storage = allele_storage
        self.logger = logger

    def UnifySNPs(self, v_gene, alleles):
        v_alleles = self.allele_storage.GetAllelesByVGene(allele_basic.ModifyGeneName(v_gene))
        main_allele = v_alleles.MinimalAlleleId()
        snp_position_union = set()
        for allele in alleles:
            snps = allele.SNPs()
            for pos, nucl in snps:
                snp_position_union.add(pos)
        self.logger.debug("Combined position set: " + str(snp_position_union))
        snp_position_union = sorted(list(snp_position_union))
        for a_ind, allele in enumerate(alleles):
            snps = allele.SNPs()
            snp_dict = dict()
            for pos, nucl in snps:
                snp_dict[pos] = nucl
            updated_snps = []
            for pos in snp_position_union:
                if pos in snp_dict:
                    updated_snps.append((pos, snp_dict[pos]))
                else:
                    main_allele_nucl = v_alleles.GetNucleotideByAlleleAndPos(main_allele, pos)
                    updated_snps.append((pos, main_allele_nucl))
            alleles[a_ind].UpdateSNPSet(updated_snps)
        return alleles


# -*- coding: utf-8 -*-
import os
import sys

reload(sys)
sys.setdefaultencoding('utf-8')
from flask_app import db

class Candidate(db.Model):
    __tablename__ = 'Candidate'

    candidateID = db.Column(db.String(100), primary_key=True)
    candidateName = db.Column(db.String(100))
    companyID = db.Column(db.String(100))
    price = db.Column(db.Float)
    ranking = db.Column(db.Integer)
    managerName = db.Column(db.String(100))
    managerID = db.Column(db.String(100))
    biddingID = db.Column(db.String(100), db.ForeignKey('WinBiddingPub.biddingID'))

    def __init__(self, candidateID=None, candidateName=None,
                 companyID=None, price=0, ranking=0,
                 managerName=None, managerID=None, biddingID=None):
        self.candidateID = candidateID
        self.candidateName = candidateName
        self.companyID = companyID
        self.price = price
        self.ranking = ranking
        self.managerName = managerName
        self.managerID = managerID
        self.biddingID = biddingID

    @staticmethod
    def generate(c):
        res = {}
        res['candidateID'] = c.candidateID
        res['candidateName'] = c.candidateName
        res['companyID'] = c.companyID
        res['price'] = c.price
        res['ranking'] = c.ranking
        res['managerName'] = c.managerName
        res['managerID'] = c.managerID
        res['biddingID'] = c.biddingID
        return res

    @staticmethod
    def delete(bidInfo):
        biddingID = bidInfo['biddingID']
        db.session.query(Candidate).filter(
            Candidate.biddingID == biddingID).delete(
            synchronize_session=False
        )
        return (True, None)


import regex

class Tag:
    def __init__(self, tag_name, dom_id, classes):
        self.tag_name = tag_name
        self.dom_id = dom_id
        self.classes = classes

    def __eq__(self, other):
        return self.tag_name == other.tag_name \
               and self.dom_id == other.dom_id \
               and self.classes == other.classes

TAG_REGEX = r'(?P<name>\w+)(#(?P<id>\w+))?(\.(?P<classes>\w+))*'

def parse_hierarchy(hierarchy_string):
    results = []
    tags = hierarchy_string.split(' ')

    for tag in tags:
        match = regex.match(TAG_REGEX, tag)
        tag_name = match.group("name")
        id_name = match.group("id")
        classes = match.captures("classes")
        classes_set = set()
        for c in classes:
            classes_set.add(c)
        results += [Tag(tag_name, id_name, classes_set)]
        print(tag_name, id_name, classes)

    return results


# -*- coding: utf-8 -*-
import re
from urllib.parse import urlparse

class URI:
    def __init__(self, text):
        self.parsed = []
        urls = re.findall('https?://(?:[^\|]+?)(?:\|.*)?>', text)
        for url in urls:
            url = url.rstrip('>')
            if '|' in url and url.index('|') > 0:
                url = url.split('|')[0]
            self.parsed.append(urlparse(url))


# DESENVOLVIDO POR:
# PEDRO LUCAS NASCIMENTO MOREIRA MACHADO
# KAIO STEFAN CAMPOS NUNES
# CAIO PEREIRA LAPA

import numpy as np

# Ajuste do modelo u(t): N = B0 + B1t
def fit_model_1(idade, quantidade):
    # Calcular os coeficientes B0 e B1 usando as fórmulas de regressão linear
    n = len(idade)
    soma_x = sum(idade)
    soma_y = sum(quantidade)
    soma_x_quadrado = sum(x ** 2 for x in idade)
    soma_xy = sum(x * y for x, y in zip(idade, quantidade))

    B1 = (n * soma_xy - soma_x * soma_y) / (n * soma_x_quadrado - soma_x ** 2)
    B0 = (soma_y - B1 * soma_x) / n

    N_hat1 = [B0 + B1 * t for t in idade]

    return N_hat1

# Ajuste do modelo u(t): N = B0 + B1t + B2t²
def fit_model_2(idade, quantidade):
    # Calcular os coeficientes B0, B1 e B2 usando as fórmulas de regressão polinomial
    n = len(idade)
    soma_x = sum(idade)
    soma_y = sum(quantidade)
    soma_x_quadrado = sum(x ** 2 for x in idade)
    soma_x_cubico = sum(x ** 3 for x in idade)
    soma_x_quarta = sum(x ** 4 for x in idade)
    soma_xy = sum(x * y for x, y in zip(idade, quantidade))
    soma_x_quadrado_y = sum(x ** 2 * y for x, y in zip(idade, quantidade))

    A = [[n, soma_x, soma_x_quadrado],
         [soma_x, soma_x_quadrado, soma_x_cubico],
         [soma_x_quadrado, soma_x_cubico, soma_x_quarta]]

    B = [soma_y, soma_xy, soma_x_quadrado_y]

    B0, B1, B2 = np.linalg.solve(A, B)

    N_hat2 = [B0 + B1 * t + B2 * t ** 2 for t in idade]

    return N_hat2

# Ajuste do modelo u(t): N = B0 * exp(B1t)
def fit_model_3(idade, quantidade):
    # Calcular os coeficientes B0 e B1 usando as fórmulas de regressão exponencial
    n = len(idade)
    soma_x = sum(idade)
    soma_y = sum([np.log(y) for y in quantidade])
    soma_x_quadrado = sum(x ** 2 for x in idade)
    soma_xy = sum(x * np.log(y) for x, y in zip(idade, quantidade))

    B1 = (n * soma_xy - soma_x * soma_y) / (n * soma_x_quadrado - soma_x ** 2)
    B0 = np.exp((soma_y - B1 * soma_x) / n)

    N_hat3 = [B0 * np.exp(B1 * t) for t in idade]

    return N_hat3

# Calcular o coeficiente de determinação (r²)
def calculate_r_squared(quantidade, N_hat):
    media_quantidade = sum(quantidade) / len(quantidade)
    numerador = sum((y - y_hat) ** 2 for y, y_hat in zip(quantidade, N_hat))
    denominador = sum((y - media_quantidade) ** 2 for y in quantidade)
    r_squared = 1 - numerador / denominador
    return r_squared

# Determinar o modelo com o maior coeficiente de determinação (r²)
def determine_best_model(r_squared_values):
    return r_squared_values.index(max(r_squared_values))  # Índice do modelo com o maior r²