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

"""
@File    :   excel_util.py
@Time    :   2022/08/04 15:19:23
@Author  :   Ysm
@Contact :   rootlulu@163.com
"""

import logging as log
import os
import shutil
import traceback
import typing as t

from openpyxl import Workbook as WB
from openpyxl import load_workbook
from openpyxl.cell import Cell
from openpyxl.styles import Font
from openpyxl.styles import PatternFill
from openpyxl.styles import Alignment
from openpyxl.utils import column_index_from_string
from openpyxl.utils.exceptions import InvalidFileException

SUPPORTED_FILE_TYPE = ".xlsx"

class _WorkBook:
    """the singleton workbook if its filename is the same.

    Raises:
        InvalidFileException: the invalid file type.

    Returns:
        [WorkBook]:
    """

    # todo： multiprocess in problem.
    singleton = {}
    SUFFIX = SUPPORTED_FILE_TYPE

    def __new__(cls, filename: t.AnyStr) -> WB:
        if filename not in cls.singleton:
            if not filename.endswith(cls.SUFFIX):
                raise InvalidFileException(
                    f"The file: {filename} is invalid. the"
                    "filename must ends with .xlsx, bitch."
                )
            if os.path.exists(filename):
                log.info(f"Open the existed file: {filename}")
                wb = load_workbook(filename)
            else:
                log.info(f"Open a new file: {filename}")
                wb = WB()
            wb.filename = filename
            cls.singleton[filename] = wb
        return cls.singleton[filename]

class Validator:
    @staticmethod
    def validate(worksheet):
        # todo, the validating rules is not confirmed.
        pass

class _WorkSheetMixin:
    @staticmethod
    def _gen_col_name() -> t.AnyStr:
        """generate the col_name from A to Z.

        Yields:
            [str]: A B C ... X Y Z"
        """
        _start = 65
        _end = 91

        for i in range(_start, _end):
            yield chr(i)
        raise ValueError("The col nums is too big, which supported only A-Z!")

class Styler:
    def __init__(self, style: t.Union[dict, list]):
        if not isinstance(
            style,
            (
                dict,
                list,
            ),
        ):
            raise TypeError(
                f"the style must be a dict or list, but it's {type(style)}"
            )
        self.style = style
        self._validate()

    def __call__(self, ins: str):
        raise NotImplementedError("The method __call__ must be implemented!")

    def _validate(self):
        raise NotImplementedError("The method validate must be implemented!")

class ColStyler(Styler):
    SUPPORTED_STYLES = {
        "width": int,
    }

    def __init__(self, style: dict):
        if not isinstance(style, dict):
            raise TypeError("the col type must be a dict")
        super().__init__(style)

    def __call__(self, col: str) -> None:
        for k, v in self.style.items():
            setattr(col, k, v)

    def _validate(self):
        "validate the supported style."
        if isinstance(self.style, dict):
            for k, v in self.style.items():
                if not isinstance(v, self.SUPPORTED_STYLES[k]):
                    raise ValueError(
                        f"the style: {self.style} is not supported!"
                    )
        else:
            raise TypeError("The col style must be dict")

class RowStyler(Styler):
    """
    to be padded in the future. Not in use in current.
    """

class CellStyler(Styler):
    """
    The utils class:
        to set the style to a Cell and return it.

    Supported styles:
        `name`:         Font.name
        `style`:        Font.style
        `color`:        Font.color
        `size`:         Font.size
        `bold`:         Font.bold
        `underline`:    Font.underline
        `italic`:       Font.italic
        `vertAlign`:    Font.vertAlign
        `outline`:      Font.outline
        `shadow`:       Font.shadow

        `fgColor`:      PatternFill.fgColor
        `bgColor`:      PatternFill.bgColor
        `fill_type`:    PatternFill.fill_type

        `warpText`:     Alignment

        `width`:        width
        `height`:       height
    """

    SUPPORTED_STYLES = {
        "font": (
            "name",
            "style",
            "color",
            "size",
            "bold",
            "underline",
            "italic",
            "vertAlign",
            "outline",
            "shadow",
        ),
        "pattern_fill": ("fgColor", "bgColor", "fill_type"),
        "alignment": ("warpText",),
        # ...
        # ...
        "others": ("width", "height"),
    }

    def __call__(self, cell: Cell) -> None:

        if isinstance(self.style, dict):
            style = self.style
            self._styled_cell(style, cell)
        if isinstance(self.style, list):
            try:
                # !!! in the first index, whose col_idx is 1 but the index is 0.
                style = self.style[cell.col_idx - 1]
            except IndexError:
                style = None
            self._styled_cell(style, cell)

    def _styled_cell(self, style: dict, cell: Cell) -> None:
        if style:
            self._set_font(cell, style)
            self._set_pattern_fill(cell, style)
            # ...
            # ...
            self._set_others(cell, style)
        return cell

    def _set_font(self, cell: Cell, style: dict) -> None:
        font = Font(
            **{
                k: v
                for k, v in style.items()
                if k in self.SUPPORTED_STYLES["font"]
            }
        )
        cell.font = font

    def _set_pattern_fill(self, cell: Cell, style: dict) -> None:
        pattern_fill = PatternFill(
            **{
                k: v
                for k, v in style.items()
                if k in self.SUPPORTED_STYLES["pattern_fill"]
            }
        )
        cell.fill = pattern_fill

    def _set_aligment(self, cell: Cell, style: dict) -> None:
        alignment = Alignment(
            **{
                k: v
                for k, v in style.items()
                if k in self.SUPPORTED_STYLES["alignment"]
            }
        )
        cell.alignment = alignment

    def _set_others(self, cell: Cell, style: dict) -> None:
        for k, v in style.items():
            if k in self.SUPPORTED_STYLES["others"]:
                setattr(cell, k, v)

    def _validate(self) -> None:
        "validate the supported style."
        supported_styles = sum(self.SUPPORTED_STYLES.values(), ())
        if isinstance(self.style, dict):
            keys = self.style.keys()
        if isinstance(self.style, list):
            keys = set(sum([list(d.keys()) for d in self.style], []))
        else:
            return
        for k in keys:
            if k not in supported_styles:
                raise ValueError(
                    f"The type keyword: {k} is not supproted, the"
                    f"supported keyword is {supported_styles}"
                )

class Style:
    """
    `type_`:
            cell:
            col:
            row:

    """

    def __init__(self, style: t.Union[dict, list], type_: str = "cell"):
        if not style:
            self.styler = lambda x: x
        if type_ == "cell":
            self.styler = CellStyler(style)
        if type_ == "col":
            self.styler = ColStyler(style)
        if type_ == "row":
            self.styler = RowStyler(style)

    def __call__(self, ins):
        """
        Args:
            ins ([Col, Cell, Col]):
        """
        self.styler(ins)

class Col:
    """
    Args:
        self (Col):
        col (str):
        style (dict): supported type see ColStyler doc
        ws (WorkSheet):
    """

    def __init__(self: "Col", col: str, style: dict, ws: "WorkSheet"):
        self.ws = ws.ws
        self.col = self.ws.column_dimensions[col]
        self.style = Style(style, type_="col")

    def set(self):
        self.style(self.col)

class Row:
    """
    Args:
        self (Row):
        row_idx (int):
        style (dict): supported type see RowStyler doc
        ws (WorkSheet):
    """

    def __init__(self: "Row", row_idx: int, style: dict, ws: "WorkSheet"):
        self.ws = ws.ws
        self.row = self.ws.row_dimensions[row_idx]
        self.style = Style(style, type_="row")

    def set(self):
        self.style(self.row)

class Cell_:
    """[summary]

    Args:
        self (Cell_):
        row_idx (int):
        col_idx (int):
        style (dict): supported type see CellStyler doc.
        ws (WorkSheet):
        value ([type], optional):  Defaults to None.
    """

    def __init__(
        self: "Cell_",
        row_idx: int,
        col_idx: int,
        style: dict,
        ws: "WorkSheet",
        value=None,
    ):
        self.ws = ws.ws
        self.cell = self.ws.cell(row=row_idx, column=col_idx, value=value)
        self.style = Style(style)

    def set(self):
        self.style(self.cell)

class IterStyledCell(t.List):
    """
    The styled cell generator, yield the styled cell.
    return the raw data cells if there is not the style param or return the
        styled data otherwise.

    supported parameters see the `Style class`
    """

    def __new__(
        cls: "IterStyledCell",
        data: t.Union[list, dict],
        style: t.Union[list, dict],
        ws: "WorkSheet",
    ) -> "IterStyledCell":
        if not style:
            return data
        else:
            return super().__new__(cls)

    def __init__(
        self: "IterStyledCell",
        data: t.Union[list, dict],
        style: t.Union[list, dict],
        ws: "WorkSheet",
    ):
        self.row_data = data
        # self.style = Style(style)
        if isinstance(style, dict):
            self.style = lambda i: style
        elif isinstance(style, list):
            self.style = lambda i: style[i - 1] if len(style) >= i else {}
        self.ws = ws.ws
        self._cells = self._styled_cells()

    def __iter__(self):
        for cell in self._cells:
            yield cell.cell

    def _styled_cells(self):
        if isinstance(
            self.row_data,
            (
                list,
                tuple,
                range,
            ),
        ):
            yield from self._seq_styled_cells()
        elif isinstance(self.row_data, dict):
            yield from self._map_styled_cells()
        else:
            raise TypeError(
                f"the {type(self.row_data)} of {self.row_data} is unsupported."
            )

    def _seq_styled_cells(self):
        row_idx = self.ws._current_row + 1
        for col_idx, col_val in enumerate(self.row_data, 1):
            cell = Cell_(row_idx, col_idx, self.style(col_idx), self, col_val)
            cell.set()
            yield cell

    def _map_styled_cells(self):
        row_idx = self.ws._current_row + 1
        for col_idx, col_val in self.row_data.items():
            if isinstance(col_idx, str):
                col_idx = column_index_from_string(col_idx)
            cell = Cell_(row_idx, col_idx, self.style(col_idx), self, col_val)
            cell.set()
            yield cell

class WorkSheet(_WorkSheetMixin):
    """if there is the worksheet in the workbook, return it.
       if there is not the worksheet, return a new worksheet.

       the headers is a row that return dict with it as the keys and write to
       excel in dict format with it as the keys.

    Properties:
        `parent`: the workbook instance.

        `ws`: the worksheet instance.

        `headers`: the headers and col_names correspondency in current worksheet.
            {"name": "A", "sex": "B", "age": "C"}

    Args:
        `filename`: the destination file.

        `title`: the sheet title, default is Sheet1.

        `index`: the sheet index, default is 1. if the index is set, the title in invalid.

        `headers_idx`: the headers index in all rows. if there is a headers_idx, the to_dict
                read would start from the headers_idx row.

        `template`: if there is a template, copy it to filename and write to the copy.

        `before_styled`: the style before reading or writing the worksheet.
                        {"A": {"color" :"#0FF00"}}

        `before_styled`: the style after reading or writing but before saving the worksheet.

    """

    CLOSE = True
    SUFFIX = SUPPORTED_FILE_TYPE

    def __init__(
        self,
        filename: str,
        title: t.Optional[str] = "Sheet1",
        index: t.Optional[int] = None,
        headers_idx: t.Optional[int] = 1,
        template: t.Optional[str] = None,
        before_styled: t.Optional[dict] = None,
        after_styled: t.Optional[dict] = None,
    ):
        if template:
            if not os.path.exists(template):
                raise FileNotFoundError(
                    f"The template file: {template} not found!"
                )
            if not template.endswith(self.SUFFIX):
                raise InvalidFileException(
                    f"The file suffix must be {self.SUFFIX}!"
                )
            if template == filename:
                raise InvalidFileException(
                    f"The template file: {template} is the same"
                    f"file as destination file {filename}"
                )
            if os.path.exists(filename):
                raise FileExistsError(
                    f"The destination {filename} is existed, can't override it by tempate file."
                )
            shutil.copyfile(template, filename)

        if not isinstance(headers_idx, int):
            raise TypeError("The headers_idx must be a integer.")
        if headers_idx < 1:
            raise ValueError("The headers_idx must lager than 1.")
        self.headers_idx = headers_idx

        # the headers is None at first, initialized when read or write.
        self.headers = None

        self.before_styled = before_styled or {}
        self.after_styled = after_styled or {}
        assert isinstance(self.before_styled, dict)
        assert isinstance(self.after_styled, dict)

        self._parent_factory = _WorkBook
        parent = self._parent_factory(filename)

        if index or title:
            if index:
                try:
                    self.ws = parent.worksheets[index - 1]
                    log.info(f"open a active sheet, its index: {index-1}.")
                except IndexError as e:
                    raise ValueError(
                        "The index: {index} worksheet is not existed."
                    ) from e
            else:
                for sheet in parent.worksheets:
                    if sheet.title == title:
                        self.ws = parent[title]
                        log.info(f"open the active the sheet: {title}.")
                else:
                    if not hasattr(self, "ws"):
                        self.ws = parent.create_sheet(title)
                        log.info(f"create and open a new sheet: {title}.")
            self._gen_headers()

    def _styled_hook(self, style):
        for k, v in style.items():
            if isinstance(k, int) and k < 65535:
                self.set_row_style(k, v)
            elif (
                isinstance(k, str)
                and len(k) == 1
                and ord(k) > 64
                and ord(k) < 91
            ):
                self.set_col_style(k, v)
            else:
                raise TypeError(
                    "To set a row style in int type keys small than 65535 like: 1, 2, "
                    "the col is in str type keys in range A-Z like :A, B"
                )

    def __enter__(self) -> "WorkSheet":
        self._styled_hook(self.before_styled)
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        if exc_type:
            self.close(save=False)
            log.warning(
                f"Error: {exc_type}, msg: {exc_value}, traceback: {traceback}"
            )
        else:
            self._styled_hook(self.after_styled)
            self.close()

    def _gen_headers(self, max_col: t.Optional[int] = None):
        """
        like this:
            {"name": "A", "sex": "B", "age": "C", ...}
        """
        col_names = self._gen_col_name()
        for i, row in enumerate(
            self.ws.iter_rows(max_col=max_col, values_only=True), start=1
        ):
            if i == self.headers_idx:
                self.headers = {col: next(col_names) for col in row}
                col_names.close()
                return

    def close(self, save=True):
        """
        save and close the workbook, and drop the singleton.
        """
        try:
            if save:
                self.ws.parent.save(self.ws.parent.filename)
            self.ws.parent.close()
        except:
            log.error(traceback.format_exc())
        finally:
            self._parent_factory.singleton.pop(self.ws.parent.filename)

    def validate(self):
        pass

    def to_dict(
        self,
        max_col: t.Optional[None] = None,
        show_col_names: bool = False,
        col_mapping: t.Optional[t.Mapping] = None,
    ) -> t.Generator:
        """yield the content as dict.
           if the excel like this:

                A       B       C       ...
                name     sex     age     ...
                xiaomi   female  1       ...
                lulu     male    2       ...

           if the show_col_names paramter is True:

                yield:
                    {"A": "name", "B": "sex", "C": "age"},
                    {"A": "xiaomi", "B": "female", "C": "1"},
                    {"A": "xiaomi", "B": "female", "C": "2"},
           else:
                yield:
                    {"name": "xiaomi", "sex": "female", "age": "1"},
                    {"name": "xiaomi", "sex": "female", "age": "2"},

        Args:
            `max_col`: how many lines would to read. return whole col if there
                is not a value.

            `show_col_names` (bool, optional): Defaults to False. see on the above.

            `col_mapping` (Union[bool, Dict], optional):
                for example:
                    the previous data: {"name": "男孩", "sex": "女孩", "age": "李韬"}
                    while the re_col = {"name": "名字", "sex": "性别"}
                    the after data: {"名字": "男孩", "性别": "女孩", "age": "李韬"}
                important: only function in the show_col_names is False.

        Yields:
            [Dict]: ...
        """
        if max_col:
            if not isinstance(max_col, int):
                raise TypeError("The max_col must be a integer.")
            if max_col < 1 or max_col > 26:
                raise ValueError(
                    "The max_col range must in 1 ~ 26, corresponding to"
                    "the alpha A ~ Z"
                )
        if not col_mapping:
            col_mapping = {}
        if show_col_names and col_mapping:
            log.warning(
                f"If show_col_names is set to True, the col_mapping param would be ignored."
            )
            col_mapping = {}
        for i, row in enumerate(
            self.ws.iter_rows(
                min_row=self.headers_idx, max_col=max_col, values_only=True
            )
        ):
            if not any(row):
                # jump the blank line
                continue
            if not self.headers:
                # generagte the self.headers. and write the headers to current sheet.
                self._gen_headers(max_col=max_col)
                if show_col_names:
                    yield {
                        v: k for k, v in list(self.headers.items())[:max_col]
                    }
                continue
            if show_col_names:
                yield {
                    k: v
                    for k, v in list(zip(self.headers.values(), row))[:max_col]
                }
            else:
                # drop the first row, which's the headers.
                if i == 0:
                    continue
                yield {
                    col_mapping.get(k, k): v
                    for k, v in list(zip(self.headers, row))[:max_col]
                }

    def append(
        self,
        iterable: t.Union[
            dict,
            list,
            tuple,
        ],
        style=None,
    ):
        """append a row to the worksheet.
            if the iterable is a iterable:
                if current_row is 0(means the first row) or there is not a header
                    in self, it will be the headers.
                if the current_row is not 0, it will append to the next row.
            if the iterable is a dict:
                if the current_row is 0 or there is not a header in self, it will
                    be the headers
                else append the iterable to the next row.

            IMPORTANT:
            support for dict append. if there is a headers already, the append
            will insert the value whose keys included in self.headers only.

        Args:
            `iterable` (Union[List, Dict, Tuple, range]):

            `style` (Optional[Union[Dict, List]]):
                Suppose that the row like this:
                    {"name": "xiaomi", "B": "female", "C": "1"}
                1. if the style is None:
                    return the raw row.
                2. if the style is dict: {"color": "00FF00FF"}:
                    the all cells in the row would be red style.
                3. if the style is list whose lenght is equal to the row:
                    such as: [  {"color": "00FF00FF"},
                                {"color": "00FF00FF"},
                                {"color": "00FF00FF"},]:
                    the style and the cell will be corresponding in the sequence.
                4. if the style is list but which's longer or shorter than the row's length:
                    the style adn the cell will be corresponding in the sequence.
                    if there is not the style in some cells, jump it.

        Raises:
            `ValueError`: ...
            `TypeError`: if the iterable's type is not in list, tuple and dict.
        """
        if isinstance(
            iterable,
            (
                list,
                tuple,
            ),
        ):
            if not self.headers:
                self._gen_headers()
            self.ws.append(IterStyledCell(iterable, style, self))
        elif isinstance(iterable, dict):
            if not self.headers:
                col_names = self._gen_col_name()
                self.headers = {k: next(col_names) for k in iterable}
                self.ws.append(
                    IterStyledCell(
                        [header for header in self.headers], style, self
                    )
                )
            self.ws.append(
                IterStyledCell(
                    {v: iterable.get(k) for k, v in self.headers.items()},
                    style,
                    self,
                )
            )
        else:
            raise TypeError(
                f"There is a unsupported type: {type(iterable)} for data: {iterable}."
                f"The data must in tuple, list or dict."
            )

    def set_row_style(self, row_idx: int, style: dict) -> None:
        row = Row(row_idx, style, self)
        row.set()

    def set_col_style(self, col_name: str, style: dict) -> None:
        col = Col(col_name, style, self)
        col.set()

    def set_cell(
        self, row_idx: int, col_idx: int, style: dict, value=None
    ) -> None:
        cell = Cell_(row_idx, col_idx, style, self, value)
        cell.set()

if __name__ == "__main__":
    with WorkSheet("test_bbb.xlsx", title="Sheet8") as ws:
        ws.append(
            "name",
        )


from requests import request as rq

class Service:

    def request(self, session: object, method: str, params: dict = {},
                payload: dict = {}, headers: dict = {}) -> dict | None:
        """request method

        Args:
            session (object): credentials object
            method (str): select https method
            url (str): url endpoint
            params (dict, optional): parameters. Defaults to {}.
            payload (dict, optional): data. Defaults to {}.
            headers (dict, optional): headers. Defaults to {}.

        Returns:
            dict | None: server response
        """

        response = rq(method,
                      session.url,
                      data=payload,
                      params=session.signature(params),
                      headers=headers)

        if response.status_code == 200:

            return response.json()

        return None


model_path='car_brand/carBrand_model.h5'
image_path1='car_brand/Acura_NSX.jpg'
image_path2='car_brand/Acura_ILX.jpg'
image_path3='car_brand/Acura_MDX.jpg'
image_path4='car_brand/Aston Martin_Vanquish.jpg'
image_path5='car_brand/Audi_TT.jpg'
image_path6='car_brand/Alfa Romeo_Giulia.jpg'
image_path7='car_brand/Audi_A6.jpg'
image_path8='car_brand/Audi_Q5.jpg'
image_path9='car_brand/Audi_e-tron.jpg'
image_path10='car_brand/Aston Martin_DBS.jpg'
brand_name='car_brand/brand_name.csv'
def pred_car_brand(model_path,image_path,brand_name):
    from tensorflow.keras.models import load_model
    import cv2
    import numpy as np

    model=load_model(model_path)
    img1=cv2.imread(image_path)
    resized_img1=cv2.resize(img1,(100,100))
    y_pred_1=model.predict(resized_img1[None,...])
    y_pred_1_classe=np.argmax(y_pred_1)
    data = open(brand_name, encoding="utf8").read()
    corpus = data.split("\n")
    for i in corpus:
        if i == "":
            corpus.remove('')
    corpus = corpus[1:-1]
    return corpus[y_pred_1_classe]
print(pred_car_brand(model_path,image_path1,brand_name))
print(pred_car_brand(model_path,image_path2,brand_name))
print(pred_car_brand(model_path,image_path3,brand_name))
print(pred_car_brand(model_path,image_path4,brand_name))
print(pred_car_brand(model_path,image_path5,brand_name))
print(pred_car_brand(model_path,image_path6,brand_name))
print(pred_car_brand(model_path,image_path7,brand_name))
print(pred_car_brand(model_path,image_path8,brand_name))
print(pred_car_brand(model_path,image_path9,brand_name))
print(pred_car_brand(model_path,image_path10,brand_name))

DEEP LEARNING/projet assurance/car brand part/car_brand/brand_pred.py


# validation script that does a pass over the val set
# currently set up for directml

import torch
import torch.cuda.amp
import torch.nn as nn
import torch.nn.parallel
import torch.profiler
import torch.optim as optim
import torch.utils.data
import torchvision
import torchvision.datasets as dset
from torchvision import models, transforms
from torchvision.io import read_image
import torchvision.utils as vutils
import numpy as np
import time
import glob
import gc
import pandas as pd
import os
import timm
from PIL import Image, ImageOps, ImageDraw
import PIL
from timm.data import IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD
from timm.models.metaformers import default_cfgs as default_cfgs

def test_model(model, crop):

    modelName = model.pretrained_cfg["architecture"]
    modelTag = model.pretrained_cfg["tag"]

    FLAGS = {}

    FLAGS['interpolation'] = torchvision.transforms.InterpolationMode.BICUBIC
    FLAGS['image_size'] = model.default_cfg['input_size'][2]
    FLAGS['crop'] = crop

    FLAGS['rootPath'] = "/media/fredo/KIOXIA/Datasets/imagenet/data/"
    FLAGS['imageRoot'] = FLAGS['rootPath'] + 'val/'

    FLAGS['batch_size'] = 64

    FLAGS['image_size_initial'] = int(round(FLAGS['image_size'] // FLAGS['crop']))

    transform = transforms.Compose([
        transforms.Resize(FLAGS['image_size_initial'], interpolation = FLAGS['interpolation']),
        transforms.CenterCrop((int(FLAGS['image_size']),int(FLAGS['image_size']))),
        transforms.ToTensor(),
        transforms.Normalize(IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD)
    ])
    dataset = torchvision.datasets.ImageFolder(FLAGS['imageRoot'], transform=transform)

    loader = torch.utils.data.DataLoader(dataset,
        batch_size = FLAGS['batch_size'],
        shuffle=True,
        num_workers=10,
        prefetch_factor=2,
        pin_memory = True,
        generator=torch.Generator().manual_seed(42))

    #model = timm.create_model('convformer_b36.sail_in22k_ft_in1k_384', pretrained=True)
    #import metaformer_baselines
    #model = metaformer_baselines.identityformer_s12v1(pretrained=True)
    model.eval()
    #print("got model")

    #import torch_directml
    #device = torch_directml.device()
    #device = torch.device('cpu')
    #device = torch.device("mps")

    device = torch.device("cuda:1" if torch.cuda.is_available() else "cpu")
    #print(device)
    model = model.to(device)

    #model = torch.jit.script(model)
    #model = torch.jit.optimize_for_inference(model)

    #print("starting run")

    startTime = time.time()
    cycleTime = time.time()
    samples = 0
    correct = 0
    stepsPerPrintout = 100

    for i, (images, tags) in enumerate(loader):
        imageBatch = images.to(device, non_blocking=True)
        tagBatch = tags.to(device, non_blocking=True)
        #tagsOneHot = torch.nn.functional.one_hot(tags, num_classes = len(classes)).to(device, non_blocking=True)
        with torch.set_grad_enabled(False):
            outputs = model(imageBatch)
            preds = torch.argmax(outputs, dim=1)
            samples += len(images)
            correct += sum(preds == tagBatch)

        '''
        if i % stepsPerPrintout == 0:
            accuracy = 100 * (correct/(samples+1e-8))
            imagesPerSecond = (FLAGS['batch_size']*stepsPerPrintout)/(time.time() - cycleTime)
            cycleTime = time.time()

            print('[%d/%d]\tImages/Second: %.4f\ttop-1: %.2f' % (i, len(loader), imagesPerSecond, accuracy))
        '''

    print(f'model: {modelName}.{modelTag}, crop: {crop}, top-1: {100 * (correct/samples)}%, spent {(time.time() - startTime):.0f} seconds')
    model = model.cpu()
    del model

def main():
    models = default_cfgs.keys()
    crop_bins=[1.00, 0.975, 0.95, 0.925, 0.90, 0.875, 0.85, 0.825, 0.8, 0.75]
    print('starting run')
    for currModel in models:
        for cfg in list(default_cfgs[currModel].cfgs.keys()):
            if 'in1k' in cfg:
                model = timm.create_model(currModel+'.'+cfg, pretrained=True)
                for currCrop in crop_bins:
                    test_model(model, currCrop)

if __name__ == '__main__':
    main()


# -*- coding: utf-8 -*-
"""
Created on Sat Dec  5 13:02:13 2020

@author: tonian
"""

import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
from linearstatistics import linestatistics as lstats

pckfile = '308.txt'
pckdata = pd.read_csv(pckfile, sep="\s", header=None)
show_slopebreaks = 'true'

pckdata.columns = ["dist", "time"]

x = np.array(pckdata.dist)
y = np.array(pckdata.time)

nPts = len(x); #number of Points in each time series

#Plotting
plt.plot(x,y, 'b-o', label='1st Arrival Pcks')
#plt.title("Displacment for PS Point %i" %(in_ID))
plt.ylabel('Time (ms)',fontsize=15)
plt.xlabel('Distance (m)',fontsize=15)

# Define range of "kinks" to test for a slope break in best fit line
firstkink = 3; #allowing the kinks to start after the first 3 data Points (remember python indices start at 1 so the first kink is at #4); this is the location of the kink as it relates to the extracted 56 data Pointss
lastkink = nPts-3;#:nPts; #leaving 4 data points for the last kink
kinks = np.arange(firstkink, lastkink+1);
nKinks = len(kinks);

#------------CREATING ARRAYS TO STORE INFORMATION----------------------#
b = np.zeros((nKinks,4)); #stores best-fitting parameters from 2-line fit for all positions
yfitk = np.zeros((nPts,1)); #empty array for all kinked lines
yfitminslopeuncertaintyk = np.zeros(nKinks); #empty array for y values of minslopeuncertaintyk (shows optimum kink point)
minslopeuncertaintyk = np.zeros(2); #creating empty array to store max Rsquared values for kinked lines
kinkpos = np.zeros(1); #creating empty array to store corresponding time values for max Rsquared values
yfitkinkline = np.zeros((1,nPts)); #empty array for saving y fit values caluclated with kink location (basically plots kink line)
bminslopeuncertaintyk = np.zeros(4); #b values that correspond to the min slopeuncertaintyk value #b(1) intercept of line 1 for nth position
#b(2)#slope of line 1, b(3)intercept of second line added past kink Points, b(4) slope of second line added past kink Points
A = np.zeros((nPts,4))
D = []

#--------Best Fit Two Lines With Kink------------------------
bk = np.zeros((1,4)); # make bk array to store best-fit coefficients for each kink time
statistics_k1 = np.zeros((nKinks,5)) # make statistics array to for each kink time for 1st slope
statistics_k2 = np.zeros((nKinks,5)) # make statistics array to for each kink time for 2nd slope

#-----------Begin finding slope breaks------------------------------------
nk = -1; # make counter for kinks
for ik in range(firstkink,lastkink+1):
    nk = nk+1;
    D = np.zeros(nPts);
    D[ik:nPts+1] = 1;  # for Pointss with D = 1 second line is added; letting the first 3 points = 0

    # build A array , for which y = A * b and b = A\y
    A[:,0] = np.ones(nPts)
    A[:,1] = x
    A[:,2] = D
    A[:,3] = np.multiply(D,x)

    bk = np.linalg.lstsq(A,y)[0]; #calculating b array using the linear algebra - least squares from numpy (has to be least squares becasue the A matrix is not a perfect square)
    #input('Press ENTER to continue');

    #store b (array of 4) into the bk row for this kink time
    b[nk,:] = bk; #using the corresponding b array to calculate the yfit value for each Points

    #compute the yfit best-fitting line with kink through the data
    yfitk = bk[0] + bk[1]*x + bk[2]*D + bk[3]*D*x

    if show_slopebreaks == 'true':
        # -------Plot kinks------
        #random colors for fun
        rc = np.random.rand(1)
        bc = np.random.rand(1)
        gc = np.random.rand(1)
        color = (rc[0], gc[0], bc[0])
        plt.plot(x,yfitk, c=color, linewidth=1,)
    elif show_slopebreaks == 'false':
        pass

    # Compute line statistics for 1st slope, function returns [m, b, m_uncertainty, b_uncertainty,  R2]
    statistics_k1[nk,:] = lstats(x[0:ik],y[0:ik])

    # Compute slope uncertainty for 2nd slope, function returns [m, b, m_uncertainty, b_uncertainty,  R2]
    statistics_k2[nk,:] = lstats(x[ik-1:nPts],y[ik-1:nPts]) # want points to cross over the "kink point"

#-------------end of for loop for for finkding slope breaks---------------------

#Finding minimum combination of slope R2 for all kink lines
sq_combo = np.square(statistics_k1[:,2]) + np.square(statistics_k2[:,2])
[mincombo_min,mincombo_index] = [np.amin(sq_combo),np.where(sq_combo == sq_combo.min())];
#np.where(a == a.min())

#Storing minimum slope uncertainties
minslopeuncertaintyk[0] = statistics_k1[mincombo_index,2];
minslopeuncertaintyk[1] = statistics_k2[mincombo_index,2];

bminslopeuncertaintyk[0:4] = b[mincombo_index,0:4]; #finding
#corresponding b values for each minslopeuncertaintyk; this is done before finding
#the kink times because the b array is 48+/-2 (based on site) cells long

posminslopeuncertaintyk = mincombo_index[0]+2; #adding the 3 points
#that were excluded from the first kink, to find positions on whole
#array

kinkpos = x[posminslopeuncertaintyk];#finding
#corresponding time location for min slopeuncertaintyk values

#----------RECALULATING Y VALUES FOR BEST FITTED KINK LINE----------#

#Recreating the D vector to calculate the yfit for the minslopeuncertaintyk
Dminslopeuncertaintyk = np.zeros(nPts);
Dminslopeuncertaintyk[posminslopeuncertaintyk[0]:nPts] = 1;

yfitminslopeuncertaintyk = ((bminslopeuncertaintyk[0]) + (bminslopeuncertaintyk[1])*x + (bminslopeuncertaintyk[2])*Dminslopeuncertaintyk + (bminslopeuncertaintyk[3])*Dminslopeuncertaintyk*x);
yfitkinkline = yfitminslopeuncertaintyk; #saving yfit line with kink for future plotting

#---------Plotting final Slope Break
#plt.plot(x,yfitminslopeuncertaintyk, 'y-')
#plt.title("Displacment for PS Point %i" %(in_ID))

x_direct = x[0:posminslopeuncertaintyk[0]+1]
y_direct = y[0:posminslopeuncertaintyk[0]+1]

x_refract = x[posminslopeuncertaintyk[0]:nPts]
y_refract = y[posminslopeuncertaintyk[0]:nPts]

#------- Computing final slope statistics and labeling direct and refreacted waves
# Compute line statistics for 1st slope, function returns [m, b, m_uncertainty, b_uncertainty,  R2], for final slope break
statistics_s1 = lstats(x_direct,y_direct)

# Compute slope uncertainty for 2nd slope, function returns [m, b, m_uncertainty, b_uncertainty,  R2]
statistics_s2 = lstats(x_refract,y_refract) # want points to cross over the "kink point"

if np.abs(statistics_s1[0]) < np.abs(statistics_s2[0]) :
         print('\n>>> !ERROR! You may have an hidden layer problem, your direct wave has a much faster velocity (higher absolute slope) OR you did not start picking from time (0)!')

if statistics_s1[0] and statistics_s2[0] < 0: #if slopes neg they are reverse shot
    rotn = -180
    vanchor = 'baseline' #'top', 'bottom', 'center', 'baseline', 'center_baseline'
    hanchor = 'left' #'center', 'right', 'left'

elif statistics_s1[0] and statistics_s2[0] > 0:
    rotn = 0
    vanchor = 'baseline'
    hanchor = 'center'

plt.title('SEG2 First Arrivals Pcks from: %s'%(pckfile),fontweight ="bold")

label_s1 = 'Direct Wave'
label_s2 = 'Refracted Wave'
color1 = (0.1, 0.7, 0.1)
color2 = (0.9, 0.1, 0.1)
m_dir = statistics_s1[0]
m_refract = statistics_s2[0]
b_dir = statistics_s1[1]
b_refract = statistics_s2[1]

#Adding trendline for slope 1
z1 = np.polyfit(x_direct, y_direct, 1)
p1 = np.poly1d(z1)
plt.plot(x_direct,p1(x_direct),c = color1,linewidth=3, label=label_s1)

#Adding trendline for slope 2
z2 = np.polyfit(x_refract,y_refract, 1)
p2 = np.poly1d(z2)
plt.plot(x_refract,p2(x_refract),c = color2,linewidth=3,label=label_s2)

plt.axvline(x= kinkpos,c=(1,.2,1), color = 'r')

plt.legend(fontsize=15)

# =============================================================================
#         #Just to move eqns up and down
#         delta_ydirect = y_direct[3] - y_direct[0]
#         delta_xdirect = x_direct[3] - x_direct[0]
#         delta_yrefract = y_refract[3] - y_refract[0]
#         delta_xrefract = x_refract[3] - x_refract[0]
# =============================================================================

# Tranformations & Locations to plot eqn text
T1_direct = plt.gca().transData.transform_point((x_direct[0], y_direct[0]))
T2_direct = plt.gca().transData.transform_point((x_direct[-1], y_direct[-1]))
dy_direct = (T2_direct[1] - T1_direct[1])
dx_direct = (T2_direct[0] - T1_direct[0])
angle_direct = np.degrees(np.arctan2(dy_direct, dx_direct))
txt1 = np.array((np.median(x_direct), np.median(y_direct)))

T1_refract = plt.gca().transData.transform_point((x_refract[0], y_refract[0]))
T2_refract = plt.gca().transData.transform_point((x_refract[-1], y_refract[-1]))
dy_refract = (T2_refract[1] - T1_refract[1])
dx_refract = (T2_refract[0] - T1_refract[0])
angle_refract = np.degrees(np.arctan2(dy_refract, dx_refract))
txt2 = np.array((np.median(x_refract), np.median(y_refract)))

   # print(delta_ydirect, delta_xrefract, delta_ydirect, delta_xdirect)

#Plot text
plt.text(txt1[0], txt1[1], 'y = %0.3fx + %0.3f'%(m_dir,b_dir), fontsize=16, ha=hanchor, va=vanchor,
               rotation=angle_direct+rotn)

plt.text(txt2[0], txt2[1], 'y = %0.3fx + %0.3f'%(m_refract,b_refract), fontsize=16, ha=hanchor, va=vanchor,
               rotation=angle_refract+rotn)


#!/usr/bin/env python3

from sys import exit
import requests
from datetime import datetime
import uuid

SESSION_ID=uuid.uuid4().hex
START_TIME=datetime.now()
LOADING_ANIMATION=['|', '/', '-', '\\']

PAGESIZE = 100
SEARCH_TYPE='product'
URL='https://www.vinmonopolet.no/api'
SEARCH_URL='{}/search?q=:relevance:visibleInSearch:true&searchType={}&pageSize={}&currentPage='.format(URL, SEARCH_TYPE, PAGESIZE)
PRODUCT_URL='{}/products'.format(URL)

ELASTIC_URL='http://localhost:9200'
WINE_INDEX='{}/wines-{}'.format(ELASTIC_URL, START_TIME.strftime("%Y.%m.%d"))

CURRENT_PAGE=0
TOTAL_PAGES=-1

elasticIndexedWineIds = 0

class ElasticNotFound(Exception):
  def __init__(self):
    self.message = 'Elastic not available at: {}'.format(ELASTIC_URL)
    super().__init__(self.message)

def checkElastic():
  try:
    r = requests.get(ELASTIC_URL)
    if r.status_code != 200: raise ElasticNotFound
    return
  except:
    raise ElasticNotFound

def addWineToElastic(wine):
  global elasticIndexedWineIds

  url = '{}/_doc'.format(WINE_INDEX)
  data = {
    "@timestamp": str(datetime.now().isoformat()),
    "wine": wine,
    "session_id": SESSION_ID,
    "search_type": SEARCH_TYPE,
    "current_page": CURRENT_PAGE,
    "total_pages": TOTAL_PAGES,
    "batch_size": PAGESIZE
  }

  r = requests.post(url, json=data)
  wineInsertResponse = r.json()
  result = wineInsertResponse['result']
  if (result != "created"):
    print('Error! from elastic wine insert:')
    print(wineInsertResponse.json())
  else:
    elasticIndexedWineIds += 1

def fetchWine(wineId):
  url = '{}/{}/?fields=FULL'.format(PRODUCT_URL, wineId)
  wineResponse = requests.get(url)
  wine = wineResponse.json()
  addWineToElastic(wine)

def fetchPage(page):
  global TOTAL_PAGES

  print('\nSearching products at page {}/{}'.format(page, TOTAL_PAGES if TOTAL_PAGES > 0 else '?' ))
  url = '{}{}'.format(SEARCH_URL, page)
  r = requests.get(url)
  results = r.json()

  productResults = results['productSearchResult']
  currentPage = productResults['pagination']['currentPage']
  if (TOTAL_PAGES == -1):
    TOTAL_PAGES = productResults['pagination']['totalPages']

  products = productResults['products']
  print('Search found {} products'.format(len(products)))

  start = datetime.now()
  frame = 0
  for index, product in enumerate(products):
    fetchWine(product['code'])
    print(' {} Indexed {} of {} products'
      .format(LOADING_ANIMATION[frame], index+1, len(products)), end='\r')
    frame += 1
    if (frame == len(LOADING_ANIMATION)):
      frame = 0

  end = datetime.now()
  print('Finised adding {} wines to elastic index'.format(len(products)))
  print('Total products indexed: {}'.format(elasticIndexedWineIds))
  print('It took: {}, total time: {}'.format(end - start, end - START_TIME))

def main():
  global CURRENT_PAGE, TOTAL_PAGES

  while CURRENT_PAGE < TOTAL_PAGES or TOTAL_PAGES == -1:
    fetchPage(CURRENT_PAGE)
    CURRENT_PAGE += 1

  print('Total wines added to elastic: {}'.format(elasticIndexedWineIds))

if __name__ == '__main__':
  try:
    checkElastic()
    main()
  except KeyboardInterrupt:
    print('\n\nKeyboard interrupt.. exiting!')
    print('Was at page {} of {}. Total indexed products where: {}'.format(CURRENT_PAGE, TOTAL_PAGES, elasticIndexedWineIds))
    exit(0)


import torch.nn as nn
from .video_frontend import Lipreading

class Transformer(nn.Module):
    """An encoder-decoder framework only includes attention.
    """

    def __init__(self, encoder, decoder):
        super(Transformer, self).__init__()
        self.encoder = encoder
        self.decoder = decoder
        self.lipreading = Lipreading(hiddenDim=512, embedSize=256)

        for p in self.parameters():
            if p.dim() > 1:
                nn.init.xavier_uniform_(p)

    def forward(self, padded_input, padded_target):
        """
        Args:
            padded_input: N x Ti x D
            input_lengths: N
            padded_targets: N x To
        """
        #print(padded_input.size())
        padded_input = padded_input.unsqueeze(4)    ###gray
        #print(padded_input.size())
        padded_input = padded_input.permute(0,4,1,2,3)
        #print(padded_input.size())
        padded_input = self.lipreading(padded_input)
        length = padded_input.size(1)
        batch = padded_input.size(0)
        #print('length is: ', length)
        input_lengths = [len(padded_input[i]) for i in range(batch)]

        #print(padded_input.size(), input_lengths)
        encoder_padded_outputs, *_ = self.encoder(padded_input, input_lengths)
        # pred is score before softmax
        #print(encoder_padded_outputs.size())
        pred, gold, *_ = self.decoder(padded_target, encoder_padded_outputs,
                                      input_lengths)
        #print(pred.size(), max(pred.size(1)))
        return pred, gold

    def recognize(self, input, char_list, args):
        """Sequence-to-Sequence beam search, decode one utterence now.
        Args:
            input: T x D
            char_list: list of characters
            args: args.beam
        Returns:
            nbest_hyps:
        """
        #input = input.unsqueeze(0)
        input = input.permute(0,4,1,2,3)
        #print(input.size())
        input = self.lipreading(input)
        #print(input.size())
        length = input.size(1)
        batch = input.size(0)
        #print('length is: ', length)
        input_lengths = [len(input[i]) for i in range(batch)]

        #input_length = input.size(1)

        #encoder_outputs, *_ = self.encoder(input.unsqueeze(0), input_lengths)
        #total_preds = []
        encoder_outputs, *_ = self.encoder(input, input_lengths)
        #for n in range(batch):
            #pred = []
        nbest_hyps = self.decoder.recognize_beam(encoder_outputs,
                                                 char_list,
                                                 args)
        #total_preds.append(nbest_hyps[0]['yseq'])
        return nbest_hyps


import cv2
import matplotlib.pyplot as plt

img = cv2.imread('image/3.jpg')
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img_dx = img_gray.copy()
img_dy = img_gray.copy()

for j in range(img_gray.shape[1]):
    for i in range(img_gray.shape[0] - 1):
        img_dx[i][j] = img_gray[i + 1][j] - img_gray[i][j]

for i in range(img_gray.shape[0]):
    for j in range(img_gray.shape[1] - 1):
        img_dy[i][j] = img_gray[i][j + 1] - img_gray[i][j]

img_res = img_gray.copy()
for i in range(img_gray.shape[0]):
    for j in range(img_gray.shape[1]):
        img_res[i][j] = max(0, min(img_res[i][j] - (img_dx[i][j] + img_dy[i][j]), 255))

plt.subplot(3, 2, 1)
plt.imshow(img, cmap='gray')
plt.title('Original')
plt.xticks([])
plt.yticks([])

plt.subplot(3, 2, 2)
plt.imshow(img_gray, cmap='gray')
plt.title('Gray')
plt.xticks([])
plt.yticks([])

plt.subplot(3, 2, 3)
plt.imshow(img_dx, cmap='gray')
plt.title('img_dx')
plt.xticks([])
plt.yticks([])

plt.subplot(3, 2, 4)
plt.imshow(img_dy, cmap='gray')
plt.title('img_dy')
plt.xticks([])
plt.yticks([])

plt.subplot(3, 2, 5)
plt.imshow(img_res, cmap='gray')
plt.title('img_res')
plt.xticks([])
plt.yticks([])

plt.show()


'''
将voc格式数据转化成 yolo training 格式
'''
import xml.etree.ElementTree as ET
from os import getcwd
import os

# 扫描数据
sets=[('2012', 'train'), ('2012', 'val')]
# 类型
classes = ["text"]
ROOTPATH = r'C:\Users\hupan\Desktop\Data'

Xml_list_File = 'VOCdevkit/VOC%s/Annotations/%s.xml'
Xml_list_File_abs = os.path.join(ROOTPATH,Xml_list_File)
def convert_annotation(year, image_id, list_file):
    in_file = open(Xml_list_File_abs%(year, image_id))
    tree=ET.parse(in_file)
    root = tree.getroot()

    for obj in root.iter('object'):
        difficult = obj.find('difficult').text
        cls = obj.find('name').text
        if cls not in classes or int(difficult)==1:
            continue
        cls_id = classes.index(cls)
        xmlbox = obj.find('bndbox')
        b = (int(xmlbox.find('xmin').text), int(xmlbox.find('ymin').text), int(xmlbox.find('xmax').text), int(xmlbox.find('ymax').text))
        list_file.write(" " + ",".join([str(a) for a in b]) + ',' + str(cls_id))

# 当前目录
wd = getcwd()

Train_list_File = 'VOCdevkit/VOC%s/ImageSets/Main/%s.txt'
Train_list_File_abs = os.path.join(ROOTPATH,Train_list_File)

Image_File = 'VOCdevkit/VOC%s/JPEGImages/%s.jpg'
Image_File_abs = os.path.join(ROOTPATH,Image_File)

for year, image_set in sets:

    # 获取train val test信息
    file_name = Train_list_File_abs%(year, image_set)
    print(file_name)
    image_ids = open(file_name).read().strip().split()
    # 导出数据名称
    list_file = open('%s_%s.txt'%(year, image_set), 'w')
    for image_id in image_ids:
        list_file.write(Image_File_abs%(year, image_id))
        convert_annotation(year, image_id, list_file)
        list_file.write('\n')
    list_file.close()


from random import randint

number_to_find = randint(0, 100)
remaining_attempts = 5

print("*** Le jeu du nombre mystère ***")

while remaining_attempts > 0:
    print(f"Il te reste {remaining_attempts} essai{'s' if remaining_attempts > 1 else ''}")

    user_choice = input("Devine le nombre : ")
    if not user_choice.isdigit():
        print("Veuillez entrer un nombre valide.")
        continue

    user_choice = int(user_choice)

    if number_to_find > user_choice:
        print(f"Le nombre mystère est plus grand que {user_choice}")
    elif number_to_find < user_choice:
        print(f"Le nombre mystère est plus petit que {user_choice}")
    else:
        break

    remaining_attempts -= 1

if remaining_attempts == 0:
    print(f"Dommage ! Le nombre mystère était {number_to_find}")
else:
    print(f"Bravo ! Le nombre mystère était bien {number_to_find} !")
    print(f"Tu as trouvé le nombre en {6 - remaining_attempts} essai")

print("Fin du jeu.")


import numpy as np
import regions
from astropy import units as u
from astropy.modeling import models, fitting
from astropy import wcs
from astropy import coordinates
from astropy.io import fits
from astropy import convolution
from spectral_cube import SpectralCube
import pvextractor
from gaussfit_catalog.core import gaussfit_image
import paths
import os
import pylab as pl
import shapely.geometry as geom
from show_pv import show_keplercurves, show_pv
import imp
import edge_on_ring_velocity_model
from astropy.utils.console import ProgressBar
from constants import vcen as assumed_vcen, origin, d_orion
import tracemalloc
from astropy import log

imp.reload(edge_on_ring_velocity_model)
from edge_on_ring_velocity_model import thindiskcurve, thindiskcurve_fitter, trace_plotter

first_snapshot = tracemalloc.take_snapshot()

if 'cached_gaussfit_results' not in locals():
    cached_gaussfit_results = {}

fitresult_list = []

for linename,(vmin,vmax),limits,(cenx, ceny) in (
    #('Unknown_4', (-15, 27), (-0.1, 0.1, -0.12, 0.12), (65.1, 60.5)),
    #('H2Ov2=1_5(5,0)-6(4,3)', (-28, 38), (-0.2, 0.2, -0.2, 0.2), (68.8, 65.5)),
    #('Unknown_1', (-15, 27), (-0.1, 0.1, -0.12, 0.12), (65.1, 60.5)),
    #('Unknown_2', (-15, 27), (-0.1, 0.1, -0.12, 0.12), (65.1, 60.5)),
    ('SiOv=1_5-4', (-30, 45), (-0.2, 0.2, -0.2, 0.2), (65.1, 60.5)),
   ):

    regs = regions.Regions.read(paths.rpath('velo_centroid_guesses_{linename}.reg').format(linename=linename))

    guesses = {}

    for reg in regs:
        vel = float(reg.meta['text'].strip("{}")
                    if 'text' in reg.meta
                    else reg.meta['label']
                   )
        if vel in guesses:
            guesses[vel].append(reg)
        else:
            guesses[vel] = [reg]

    velocities = np.array(sorted(guesses.keys()))*u.km/u.s

    cubefn = paths.dpath('cubes/OrionSourceI_{linename}_robust0.5maskedclarkclean10000_medsub_K.fits'
                         .format(linename=linename))
    basename = os.path.splitext(os.path.basename(cubefn))[0]
    cube = SpectralCube.read(cubefn)

    # hard-coded icrs radecsys assumed
    assert cube.header['RADESYS'] == 'ICRS'

    vdiff = np.abs(np.diff(cube.spectral_axis).mean())
    rms = cube.std()
    weights = np.ones(cube.shape[1:]) * rms.value**2

    try:
        beam = cube.beam
    except AttributeError:
        beam = cube.average_beams(1)
    pixscale = wcs.utils.proj_plane_pixel_area(cube.wcs.celestial)**0.5 * u.deg
    bmmaj_px = (beam.major / pixscale).decompose().value
    bmmin_px = (beam.minor / pixscale).decompose().value
    max_radius_in_beams = 1.25
    max_offset_in_beams = 1.5

    STDDEV_TO_FWHM = np.sqrt(8*np.log(2))

    results = {}

    if linename in cached_gaussfit_results:
        print("Loading {0} from cache".format(linename))
        results = cached_gaussfit_results[linename]
    else:
        print("Fitting {0}, which is not in cache".format(linename))
        pb = ProgressBar(cube.shape[0])

        for vel,vslice in (zip(cube.spectral_axis, cube)):
            closest = np.argmin(np.abs(vel-velocities))
            if np.abs(velocities[closest] - vel) > vdiff:
                #print("Skipping velocity {0}, closest is {1} -> {2}".format(vel, closest,
                #                                                            velocities[closest]))
                pb.update()
                continue

            thisvel = velocities[closest].value
            guess_regs = guesses[thisvel]

            ampguess = vslice.max().value

            model_list = []
            for reg in guess_regs:

                p_init = models.Gaussian2D(amplitude=ampguess,
                                           x_mean=reg.center.x,
                                           y_mean=reg.center.y,
                                           x_stddev=bmmaj_px/STDDEV_TO_FWHM*0.75,
                                           y_stddev=bmmin_px/STDDEV_TO_FWHM*0.75,
                                           theta=beam.pa.to(u.deg).value,
                                           bounds={'x_stddev':(bmmin_px/STDDEV_TO_FWHM*0.5,
                                                               bmmaj_px*max_radius_in_beams/STDDEV_TO_FWHM),
                                                   'y_stddev':(bmmin_px/STDDEV_TO_FWHM*0.5,
                                                               bmmaj_px*max_radius_in_beams/STDDEV_TO_FWHM),
                                                   'x_mean':(reg.center.x-max_offset_in_beams*bmmaj_px/STDDEV_TO_FWHM,
                                                             reg.center.x+max_offset_in_beams*bmmaj_px/STDDEV_TO_FWHM),
                                                   'y_mean':(reg.center.y-max_offset_in_beams*bmmaj_px/STDDEV_TO_FWHM,
                                                             reg.center.y+max_offset_in_beams*bmmaj_px/STDDEV_TO_FWHM),
                                                   'amplitude':(ampguess*0.1, ampguess*2.1)
                                                  }
                                          )
                assert not p_init._has_units
                model_list.append(p_init)

            composite_model = model_list[0]
            if len(model_list) > 1:
                for mod in model_list[1:]:
                    composite_model += mod

            fit_result = gaussfit_image(vslice.value, composite_model,
                                        weights=weights, plot=True)
            results[thisvel] = fit_result

            if not os.path.exists(paths.fpath('velcentroid/diagnostics/{0}/'.format(basename))):
                os.mkdir(paths.fpath('velcentroid/diagnostics/{0}/').format(basename))
            pl.savefig(paths.fpath('velcentroid/diagnostics/{0}/{1}.png')
                       .format(basename, thisvel))

            pb.update()

        cached_gaussfit_results[linename] = results

    diskend_regs = regions.Regions.read(paths.rpath('diskends.reg'))
    diskends = coordinates.SkyCoord([reg.center for reg in diskend_regs]).icrs

    #center = coordinates.SkyCoord(diskends.ra.mean(), diskends.dec.mean(),
    #                              frame=diskends.frame)
    center_cont = regions.Regions.read(paths.rpath('sourceI_center.reg'))[0].center.transform_to(coordinates.ICRS)
    center_U = regions.Regions.read(paths.rpath('sourceI_center.reg'))[1].center.transform_to(coordinates.ICRS)
    center_h2o = regions.Regions.read(paths.rpath('sourceI_center.reg'))[2].center.transform_to(coordinates.ICRS)

    center = center_cont

    ref_cen_x, ref_cen_y = cube.wcs.celestial.wcs_world2pix(center.ra.deg,
                                                            center.dec.deg, 0)
    # had to switch to pixel centering because coordinate transformations
    # aren't accurate enough (and/or, don't match ds9)
    ref_cen_x = cenx
    ref_cen_y = ceny

    #assert np.abs(ref_cen_x - 66) < 2
    #assert np.abs(ref_cen_y - 63) < 2

    def offset_to_point(xx, yy):
        line = geom.LineString(zip(diskends.ra.deg, diskends.dec.deg))
        point = geom.Point(xx, yy)
        return line.project(point)

    ref_offset = offset_to_point(center.ra.deg, center.dec.deg)

    # Add the data as a background image
    pvfn = 'pv/sourceI_{0}_B6_robust0.5_diskpv_0.01.fits'.format(linename)
    fh = fits.open(paths.dpath(pvfn))
    data = fh[0].data
    header = fh[0].header

    ww = wcs.WCS(fh[0].header)

    ww.wcs.cdelt[1] /= 1000.0
    ww.wcs.crval[1] /= 1000.0
    ww.wcs.cunit[1] = ' '#u.km/u.s
    ww.wcs.cdelt[0] *= 3600
    ww.wcs.cunit[0] = u.arcsec
    ww.wcs.crval[0] = -origin.to(u.arcsec).value

    # #!@#$!@#$@!%@#${^(@#$)%#$(
    ww.wcs.set()

    snap3 = tracemalloc.take_snapshot()
    diff = snap3.compare_to(first_snapshot, 'lineno')
    mem_used = sum([dd.size_diff for dd in diff])*u.B
    log.info(f"Used {mem_used.to(u.GB)} for line {linename} prior to plotting")

    fig1 = pl.figure(1)
    pl.clf()
    ax1 = fig1.add_subplot(1,2,1)
    pvwcs = pvextractor.utils.wcs_slicing.slice_wcs(cube.wcs, pixscale)
    pvwcs.wcs.cdelt[0] *= 3600
    pvwcs.wcs.crval[0] = -origin.to(u.arcsec).value
    pvwcs.wcs.cunit[0] = u.arcsec
    pvwcs.wcs.crval[1] /= 1e3
    # not clear why this is needed?
    pvwcs.wcs.crval[1] += assumed_vcen.to(u.km/u.s).value
    pvwcs.wcs.cdelt[1] /= 1e3
    pvwcs.wcs.cunit[1] = ' ' # force wcs.set to NOT revert to m/s
    print('pvwcs: cdelt={0} crval={1} crpix={2}'.format(pvwcs.wcs.cdelt,
                                                        pvwcs.wcs.crval,
                                                        pvwcs.wcs.crpix))
    ax2 = fig1.add_subplot(1,2,2, projection=ww)

    trans = ax2.get_transform('world')

    diskends_x, diskends_y = cube.wcs.celestial.wcs_world2pix(diskends.ra.deg,
                                                              diskends.dec.deg,
                                                              0)
    ax1.plot((diskends_x-ref_cen_x)*pixscale.to(u.arcsec),
             (diskends_y-ref_cen_y)*pixscale.to(u.arcsec), 'k-',
             linewidth=3, alpha=0.2, zorder=-100)
    ax1.plot(0, 0, 'ko', markersize=5, alpha=0.5, zorder=-50)

    loc = pl.matplotlib.ticker.MultipleLocator(base=0.04)
    ax1.xaxis.set_major_locator(loc)

    cmap = pl.cm.Spectral_r
    cmap = pl.cm.Spectral
    norm = pl.matplotlib.colors.Normalize(vmin=vmin, vmax=vmax)

    offset_fits_arcsec = []
    vels = np.sort(np.array([v for v in results]))

    gfit_points = []

    for vel in vels:
        fit_result = results[vel]
        fitted = fit_result[0]
        n_submodels = fitted.n_submodels()
        color = cmap(norm(vel))
        if n_submodels > 1:
            offsets_ = []
            for ii in range(n_submodels):
                xcen, ycen = (getattr(fitted, 'x_mean_{0}'.format(ii)),
                              getattr(fitted, 'y_mean_{0}'.format(ii)))
                ax1.plot((xcen-ref_cen_x)*pixscale.to(u.arcsec),
                         (ycen-ref_cen_y)*pixscale.to(u.arcsec),
                         color=color,
                         marker='o')
                ra,dec = cube.wcs.celestial.wcs_pix2world(xcen, ycen, 0)
                offset = offset_to_point(ra, dec)
                gfit_points.extend(ax2.plot((offset-ref_offset)*3600, vel,
                                            color=color, marker='s',
                                            markersize=5,
                                            markeredgecolor='k',
                                            transform=trans))
                offsets_.append((offset-ref_offset)*3600)
            offset_fits_arcsec.append(np.mean(offsets_))
        else:
            xcen, ycen = fitted.x_mean, fitted.y_mean
            ax1.plot((xcen-ref_cen_x)*pixscale.to(u.arcsec),
                     (ycen-ref_cen_y)*pixscale.to(u.arcsec), color=color, marker='o')
            ra,dec = cube.wcs.celestial.wcs_pix2world(xcen, ycen, 0)
            offset = offset_to_point(ra, dec)
            gfit_points.extend(ax2.plot((offset-ref_offset)*3600, vel,
                                        color=color, marker='s',
                                        markersize=5,
                                        markeredgecolor='k',
                                        transform=trans)
                              )
            offset_fits_arcsec.append((offset-ref_offset)*3600)

    show_keplercurves(ax2, 0*u.deg, 150, assumed_vcen, yaxis_unit=u.km/u.s, radii={},
                      masses=[15, ], linestyles=[':',], colors=['r'],
                      trans=ax2.get_transform('world'),
                     )

    # xx_thindisk, yy_thindisk = thindiskcurve(mass=20*u.M_sun, rmin=30*u.au, rmax=80*u.au)
    # ax2.plot((xx_thindisk / d_orion).to(u.arcsec, u.dimensionless_angles()),
    #          yy_thindisk + assumed_vcen,
    #          'k:',
    #          transform=trans)
    xx_thindisk, yy_thindisk = thindiskcurve(mass=15.5*u.M_sun, rmin=17*u.au,
                                             rmax=66*u.au)
    thindiskline = ax2.plot((xx_thindisk / d_orion).to(u.arcsec,
                                                       u.dimensionless_angles()),
                            yy_thindisk + assumed_vcen, 'k-', transform=trans)

    xlim, ylim = pvwcs.wcs_world2pix([-0.2,0.2], [vmin-3, vmax+3], 0)
    xlim, ylim = ww.wcs_world2pix([-0.2,0.2], [vmin-3, vmax+3], 0)
    ax2.set_ylim(*ylim)
    ax2.set_xlim(*xlim)
    ax2.yaxis.tick_right() # mpl version; incompatible with wcsaxes
    ax2.coords[1].set_ticklabel_position('r')
    ax2.coords[1].set_axislabel_position('r')
    ax2.set_ylabel("$V_{LSR}$ [km s$^{-1}$]")
    ax2.set_xlabel("Offset Position (arcsec)")
    ax1.set_xlabel("Offset RA (arcsec)")
    ax1.set_ylabel("Offset Dec (arcsec)")
    ax1.axis(limits)

    for tick in ax1.get_xticklabels():
        tick.set_rotation(90)
    for tick in ax2.get_xticklabels():
        tick.set_rotation(90)

    pl.savefig(paths.fpath('velcentroid/{linename}_pp_pv_plots.pdf'.format(linename=linename)),
               bbox_inches='tight')

    im = ax2.imshow(data, cmap='gray_r', interpolation='none', vmax=0.02,
                    vmin=-0.0001, origin='lower',
                    #transform=ax2.get_transform('world'),
                   )
    ax2.set_aspect('auto')
    ax2.set_ylim(*ylim)
    ax2.set_xlim(*xlim)

    pl.savefig(paths.fpath('velcentroid/{linename}_pp_pv_plots_withbackground.pdf'.format(linename=linename)),
               bbox_inches='tight')

    #fig3,ax3 = show_pv(data, ww,
    #                   origin, vrange=[-40,55], vcen=assumed_vcen,
    #                   imvmin=-0.001, imvmax=0.020)

    #trans3 = ax3.get_transform('world')
    #overlay_thindiskline = ax3.plot((xx_thindisk / d_orion).to(u.arcsec,
    #                                                           u.dimensionless_angles()),
    #                                 (yy_thindisk + assumed_vcen).to(u.m/u.s), 'k-', transform=trans3)

    # previously had an
    #if 'Unknown' in linename:
    # statement here because these are the only ones that represent disks,
    # but since we're using the *average* offset position, maybe this is OK?

    offsets_au = (u.Quantity(offset_fits_arcsec, u.arcsec) *
                  d_orion).to(u.au, u.dimensionless_angles())
    print("Beginning thin disk fitting for {0}".format(linename))
    if False:
        fitresult, ci, trace, minimizer = thindiskcurve_fitter(
            xsep=np.array(offsets_au), velo=vels, mguess=15.5*u.M_sun, rinner=17,
            router=66, conf_int=True, npix=500)
        fitresult_list.append(fitresult)
        trace_plotter(ci, trace, fitresult, minimizer)
    else:
        fitresult = thindiskcurve_fitter(xsep=np.array(offsets_au), velo=vels,
                                         mguess=15.5*u.M_sun, rinner=17,
                                         router=66, conf_int=False, npix=500)
        fitresult_list.append(fitresult)

    for line in thindiskline:
        line.set_visible(False)

    xx_thindisk, yy_thindisk = thindiskcurve(mass=fitresult.params['mass']*u.M_sun,
                                             rmin=fitresult.params['rinner']*u.au,
                                             rmax=fitresult.params['router']*u.au,
                                            )

    lines = ax2.plot((xx_thindisk / d_orion).to(u.arcsec, u.dimensionless_angles()),
                     yy_thindisk + assumed_vcen,
                     'k-',
                     transform=trans,
                     label=('$M={0:0.1f}$\n$R_{{in}}={1:d}$\n$R_{{out}}={2:d}$'
                            .format(fitresult.params['mass'].value,
                                    int(fitresult.params['rinner'].value),
                                    int(fitresult.params['router'].value),
                                   )
                           )
                    )

    xmin,xmax = ax2.get_xlim()
    ax2.hlines(fitresult.params['vcen'].value, xmin, xmax, linestyle='--', color='k',
               alpha=0.5, zorder=500, transform=trans)

    leg = pl.legend(loc='upper left', fontsize=12, handlelength=1.0)

    im.set_visible(False)

    pl.savefig(paths.fpath('velcentroid/{linename}_pp_pv_plots_fittedmodel.pdf'.format(linename=linename)),
               bbox_inches='tight')

    # show the average fitted positions
    avgposns = ax2.plot(offset_fits_arcsec, vels, marker='o', markersize=5,
                        linestyle='none', markerfacecolor='k', alpha=0.5,
                        markeredgecolor='w', transform=trans)

    pl.savefig(paths.fpath('velcentroid/{linename}_pp_pv_plots_fittedmodel_withavgs.pdf'.format(linename=linename)),
               bbox_inches='tight')

    im.set_visible(True)
    pl.savefig(paths.fpath('velcentroid/{linename}_pp_pv_plots_fittedmodel_withavgs_withbackground.pdf'.format(linename=linename)),
               bbox_inches='tight')
    im.set_visible(False)

    tracemalloc.start()

    snap1 = tracemalloc.take_snapshot()

    for mass in (15.5, 19, 5, 10, 15, 20, ):
        for line in lines:
            line.remove()
            #line.set_visible(False)
        leg.remove()
        del leg, lines

        fitresult = thindiskcurve_fitter(xsep=np.array(offsets_au),
                                         velo=vels,
                                         mguess=mass*u.M_sun,
                                         rinner=17,
                                         router=66,
                                         fixedmass=True,
                                        )
        assert fitresult.params['mass'].value == mass

        snap2 = tracemalloc.take_snapshot()
        diff = snap2.compare_to(snap1, 'lineno')
        mem_used = sum([dd.size_diff for dd in diff])*u.B
        log.info(f"Used {mem_used.to(u.GB)} with mass={mass} after fitresult")

        xx_thindisk, yy_thindisk = thindiskcurve(mass=fitresult.params['mass']*u.M_sun,
                                                 rmin=fitresult.params['rinner']*u.au,
                                                 rmax=fitresult.params['router']*u.au,
                                                )

        lines = ax2.plot((xx_thindisk / d_orion).to(u.arcsec, u.dimensionless_angles()),
                         yy_thindisk + assumed_vcen,
                         'k-',
                         transform=trans,
                         label=('$M={0:0.1f}$\n$R_{{in}}={1:d}$\n$R_{{out}}={2:d}$'
                                .format(fitresult.params['mass'].value,
                                        int(fitresult.params['rinner'].value),
                                        int(fitresult.params['router'].value),
                                       )
                               )
                        )
        leg = pl.legend(lines,
                        [line.get_label() for line in lines],
                        loc='upper left',
                        fontsize=12, handlelength=1.0)
        pl.tight_layout()
        pl.savefig(paths.fpath('velcentroid/{linename}_pp_pv_plots_fittedmodel_{mass}msun_withavgs.pdf'
                               .format(mass=mass, linename=linename)),
                   bbox_inches='tight'
                  )

        del fitresult, xx_thindisk, yy_thindisk

        snap2 = tracemalloc.take_snapshot()
        diff = snap2.compare_to(snap1, 'lineno')
        mem_used = sum([dd.size_diff for dd in diff])*u.B
        log.info(f"Used {mem_used.to(u.GB)} with mass={mass}")

    im.set_visible(True)
    for line in lines:
        line.set_visible(False)
    leg.remove()

    xx,vv,pvd = thindiskcurve(mass=15*u.M_sun,
                              rmin=25*u.au,
                              rmax=65*u.au,
                              pvd=True,
                             )
    xx_as = (xx/d_orion).to(u.arcsec, u.dimensionless_angles())

    conv_beam = convolution.Gaussian2DKernel(0.04*u.arcsec/np.diff(xx_as).mean(),
                                             1.5*u.km/u.s/np.diff(vv).mean(),
                                            )
    sm_pvd = convolution.convolve_fft(pvd, conv_beam)

    ax1.cla()
    #ax1.remove()
    #ax1 = fig1.add_subplot(1,2,1, projection=ww)
    ax1.imshow(sm_pvd, cmap='gray_r', extent=[xx_as.value.min(),
                                              xx_as.value.max(),
                                              (vv+assumed_vcen).value.min(),
                                              (vv+assumed_vcen).value.max()],
               interpolation='none', origin='lower',
               vmin=0,
               vmax=sm_pvd[np.abs(vv)<20*u.km/u.s].max(),
               label=('$M={0:0.1f}$\n$R_{{in}}={1:d}$\n$R_{{out}}={2:d}$'
                      .format(15, 25, 65))
              )

    keplines = show_keplercurves(ax1, 0*u.deg, 150, assumed_vcen,
                                 yaxis_unit=u.km/u.s, radii={}, masses=[15, ],
                                 linestyles=[':',], colors=['r'],
                                 trans=ax1.transData,
                     )

    xlim_as, ylim_kms = [-0.2,0.2], [vmin-3, vmax+3]
    ax1.set_xlim(*xlim_as)
    ax1.set_ylim(*ylim_kms)

    ax1.set_aspect('auto')
    #ax1.legend(('$M={0:0.1f}$\n$R_{{in}}={1:d}$\n$R_{{out}}={2:d}$'
    #                  .format(15, 25, 65)),
    #           [im],
    #           loc='best')

    loc = pl.matplotlib.ticker.MultipleLocator(base=0.1)
    ax1.xaxis.set_major_locator(loc)

    ax1.set_ylabel("$V_{LSR}$ [km s$^{-1}$]")
    ax1.set_xlabel("Offset Position (arcsec)")

    pl.savefig(paths.fpath('velcentroid/{linename}_pp_pv_plots_fittedmodel_{mass}msun_withavgs_comparepv.pdf'
                           .format(mass=15, linename=linename)),
               bbox_inches='tight')

    for feature in gfit_points + avgposns:
        feature.set_visible(False)

    pl.savefig(paths.fpath('velcentroid/{linename}_pp_pv_plots_fittedmodel_{mass}msun_comparepv.pdf'
                           .format(mass=15, linename=linename)),
               bbox_inches='tight')
    pl.savefig(paths.fpath('velcentroid/{linename}_pp_pv_plots_fittedmodel_{mass}msun_comparepv.png'
                           .format(mass=15, linename=linename)),
               bbox_inches='tight')

    fig1.clf()

    snap3 = tracemalloc.take_snapshot()
    diff = snap3.compare_to(first_snapshot, 'lineno')
    mem_used = sum([dd.size_diff for dd in diff])*u.B
    log.info(f"Used {mem_used.to(u.GB)} for line {linename}")


"""wrap the ccmake-gui tools (Windows only)"""
import subprocess

name = 'cmake-gui'
platforms = ['win']
optional = True
not_found = "required for 'fips config' functionality"

#-------------------------------------------------------------------------------
def check_exists(fips_dir) :
    """test if cmake-gui is in the path

    :returns:   True if cmake-gui is in the path
    """
    try:
        out = subprocess.check_output(['cmake-gui', '--version'])
        return True
    except (OSError, subprocess.CalledProcessError) :
        return False;

#-------------------------------------------------------------------------------
def run(build_dir) :
    """run the cmake-gui tool

    :params build_dir:  directory where cmake-generated build files are located
    :returns:           True if cmake-gui returns successful
    """
    res = subprocess.call('cmake-gui .', cwd=build_dir, shell=True)
    return res == 0


import jsonpickle

from cloudshell.cp.docker.common.deploy_data_holder import DeployDataHolder
from cloudshell.cp.docker.models.deploy_docker_container_resource_model import DeployDockerContainerResourceModel
from cloudshell.cp.docker.models.docker_cloud_provider_resource_model import DockerCloudProviderResourceModel

class DockerModelsParser(object):
    @staticmethod
    def convert_app_resource_to_deployed_app(resource):
        json_str = jsonpickle.decode(resource.app_context.deployed_app_json)
        data_holder = DeployDataHolder(json_str)

        return data_holder

    @staticmethod
    def convert_to_docker_resource_model(resource):
        resource_context = resource.attributes

        docker_resource_model = DockerCloudProviderResourceModel()

        return docker_resource_model

    @staticmethod
    def convert_to_deployment_resource_model(deployment_request):
        data = jsonpickle.decode(deployment_request)

        data_holder = DeployDataHolder(data)

        deployment_resource_model = DeployDockerContainerResourceModel()
        deployment_resource_model.app_name = data_holder.app_name
        deployment_resource_model.cloud_provider = data_holder.docker_params.cloud_provider
        deployment_resource_model.docker_image = data_holder.docker_params.docker_image
        deployment_resource_model.docker_image_command = data_holder.docker_params.docker_image_command
        deployment_resource_model.docker_image_tag = data_holder.docker_params.docker_image_tag

        return deployment_resource_model

    @staticmethod
    def convert_to_bool(string):
        """
        Converts string to bool
        :param string: String
        :str string: str
        :return: True or False
        """
        if isinstance(string, bool):
            return string
        return string in ['true', 'True', '1']

    @staticmethod
    def get_public_ip_from_connected_resource_details(resource_context):
        public_ip_on_resource = ""
        public_ip = 'Public IP'
        if resource_context.remote_endpoints is not None and public_ip in resource_context.remote_endpoints[
            0].attributes:
            public_ip_on_resource = resource_context.remote_endpoints[0].attributes[public_ip]
        return public_ip_on_resource

    @staticmethod
    def get_private_ip_from_connected_resource_details(resource_context):
        private_ip_on_resource = ""
        if resource_context.remote_endpoints is not None:
            private_ip_on_resource = resource_context.remote_endpoints[0].address
        return private_ip_on_resource

    @staticmethod
    def try_get_deployed_connected_resource_instance_id(resource_context):
        try:
            deployed_instance_id = str(
                jsonpickle.decode(resource_context.remote_endpoints[0].app_context.deployed_app_json)['vmdetails'][
                    'uid'])
        except Exception as e:
            raise ValueError('Could not find an ID of the Docker Deployed instance' + e.message)
        return deployed_instance_id

    @staticmethod
    def get_connectd_resource_fullname(resource_context):
        if resource_context.remote_endpoints[0]:
            return resource_context.remote_endpoints[0].fullname
        else:
            raise ValueError('Could not find resource fullname on the deployed app.')


import math
import heapq
import json

# running virtual environment on windows
###############################################
# virtualenv env
# .\env\Scripts\activate.bat
# python Graph.py

class Node:
    def __init__(self, label, latitude, longitude, name, distance=None, nextNode=None, dir=None):
        self.vertex = label
        self.longitude = longitude
        self.latitude = latitude
        self.dist = distance
        self.next = nextNode
        self.name = name
        self.dir = dir

    def printNode(self):
        print("(" + str(self.vertex) + ") " + self.name + ": " + str(self.latitude) + ", " + str(self.longitude))

    def getName(self):
        return self.name

    def getLon(self):
        return self.longitude

    def getLat(self):
        return self.latitude

    def getDist(self):
        return self.dist

    def getLabel(self):
        return self.vertex

    def getNext(self):
        return self.next

    def setNext(self, nextNode):
        self.next = nextNode

    def setDist(self, dist):
        self.dist = dist

    def setDir(self, dir):
        self.dir = dir

class Graph:
    def __init__(self, numVertices):
        self.numVert = numVertices
        self.graph = [None] * self.numVert
        self.vertices = [None] * self.numVert

    def addEdge(self, src, dst):
        srcNode = src.getLabel()

        # calculate distance between 2 nodes
        dist = distance(src, dst)
        dst.setDist(dist)

        # calculate bearing between 2 nodes
        direction = bearing(src, dst)
        dst.setDir(direction)

        if self.graph[srcNode] == None:
            self.graph[srcNode] = []
        self.graph[srcNode].append(dst)

    def addVertex(self, node):
        self.vertices[node.getLabel()] = node

    def printGraph(self):
        for i in range(self.numVert):
            print(str(i) + ": ")
            if self.graph[i] != None:
                for j in range(len(self.graph[i])):
                    curr = self.graph[i][j]
                    print("(" + str(curr.getLabel()) + ", " + str(curr.getLat()) + ", " + str(curr.getLon()) + ", " + str(curr.getDist()) + ", " + str(curr.getName()) + ")")

    def getVertices(self):
        return self.vertices

    def getVertex(self, label):
        return self.vertices[label]

    def getNumVertices(self):
        return self.numVert

    def adjacencyList(self, currVertex):
        return self.graph[currVertex]

# calculates the bearing between two lat/lon coordiantes
# https://www.movable-type.co.uk/scripts/latlong.html
"""
Understanding bearings
------------------------
0 degrees = W
90 degrees = N
180 degrees = E
270 degrees = S
"""
def bearing(node1, node2):

    # extract lat, lon from nodes
    lat1 = node1.getLat()
    lon1 = node1.getLon()
    lat2 = node2.getLat()
    lon2 = node2.getLon()

    # calculate bearing
    y = math.sin(lon2-lon1) * math.cos(lat2)
    x = math.cos(lat1) * math.sin(lat2) - math.sin(lat1) * math.cos(lat2) * math.cos(lon2-lon1)
    bearingRadians = math.atan2(y,x)

    # bearing in degrees
    bearing = (bearingRadians*180/math.pi + 360) % 360

    return bearing

# calculates the distance between two lon/lat coordinates
# https://www.geodatasource.com/developers/java
def distance(node1, node2, unit="M"):

    # extract lat, lon from nodes
    lat1 = node1.getLat()
    lon1 = node1.getLon()
    lat2 = node2.getLat()
    lon2 = node2.getLon()

    # calculate distance
    if (lat1 == lat2) and (lon1 == lon2):
        return 0
    else:
        theta = lon1-lon2
        dist = math.sin(math.radians(lat1)) * math.sin(math.radians(lat2)) + math.cos(math.radians(lat1)) * math.cos(math.radians(lat2)) * math.cos(math.radians(theta))
        dist = math.acos(dist)
        dist = math.degrees(dist)

        # default is miles "M"
        dist = dist * 60 * 1.1515;

        # Kilometers
        if unit == "K":
            dist = dist * 1.609344

        # Nautical miles
        elif unit == "N":
            dist = dist * 0.8684
        return dist

# given user's geolocation, determine the nearest node on the graph and distance to it
def nearest(numNodes, graph, lat, lon, unit="M"):

    vertices = graph.getVertices()
    minDist = float('inf')
    nearest = None
    direction = None

    # current geolocation
    curr = Node(0, lat, lon, "")

    for i in vertices:
        if i != None:
            dist = distance(i, curr, unit)
            if dist < minDist:
                minDist = dist
                nearest = i
                direction = bearing(i, curr)

    return nearest, minDist, direction

def dijkstra(numNodes, graph, src):
    srcNode = src.getLabel()

    # initialization
    distances = [float('inf')] * numNodes
    distances[srcNode] = 0
    parents = [None] * numNodes

    # init priority queue
    pq = [(0, srcNode)]
    while len(pq) > 0:
        current_distance, current_vertex = heapq.heappop(pq)

        # Nodes can get added to the priority queue multiple times. We only
        # process a vertex the first time we remove it from the priority queue.
        if current_distance > distances[current_vertex]:
            continue

        for node in graph.adjacencyList(current_vertex):
            distance = current_distance + node.getDist()

            # Only consider this new path if it's better than any path we've
            # already found.
            neighbor = node.getLabel()
            if distance < distances[neighbor]:
                distances[neighbor] = distance
                parents[neighbor] = current_vertex
                heapq.heappush(pq, (distance, neighbor))

    return parents

# Driver program to the above graph class
if __name__ == "__main__":

    # init digraph
    numVertices = 6
    graph = Graph(numVertices)

    node1 = Node(1, 33.64331, -84.43274, "C52")
    node2 = Node(2, 33.64331, -84.43252, "C55")
    node3 = Node(3, 33.64329, -84.43284, "C50")
    node4 = Node(4, 33.64310, -84.43282, "C46")
    node5 = Node(5, 33.64311, -84.43241, "C49")

    # add vertices
    graph.addVertex(node1)
    graph.addVertex(node2)
    graph.addVertex(node3)
    graph.addVertex(node4)
    graph.addVertex(node5)

    # add directed edges
    # direction is in degrees north
    graph.addEdge(node1, node2)
    graph.addEdge(node2, node1)
    graph.addEdge(node2, node5)
    graph.addEdge(node5, node2)
    graph.addEdge(node3, node1)
    graph.addEdge(node1, node3)
    graph.addEdge(node4, node5)
    graph.addEdge(node5, node4)
    graph.addEdge(node3, node4)
    graph.addEdge(node4, node3)

    graph.printGraph()

    # calculate distance between user location and nearest node
    userGeolocation = (33.64307,-84.43250)
    nearestNode, dist, bearing = nearest(numVertices, graph, userGeolocation[0], userGeolocation[1], "M")
    print()
    nearestNode.printNode()
    print(dist)
    print(bearing)

    # dijkstra
    path = dijkstra(numVertices, graph, node1)
    path[0] = nearestNode.getLabel()

    with open('../maps/ATL/C.json') as f:
        data = json.load(f)

    json = {}
    for i in data:
        if (i["name"] != "inter"):
            json[i["name"]] = i["label"]

    print(json)


'''
	Utility method to make graphs for all the .txt files in a folder. Can plot
	an average over a given number of epochs.

	Usage: python grapher.py <folder_path> <num_to_average_over>

	Txt file format: <epoch>,<value>
	All other files and txt files with other format will be ignored
'''

import matplotlib.pyplot as plt
import sys
import os

avg_over = float(sys.argv[2])
# x_tick_distance = int(sys.argv[3])

def walkThroughFolder(folder_name):
	for root, dirs, files in os.walk(folder_name):
		directory = os.path.basename(root)

		for file in files:
			makeGraph(root, file)

		for dr in dirs:
			walkThroughFolder(os.path.join(root, dr))

def makeGraph(root, file):
	file_path = os.path.join(root, file)
	if file_path[-4:] != '.txt': return

	title = ' '.join(file[:-4].split('-')).capitalize()

	x = []
	y = []

	with open(file_path, "r") as f:
		i = 0.
		y_s = []
		for line in f.readlines():
			def checkFloat(string):
				try:
				    float(string)
				    return True
				except ValueError:
				    return False

			split_lines = line.split(",")
			if len(split_lines) != 2 or not checkFloat(split_lines[0]) or not checkFloat(split_lines[1]):
				return
			y_s.append(float(split_lines[1]))
			i += 1.
			if i % avg_over == 0:
				x.append(split_lines[0])
				y.append(sum(y_s) / avg_over)
				y_s = []

	plt.plot(x, y)
	plt.title(title)
	plt.savefig(file_path[:-4] + '.png')
	plt.close()

walkThroughFolder(sys.argv[1])


from os import path
from setuptools import setup, find_packages

here = path.abspath(path.dirname(__file__))

with open(path.join(here, "requirements.txt")) as f:
    requirements = []
    for line in f:
        # Skip lines with hash values
        if not line.strip().startswith("--"):
            requirements.append(line.split()[0])

setup(
    name='BucketList API',
    version='1.0',
    long_description=__doc__,
    author="Bolaji Olajide",
    author_email="bolaji.olajide@andela.com",
    packages=find_packages(),
    include_package_data=True,
    zip_safe=False,
    install_requires=requirements,
    url="https://github.com/andela-bolajide/BucketListAPI",
)


import comet_ml
from comet_ml import ConfusionMatrix

import logging
import keras
from datetime import date
from keras.callbacks import Callback
from keras.datasets import mnist
from keras.layers import Dense
from keras.models import Sequential
from keras.optimizers import RMSprop
import keract
import numpy as np
import os

def get_comet_experiment():
    return comet_ml.Experiment(log_env_details=False)

def build_model_graph(experiment):
    model = Sequential()
    model.add(
        Dense(
            experiment.get_parameter("first_layer_units"),
            activation="sigmoid",
            input_shape=(784,),
        )
    )
    model.add(Dense(128, activation="sigmoid"))
    model.add(Dense(128, activation="sigmoid"))
    model.add(Dense(10, activation="softmax"))
    model.compile(
        loss="categorical_crossentropy",
        optimizer=RMSprop(),
        metrics=["accuracy"],
    )

    return model

def train(experiment, model, x_train, y_train, x_test, y_test):
    class ConfusionMatrixCallback(Callback):
        def __init__(self, experiment, inputs, targets):
            self.experiment = experiment
            self.inputs = inputs
            self.targets = targets
            # We make one ConfusionMatrix so to share images:
            self.confusion_matrix = ConfusionMatrix(
                index_to_example_function=self.index_to_example)

        def on_epoch_begin(self, epoch, logs={}):
            # Get Confusion Matrix before training:
            if epoch == 0:
                self.on_epoch_end(-1)

        def on_epoch_end(self, epoch, logs={}):
            predicted = self.model.predict(self.inputs)
            # First we compute the matrix:
            self.confusion_matrix.compute_matrix(self.targets, predicted)
            # Then log it from the ConfusionMatrix object:
            self.experiment.log_confusion_matrix(
                matrix=self.confusion_matrix,
                title="Confusion Matrix, Epoch #%d" % (epoch + 1),
                file_name="confusion-matrix-%03d.json" % (epoch + 1),
            )

        def index_to_example(self, index):
            image_array = self.inputs[index]
            image_name = "confusion-matrix-%05d.png" % index
            result = self.experiment.log_image(
                image_array,
                name=image_name,
                image_shape=(28, 28, 1))
            # Return sample name and assetId
            return {"sample": image_name, "assetId": result["imageId"]}
    class HistogramCallback(Callback):
        def __init__(self, experiment):
            self.experiment = experiment

        def on_epoch_begin(self, epoch, logs={}):
            # Get Histogram before training:
            if epoch == 0:
                self.on_epoch_end(-1)

        def on_epoch_end(self, epoch, logs={}):
            for layer in range(len(self.model.layers)):
                weights_biases = self.model.layers[layer].get_weights()
                self.experiment.log_histogram_3d(
                    weights_biases,
                    name="histogram-layer-%03d.json" % layer,
                    step=(epoch + 1),
                )
    class EmbeddingCallback(Callback):
        def __init__(self, experiment, inputs, targets):
            self.experiment = experiment
            self.inputs = inputs
            self.targets = targets
            self.labels = targets.argmax(axis=1)
            self.image_size = (28, 28)
            results = self.experiment.create_embedding_image(
                image_data=self.inputs,
                # we round the pixels to 0 and 1, and multiple by 2
                # to keep the non-zero colors dark (if they were 1, they
                # would get distributed between 0 and 255):
                image_preprocess_function=lambda matrix: np.round(matrix,0) * 2,
                # Set the transparent color:
                image_transparent_color=(0, 0, 0),
                image_size=self.image_size,
                # Fill in the transparent color with a background color:
                image_background_color_function=self.label_to_color,
            )
            if results:
                image, self.sprite_url = results
            else:
                self.sprite_url = None

        def label_to_color(self, index):
            label = self.labels[index]
            if label == 0:
                return (255, 0, 0)
            elif label == 1:
                return (0, 255, 0)
            elif label == 2:
                return (0, 0, 255)
            elif label == 3:
                return (255, 255, 0)
            elif label == 4:
                return (0, 255, 255)
            elif label == 5:
                return (128, 128, 0)
            elif label == 6:
                return (0, 128, 128)
            elif label == 7:
                return (128, 0, 128)
            elif label == 8:
                return (255, 0, 255)
            elif label == 9:
                return (255, 255, 255)

        def on_epoch_begin(self, epoch, logs={}):
            # Get Embedding before training:
            if epoch == 0:
                self.on_epoch_end(-1)

        def on_epoch_end(self, epoch, logs={}):
            # The vectors are big, only log them every 10 epochs:
            if (epoch + 1) % 10 != 0:
                return
            # Assuming one input bank:
            input_tensor = self.inputs
            activations = keract.get_activations(self.model, input_tensor)
            keys = list(activations.keys())
            # Get the activations before output layer:
            layer_name = keys[-2]
            # Group the embeddings by layer_name:
            self.experiment.log_embedding(
                activations[layer_name],
                self.labels,
                image_data=self.sprite_url,
                image_size=self.image_size,
                title="%s-%s" % (layer_name, epoch + 1),
                group=layer_name)

    callbacks = [
        ConfusionMatrixCallback(experiment, x_test, y_test),
        HistogramCallback(experiment)
        # EmbeddingCallback(experiment, x_test, y_test),
    ]

    model.fit(
        x_train,
        y_train,
        batch_size=experiment.get_parameter("batch_size"),
        epochs=experiment.get_parameter("epochs"),
        validation_data=(x_test, y_test),
        callbacks=callbacks,
    )

    experiment.send_notification("Training done", "finished", {"Data": "100"})

def evaluate(experiment, model, x_test, y_test):
    score = model.evaluate(x_test, y_test, verbose=0)
    logging.info("Score %s", score)

def get_dataset():
    num_classes = 10

    # the data, shuffled and split between train and test sets
    (x_train, y_train), (x_test, y_test) = mnist.load_data()

    x_train = x_train.reshape(60000, 784)
    x_test = x_test.reshape(10000, 784)
    x_train = x_train.astype("float32")
    x_test = x_test.astype("float32")
    x_train /= 255
    x_test /= 255
    print(x_train.shape[0], "train samples")
    print(x_test.shape[0], "test samples")

    # convert class vectors to binary class matrices
    y_train = keras.utils.to_categorical(y_train, num_classes)
    y_test = keras.utils.to_categorical(y_test, num_classes)

    return x_train, y_train, x_test, y_test

def main():
    today = date.today()
    x_train, y_train, x_test, y_test = get_dataset()
    config = {
        "algorithm": "bayes",
        "name": "Optimize MNIST Network",
        "spec": {"maxCombo": 10, "objective": "minimize", "metric": "loss"},
        "parameters": {
            "first_layer_units": {
                "type": "integer",
                "mu": 500,
                "sigma": 50,
                "scalingType": "normal",
            },
            "batch_size": {"type": "discrete", "values": [64, 128, 256]},
        },
        "trials": 1,
    }

    experiment_class = comet_ml.Experiment
    opt = comet_ml.Optimizer(config, experiment_class)
    experiment_kwargs = {}
    date_str = today.strftime("%Y_%m_%d")

    for experiment in opt.get_experiments(**experiment_kwargs):
        experiment.log_parameter("epochs", 3)
        experiment.log_html("<div> Some Html </div>")
        for i in range(2):
            experiment.log_html("<br>Code: " + str(i))
        # experiment.log_system_info("someKey", "someValue")
        # experiment.log_system_info("someSystemKey", "someSystemValue")
        experiment.add_tag(date_str)
        #experiment.log_text()

        experiment.log_image("/Users/daven/Downloads/greenSquare.jpg", "my-image", step=1)
        experiment.log_image("/Users/daven/Downloads/redSquare.jpg", "my-image", step=2)
        experiment.log_image("/Users/daven/Downloads/blueSquare.jpg", "my-image", step=3)
        experiment.log_image("/Users/daven/Downloads/yellowSquare.jpg", "my-image", step=4)

        model = build_model_graph(experiment)

        train(experiment, model, x_train, y_train, x_test, y_test)

        evaluate(experiment, model, x_test, y_test)

if __name__ == "__main__":
    main()


from optparse import make_option
from ..base import BaseBowerCommand

class Command(BaseBowerCommand):
    help = 'Install bower apps'

    # for Django<1.10
    option_list = BaseBowerCommand.option_list + (
        make_option('-F',
                    action='store_true',
                    dest='force',
                    default=False,
                    help='Force installation of latest package version on conflict'),
        make_option('-R', '--allow-root',
                    action='store_true',
                    dest='allow-root',
                    default=False,
                    help='Allow installing bower packages even when user executing this script is root'),
    )
    # for Django>=1.10
    def add_arguments(self, parser):
        parser.add_argument('--force',
                            '-F',
                            action='store_true',
                            dest='force',
                            default=False,
                            help='Force installation of latest package version on conflict')
        parser.add_argument('--allow-root',
                            '-R',
                            action='store_true',
                            dest='allow-root',
                            default=False,
                            help='Allow installing bower packages even when user executing this script is root')

    def handle(self, *args, **options):
        super(Command, self).handle(*args, **options)

        if options.get('force'):
            args = args + ("-F", )

        if options.get('allow-root'):
            args = args + ("--allow-root", )

        self._install(args)


class Vertex:
    def __init__(self, data):
        self.data = data
        self.parent = None
        self.left_child = None
        self.right_child = None

    def add_left_child(self, other):
        self.left_child = other
        other.parent = self

    def add_right_child(self, other):
        self.right_child = other
        other.parent = self

    def get_left_child(self):
        return self.left_child

    def get_right_child(self):
        return self.right_child

    def visit(self, end=' '):
        print(self.data, end=end)

    def traverse_inorder(self):
        if self.left_child is not None:
            self.left_child.traverse_inorder()
        self.visit()
        if self.right_child is not None:
            self.right_child.traverse_inorder()

    def traverse_preorder(self):
        self.visit()
        if self.left_child is not None:
            self.left_child.traverse_preorder()
        if self.right_child is not None:
            self.right_child.traverse_preorder()

    def traverse_postorder(self):
        if self.left_child is not None:
            self.left_child.traverse_postorder()
        if self.right_child is not None:
            self.right_child.traverse_postorder()
        self.visit()

    def has_right_child(self):
        return self.right_child is not None

    def has_left_child(self):
        return self.left_child is not None

    def __le__(self, other):
        if isinstance(other, Vertex):
            return self.data <= other.data
        else:
            return self.data <= other

    def __gt__(self, other):
        if isinstance(other, Vertex):
            return self.data > other.data
        else:
            return self.data > other

def create_binary_search_tree(arr):
    # Takes a list of integers and converts it to a BST. Returns the root of this BST (instance of Vertex)
    root = Vertex(arr[0])
    for number in arr[1:]:
        new_vertex = Vertex(number)
        parent = root
        while True:
            if new_vertex <= parent:
                if parent.has_left_child():
                    parent = parent.get_left_child()
                else:
                    parent.add_left_child(new_vertex)
                    break
            else:
                if parent.has_right_child():
                    parent = parent.get_right_child()
                else:
                    parent.add_right_child(new_vertex)
                    break
    return root

bst_root = create_binary_search_tree([ 21, 14, 35, 10, 12, 41, 26, 30, 39, 11, 44, 36])

print("Pre order:", end='\t')
bst_root.traverse_preorder()
print("\nIn order: ", end='\t')
bst_root.traverse_inorder()
print("\nPost order: ", end='\t')
bst_root.traverse_postorder()
print()