import logging
import os
import pickle
from itertools import cycle
from typing import List, Optional

import numpy as np
import torch
from anndata import AnnData, read
from torch.utils.data import DataLoader

from scvi import _CONSTANTS, settings
from scvi.data import transfer_anndata_setup
from scvi.dataloaders import AnnDataLoader
from scvi.lightning import Trainer
from scvi.model._utils import _get_var_names_from_setup_anndata
from scvi.model.base import BaseModelClass, VAEMixin

from ._module import JVAE
from ._task import GIMVITrainingPlan

logger = logging.getLogger(__name__)

def _unpack_tensors(tensors):
    x = tensors[_CONSTANTS.X_KEY].squeeze_(0)
    local_l_mean = tensors[_CONSTANTS.LOCAL_L_MEAN_KEY].squeeze_(0)
    local_l_var = tensors[_CONSTANTS.LOCAL_L_VAR_KEY].squeeze_(0)
    batch_index = tensors[_CONSTANTS.BATCH_KEY].squeeze_(0)
    y = tensors[_CONSTANTS.LABELS_KEY].squeeze_(0)
    return x, local_l_mean, local_l_var, batch_index, y

class GIMVI(VAEMixin, BaseModelClass):
    """
    Joint VAE for imputing missing genes in spatial data [Lopez19]_.

    Parameters
    ----------
    adata_seq
        AnnData object that has been registered via :func:`~scvi.data.setup_anndata`
        and contains RNA-seq data.
    adata_spatial
        AnnData object that has been registered via :func:`~scvi.data.setup_anndata`
        and contains spatial data.
    n_hidden
        Number of nodes per hidden layer.
    generative_distributions
        List of generative distribution for adata_seq data and adata_spatial data.
    model_library_size
        List of bool of whether to model library size for adata_seq and adata_spatial.
    n_latent
        Dimensionality of the latent space.
    use_gpu
        Use the GPU or not.
    **model_kwargs
        Keyword args for :class:`~scvi.modules.JVAE`

    Examples
    --------
    >>> adata_seq = anndata.read_h5ad(path_to_anndata_seq)
    >>> adata_spatial = anndata.read_h5ad(path_to_anndata_spatial)
    >>> scvi.data.setup_anndata(adata_seq)
    >>> scvi.data.setup_anndata(adata_spatial)
    >>> vae = scvi.model.GIMVI(adata_seq, adata_spatial)
    >>> vae.train(n_epochs=400)
    """

    def __init__(
        self,
        adata_seq: AnnData,
        adata_spatial: AnnData,
        generative_distributions: List = ["zinb", "nb"],
        model_library_size: List = [True, False],
        n_latent: int = 10,
        use_gpu: bool = True,
        **model_kwargs,
    ):
        super(GIMVI, self).__init__(use_gpu=use_gpu)
        self.use_gpu = use_gpu and torch.cuda.is_available()
        self.adatas = [adata_seq, adata_spatial]
        self.scvi_setup_dicts_ = {
            "seq": adata_seq.uns["_scvi"],
            "spatial": adata_spatial.uns["_scvi"],
        }

        seq_var_names = _get_var_names_from_setup_anndata(adata_seq)
        spatial_var_names = _get_var_names_from_setup_anndata(adata_spatial)

        if not set(spatial_var_names) <= set(seq_var_names):
            raise ValueError("spatial genes needs to be subset of seq genes")

        spatial_gene_loc = [
            np.argwhere(seq_var_names == g)[0] for g in spatial_var_names
        ]
        spatial_gene_loc = np.concatenate(spatial_gene_loc)
        gene_mappings = [slice(None), spatial_gene_loc]
        sum_stats = [d.uns["_scvi"]["summary_stats"] for d in self.adatas]
        n_inputs = [s["n_vars"] for s in sum_stats]

        total_genes = adata_seq.uns["_scvi"]["summary_stats"]["n_vars"]

        # since we are combining datasets, we need to increment the batch_idx
        # of one of the datasets
        adata_seq_n_batches = adata_seq.uns["_scvi"]["summary_stats"]["n_batch"]
        adata_spatial.obs["_scvi_batch"] += adata_seq_n_batches

        n_batches = sum([s["n_batch"] for s in sum_stats])

        self.module = JVAE(
            n_inputs,
            total_genes,
            gene_mappings,
            generative_distributions,
            model_library_size,
            n_batch=n_batches,
            n_latent=n_latent,
            **model_kwargs,
        )

        self._model_summary_string = (
            "GimVI Model with the following params: \nn_latent: {}, n_inputs: {}, n_genes: {}, "
            + "n_batch: {}, generative distributions: {}"
        ).format(n_latent, n_inputs, total_genes, n_batches, generative_distributions)
        self.init_params_ = self._get_init_params(locals())

    def train(
        self,
        max_epochs: int = 200,
        use_gpu: Optional[bool] = None,
        kappa: int = 5,
        train_size: float = 0.9,
        validation_size: Optional[float] = None,
        batch_size: int = 128,
        plan_kwargs: Optional[dict] = None,
        plan_class: Optional[None] = None,
        **kwargs,
    ):
        """
        Train the model.

        Parameters
        ----------
        max_epochs
            Number of passes through the dataset. If `None`, defaults to
            `np.min([round((20000 / n_cells) * 400), 400])`
        use_gpu
            If `True`, use the GPU if available. Will override the use_gpu option when initializing model
        kappa
            Scaling parameter for the discriminator loss.
        train_size
            Size of training set in the range [0.0, 1.0].
        validation_size
            Size of the test set. If `None`, defaults to 1 - `train_size`. If
            `train_size + validation_size < 1`, the remaining cells belong to a test set.
        batch_size
            Minibatch size to use during training.
        plan_kwargs
            Keyword args for model-specific Pytorch Lightning task. Keyword arguments passed to
            `train()` will overwrite values present in `plan_kwargs`, when appropriate.
        **kwargs
            Other keyword args for :class:`~scvi.lightning.Trainer`.
        """
        if use_gpu is None:
            use_gpu = self.use_gpu
        else:
            use_gpu = use_gpu and torch.cuda.is_available()
        gpus = 1 if use_gpu else None
        pin_memory = (
            True if (settings.dl_pin_memory_gpu_training and use_gpu) else False
        )

        self.trainer = Trainer(
            max_epochs=max_epochs,
            gpus=gpus,
            **kwargs,
        )
        self.train_indices_, self.test_indices_, self.validation_indices_ = [], [], []
        train_dls, test_dls, val_dls = [], [], []
        for i, ad in enumerate(self.adatas):
            train, val, test = self._train_test_val_split(
                ad,
                train_size=train_size,
                validation_size=validation_size,
                pin_memory=pin_memory,
                batch_size=batch_size,
            )
            train_dls.append(train)
            test_dls.append(test)
            val.mode = i
            val_dls.append(val)
            self.train_indices_.append(train.indices)
            self.test_indices_.append(test.indices)
            self.validation_indices_.append(val.indices)
        train_dl = TrainDL(train_dls)

        plan_kwargs = plan_kwargs if isinstance(plan_kwargs, dict) else dict()
        self._pl_task = self._plan_class(
            self.module,
            len(self.train_indices_),
            adversarial_classifier=True,
            scale_adversarial_loss=kappa,
            **plan_kwargs,
        )

        if train_size == 1.0:
            # circumvent the empty data loader problem if all dataset used for training
            self.trainer.fit(self._pl_task, train_dl)
        else:
            # accepts list of val dataloaders
            self.trainer.fit(self._pl_task, train_dl, val_dls)
        try:
            self.history_ = self.trainer.logger.history
        except AttributeError:
            self.history_ = None
        self.module.eval()
        if use_gpu:
            self.module.cuda()
        self.is_trained_ = True

    def _make_scvi_dls(self, adatas: List[AnnData] = None, batch_size=128):
        if adatas is None:
            adatas = self.adatas
        post_list = [self._make_scvi_dl(ad) for ad in adatas]
        for i, dl in enumerate(post_list):
            dl.mode = i

        return post_list

    @torch.no_grad()
    def get_latent_representation(
        self,
        adatas: List[AnnData] = None,
        deterministic: bool = True,
        batch_size: int = 128,
    ) -> List[np.ndarray]:
        """
        Return the latent space embedding for each dataset.

        Parameters
        ----------
        adatas
            List of adata seq and adata spatial.
        deterministic
            If true, use the mean of the encoder instead of a Gaussian sample.
        batch_size
            Minibatch size for data loading into model.
        """
        if adatas is None:
            adatas = self.adatas
        scdls = self._make_scvi_dls(adatas, batch_size=batch_size)
        self.module.eval()
        latents = []
        for mode, scdl in enumerate(scdls):
            latent = []
            for tensors in scdl:
                (
                    sample_batch,
                    local_l_mean,
                    local_l_var,
                    batch_index,
                    label,
                    *_,
                ) = _unpack_tensors(tensors)
                latent.append(
                    self.module.sample_from_posterior_z(
                        sample_batch, mode, deterministic=deterministic
                    )
                )

            latent = torch.cat(latent).cpu().detach().numpy()
            latents.append(latent)

        return latents

    @torch.no_grad()
    def get_imputed_values(
        self,
        adatas: List[AnnData] = None,
        deterministic: bool = True,
        normalized: bool = True,
        decode_mode: Optional[int] = None,
        batch_size: int = 128,
    ) -> List[np.ndarray]:
        """
        Return imputed values for all genes for each dataset.

        Parameters
        ----------
        adatas
            List of adata seq and adata spatial
        deterministic
            If true, use the mean of the encoder instead of a Gaussian sample for the latent vector.
        normalized
            Return imputed normalized values or not.
        decode_mode
            If a `decode_mode` is given, use the encoder specific to each dataset as usual but use
            the decoder of the dataset of id `decode_mode` to impute values.
        batch_size
            Minibatch size for data loading into model.
        """
        self.module.eval()

        if adatas is None:
            adatas = self.adatas
        scdls = self._make_scvi_dls(adatas, batch_size=batch_size)

        imputed_values = []
        for mode, scdl in enumerate(scdls):
            imputed_value = []
            for tensors in scdl:
                (
                    sample_batch,
                    local_l_mean,
                    local_l_var,
                    batch_index,
                    label,
                    *_,
                ) = _unpack_tensors(tensors)
                if normalized:
                    imputed_value.append(
                        self.module.sample_scale(
                            sample_batch,
                            mode,
                            batch_index,
                            label,
                            deterministic=deterministic,
                            decode_mode=decode_mode,
                        )
                    )
                else:
                    imputed_value.append(
                        self.module.sample_rate(
                            sample_batch,
                            mode,
                            batch_index,
                            label,
                            deterministic=deterministic,
                            decode_mode=decode_mode,
                        )
                    )

            imputed_value = torch.cat(imputed_value).cpu().detach().numpy()
            imputed_values.append(imputed_value)

        return imputed_values

    def save(
        self,
        dir_path: str,
        overwrite: bool = False,
        save_anndata: bool = False,
        **anndata_write_kwargs,
    ):
        """
        Save the state of the model.

        Neither the trainer optimizer state nor the trainer history are saved.
        Model files are not expected to be reproducibly saved and loaded across versions
        until we reach version 1.0.

        Parameters
        ----------
        dir_path
            Path to a directory.
        overwrite
            Overwrite existing data or not. If `False` and directory
            already exists at `dir_path`, error will be raised.
        save_anndata
            If True, also saves the anndata
        anndata_write_kwargs
            Kwargs for anndata write function
        """
        # get all the user attributes
        user_attributes = self._get_user_attributes()
        # only save the public attributes with _ at the very end
        user_attributes = {a[0]: a[1] for a in user_attributes if a[0][-1] == "_"}
        # save the model state dict and the trainer state dict only
        if not os.path.exists(dir_path) or overwrite:
            os.makedirs(dir_path, exist_ok=overwrite)
        else:
            raise ValueError(
                "{} already exists. Please provide an unexisting directory for saving.".format(
                    dir_path
                )
            )
        if save_anndata:
            dataset_names = ["seq", "spatial"]
            for i in range(len(self.adatas)):
                save_path = os.path.join(
                    dir_path, "adata_{}.h5ad".format(dataset_names[i])
                )
                self.adatas[i].write(save_path)
                varnames_save_path = os.path.join(
                    dir_path, "var_names_{}.csv".format(dataset_names[i])
                )

                var_names = self.adatas[i].var_names.astype(str)
                var_names = var_names.to_numpy()
                np.savetxt(varnames_save_path, var_names, fmt="%s")

        model_save_path = os.path.join(dir_path, "model_params.pt")
        attr_save_path = os.path.join(dir_path, "attr.pkl")

        torch.save(self.module.state_dict(), model_save_path)
        with open(attr_save_path, "wb") as f:
            pickle.dump(user_attributes, f)

    @classmethod
    def load(
        cls,
        dir_path: str,
        adata_seq: Optional[AnnData] = None,
        adata_spatial: Optional[AnnData] = None,
        use_gpu: Optional[bool] = None,
    ):
        """
        Instantiate a model from the saved output.

        Parameters
        ----------
        adata_seq
            AnnData organized in the same way as data used to train model.
            It is not necessary to run :func:`~scvi.data.setup_anndata`,
            as AnnData is validated against the saved `scvi` setup dictionary.
            AnnData must be registered via :func:`~scvi.data.setup_anndata`.
        adata_spatial
            AnnData organized in the same way as data used to train model.
            If None, will check for and load anndata saved with the model.
        dir_path
            Path to saved outputs.
        use_gpu
            Whether to load model on GPU.

        Returns
        -------
        Model with loaded state dictionaries.

        Examples
        --------
        >>> vae = GIMVI.load(adata_seq, adata_spatial, save_path)
        >>> vae.get_latent_representation()
        """
        model_path = os.path.join(dir_path, "model_params.pt")
        setup_dict_path = os.path.join(dir_path, "attr.pkl")
        seq_data_path = os.path.join(dir_path, "adata_seq.h5ad")
        spatial_data_path = os.path.join(dir_path, "adata_spatial.h5ad")
        seq_var_names_path = os.path.join(dir_path, "var_names_seq.csv")
        spatial_var_names_path = os.path.join(dir_path, "var_names_spatial.csv")

        if adata_seq is None and os.path.exists(seq_data_path):
            adata_seq = read(seq_data_path)
        elif adata_seq is None and not os.path.exists(seq_data_path):
            raise ValueError(
                "Save path contains no saved anndata and no adata was passed."
            )
        if adata_spatial is None and os.path.exists(spatial_data_path):
            adata_spatial = read(spatial_data_path)
        elif adata_spatial is None and not os.path.exists(spatial_data_path):
            raise ValueError(
                "Save path contains no saved anndata and no adata was passed."
            )
        adatas = [adata_seq, adata_spatial]

        seq_var_names = np.genfromtxt(seq_var_names_path, delimiter=",", dtype=str)
        spatial_var_names = np.genfromtxt(
            spatial_var_names_path, delimiter=",", dtype=str
        )
        var_names = [seq_var_names, spatial_var_names]

        for i, adata in enumerate(adatas):
            saved_var_names = var_names[i]
            user_var_names = adata.var_names.astype(str)
            if not np.array_equal(saved_var_names, user_var_names):
                logger.warning(
                    "var_names for adata passed in does not match var_names of "
                    "adata used to train the model. For valid results, the vars "
                    "need to be the same and in the same order as the adata used to train the model."
                )

        with open(setup_dict_path, "rb") as handle:
            attr_dict = pickle.load(handle)

        scvi_setup_dicts = attr_dict.pop("scvi_setup_dicts_")
        transfer_anndata_setup(scvi_setup_dicts["seq"], adata_seq)
        transfer_anndata_setup(scvi_setup_dicts["spatial"], adata_spatial)

        # get the parameters for the class init signiture
        init_params = attr_dict.pop("init_params_")

        # update use_gpu from the saved model
        if use_gpu is None:
            use_gpu = torch.cuda.is_available()

        init_params["use_gpu"] = use_gpu

        # new saving and loading, enable backwards compatibility
        if "non_kwargs" in init_params.keys():
            # grab all the parameters execept for kwargs (is a dict)
            non_kwargs = init_params["non_kwargs"]
            kwargs = init_params["kwargs"]

            # update use_gpu from the saved model
            # we assume use_gpu is exposed and not a kwarg
            non_kwargs["use_gpu"] = use_gpu

            # expand out kwargs
            kwargs = {k: v for (i, j) in kwargs.items() for (k, v) in j.items()}
        else:
            init_params["use_gpu"] = use_gpu

            # grab all the parameters execept for kwargs (is a dict)
            non_kwargs = {
                k: v for k, v in init_params.items() if not isinstance(v, dict)
            }
            kwargs = {k: v for k, v in init_params.items() if isinstance(v, dict)}
            kwargs = {k: v for (i, j) in kwargs.items() for (k, v) in j.items()}
        model = cls(adata_seq, adata_spatial, **non_kwargs, **kwargs)

        for attr, val in attr_dict.items():
            setattr(model, attr, val)

        if use_gpu:
            model.module.load_state_dict(torch.load(model_path))
            model.module.cuda()
        else:
            device = torch.device("cpu")
            model.module.load_state_dict(torch.load(model_path, map_location=device))
        model.module.eval()
        return model

    @property
    def _data_loader_cls(self):
        return AnnDataLoader

    @property
    def _plan_class(self):
        return GIMVITrainingPlan

class TrainDL(DataLoader):
    def __init__(self, data_loader_list, **kwargs):
        self.data_loader_list = data_loader_list
        self.largest_train_dl_idx = np.argmax(
            [len(dl.indices) for dl in data_loader_list]
        )
        self.largest_dl = self.data_loader_list[self.largest_train_dl_idx]
        super().__init__(self.largest_dl, **kwargs)

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

    def __iter__(self):
        train_dls = [
            dl if i == self.largest_train_dl_idx else cycle(dl)
            for i, dl in enumerate(self.data_loader_list)
        ]
        return zip(*train_dls)


#!/usr/bin/python3
def weight_average(my_list=[]):
    if not my_list:
        return 0
    suma = 0
    count = 0
    for i, j in enumerate(my_list):
        suma += j[0] * j[1]
        count += j[1]
    return suma / count


# Implementation of fast modular exponentiation

def FastModularExponentiation(b, e, m):
    binary = bin(e)[2:]
    binary = binary[::-1]
    r = 1
    x = b
    for i in binary:
        if i == '1':
            r = (r * x) % m
            x = (x ** 2 ) % m
        else:
            x = (x ** 2) % m
    return r


# -*- coding: utf-8 -*-

import common
import logging
import json
from tornado.options import options
from autumn.api.zhutong import Zhutong
from autumn.utils import json_hook

def main_loop():
    redis = common.redis_client()
    logging.info('----- coupon sms send consumer starts -----')

    while common.running():
        message_raw = redis.brpoplpush(options.queue_coupon_send, options.queue_coupon_send_processing)
        logging.info('get sms task: %s' % message_raw)
        task = json.loads(message_raw, object_hook=json_hook)
        mobile = task.mobile
        content = task.sms.encode('utf-8')

        # 检查手机号码长度
        if len(mobile) != 11:
            logging.error('coupon sms send consumer error: mobile number %s is not valid' % mobile)
            continue

        # 发送请求
        zt = Zhutong()
        try:
            response = zt.sync_fetch(mobile=mobile, content=content, xh='')
            zt.parse_response(response)

            if zt.is_ok():
                redis.lrem(options.queue_coupon_send_processing, 0, message_raw)
                logging.info('send sms successfully: %s' % content)
            elif int(zt.message) == 13:
                redis.lrem(options.queue_coupon_send_processing, 0, message_raw)
                logging.info('send sms faied, 30分钟重复提交')
            else:
                redis.lpush(options.queue_coupon_send_emay, message_raw)
                logging.error('send sms failed, zhutong response error: %s', response)
        except:
            redis.lpush(options.queue_coupon_send_emay, message_raw)
            logging.error('send sms failed, zhutong connection reset')

    logging.info('----- coupon sms sender consumer shut down -----')

if __name__ == '__main__':
    common.set_up()

    main_loop()


from django.conf.urls import url
from django.contrib import admin
from django.urls import path, include
from apidemo import views
from django.contrib.auth import views as auth_views
from rest_framework_swagger.views import get_swagger_view
schema_view = get_swagger_view(title='fundooNotes')
urlpatterns = [

    #Admin Panel and Index.

    #path('admin/', admin.site.urls),
    path('', views.login_v,name='login_v'),
    #path('api/',include('urls.apidemo')),
    # URLS for REST API

    path('rest_register/', views.Signup,name='rest_register'),  # Registration using REST.
    path('rest_login/', views.LoginView.as_view(), name='rest_login'),       # REST Login.
    path('dash/', include('rest_framework.urls', namespace='rest_framework')),

    # Login,Logout And Registration

    path('user_login/', views.demo_user_login,name='user_login'),
    url(r'^signup/$', views.Signup, name='signup'),
    path('login_v/', views.login_v, name='login_v'),
    url(r'^activate/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$',
        views.activate, name='activate'),
    path('logout/', views.logout, name='logout'),

    # Reset Password

    url(r'^password_reset/$', auth_views.PasswordResetView.as_view(), name='password_reset'),
    url(r'^password_reset/done/$', auth_views.PasswordResetDoneView.as_view(), name='password_reset_done'),
    url(r'^reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$',
        auth_views.PasswordResetConfirmView.as_view(), name='password_reset_confirm'),
    url(r'^reset/done/$', auth_views.PasswordResetCompleteView.as_view(), name='password_reset_complete'),

    # Upload Profile Pic
    path('upload_profile/', views.upload_profile, name='upload_profile'),
    path('open_upload_form/', views.open_upload_form, name='open_upload_form'),
    path('profile_page/', views.profile_page, name='profile_page'),

    #Base Template

    path('base/', views.base, name='base'),

    #crop profile picture

    path('crop/', views.crop, name='crop'),
    path('photo_list/', views.photo_list, name='photo_list'),

    path('demo/',views.demo,name='demo'),

    # CRUD Operations

    path('addnote/', views.AddNote.as_view(),name='addnote'),
    #deletenote
    path('delete/<int:id>/',views.deleteN, name='deleteN'),
    #getnotes
    #move_to_trash
    path('move_to_trash/<int:id>/',views.trash, name='move_to_trash'),

    path('getnotes/', views.getnotes.as_view(), name='getnotes'),
    #updatenote
    path('updatenote/<int:pk>/', views.updatenote.as_view(),name='updatenote'),
    path('updateform/<int:pk>/', views.updateform, name='updateform'),

    #updateNotes
    path('updateNotes/<int:pk>/', views.updateNotes, name='updateNotes'),

    #pin_unpin
    path('pin_unpin/<int:pk>/', views.pin_unpin, name='pin_unpin'),

    #trash
    path('trash/<int:pk>/', views.trash, name='trash'),
    #view_trash
    path('view_trash/', views.view_trash.as_view(), name='view_trash'),

    #delete_forever
    path('delete_forever/<int:pk>/', views.delete_forever, name='delete_forever'),

    #is_archived
    path('is_archived/<int:pk>/', views.is_archived, name='is_archived'),
    #View_is_archived
    path('View_is_archived/', views.View_is_archived.as_view(), name='View_is_archived'),
    #set_card_reminder
    path('set_card_reminder/<int:pk>/', views.set_card_reminder.as_view(), name='set_card_reminder'),

    # Labels
    #add_labels
    path('add_labels/<int:pk>/', views.add_labels, name='add_labels'),
    #map_labels
    path('map_labels/', views.map_labels, name='map_labels'),
    #delete_label
    path('delete_label/<int:pk>/', views.delete_label, name='delete_label'),
    #view_notes_for_each_label
    path('view_notes_for_each_label/<int:pk>/', views.view_notes_for_each_label, name='view_notes_for_each_label'),
    #copy_note
    path('copy_note/<int:pk>/', views.copy_note, name='copy_note'),
    #remove_labels
    path('remove_labels/<int:id>/<int:key>/', views.remove_labels, name='remove_labels'),

    # ×

    # Search
    path('search/',views.search,name='search'),

    #reminder
    path('reminder/', views.reminder, name='reminder'),
    path('View_reminder/', views.View_reminder.as_view(), name='View_reminder'),

    #Update
    path('Update/<int:pk>/', views.Update.as_view(), name='Update'),
    #View_reminder

    #change_color
    path('change_color/<int:pk>/', views.change_color, name='change_color'),

    #auto_delete_archive
    path('auto_delete_archive/', views.auto_delete_archive, name='auto_delete_archive'),

    #invite
    path('invite/', views.invite, name='invite'),

    #delete_from_s3
    path('delete_from_s3/', views.delete_from_s3, name='delete_from_s3'),

    url(r'^swagger/$', schema_view),

    # REST API's

    #delete_collaborator
    path('delete_collaborator/<int:user_id>/<int:note_id>/',views.delete_collaborator.as_view(),name='delete_collaborator'),

    #get_single_note
    path('get_data_by_id/<int:pk>/', views.get_data_by_id.as_view(), name='get_data_by_id'),

    #delete_note_by_id
    path('delete_note_by_id/<int:pk>/', views.delete_note_by_id.as_view(), name='delete_note_by_id'),

    #add_label
    path('add_label/<int:pk>/', views.add_label.as_view(), name='add_label'),

    #delete_created_label
    path('delete_created_label/<int:pk>/', views.delete_created_label.as_view(), name='delete_created_label'),

    #map_label_with_note
    path('map_label_with_note/<int:user_id>/<int:note_id>/<int:label_id>/', views.map_label_with_note.as_view(),
         name='map_label_with_note'),

    #update_label
    path('update_label/<int:label_id>/<int:user_id>/', views.update_label.as_view(), name='update_label'),

    #get_noteLabel_list
    path('get_noteLabel_list/<int:note_id>/', views.get_noteLabel_list.as_view(), name='get_noteLabel_list'),

    #get_colaborator_for_note
    path('get_colaborator_for_note/<int:note_id>/', views.get_colaborator_for_note.as_view(), name='get_colaborator_for_note'),

    #get_notes_of_label
    path('get_notes_of_label/<int:label_id>/', views.get_notes_of_label.as_view(),
         name='get_notes_of_label'),

    # make_note_archive
    path('make_note_archive/<int:note_id>/', views.make_note_archive.as_view(),
         name='make_note_archive'),

    #make_note_trash
    path('make_note_trash/<int:note_id>/', views.make_note_trash.as_view(),
         name='make_note_trash'),
    #note_pin_unpin
    path('note_pin_unpin/<int:note_id>/', views.note_pin_unpin.as_view(),
         name='note_pin_unpin'),

    #view_archived_notes
    path('view_archived_notes/<int:user_id>/', views.view_archived_notes.as_view(),
         name='view_archived_notes'),
    #view_trash_notes
    path('view_trash_notes/<int:user_id>/', views.view_trash_notes.as_view(),
         name='view_trash_notes'),
    #view_pinned_notes
    path('view_pinned_notes/<int:user_id>/', views.view_pinned_notes.as_view(),
         name='view_pinned_notes'),
    #update_details
    path('update_details/<int:note_id>/', views.update_details.as_view(),
         name='update_details'),
    #reminder_notification
    path('reminder_notification/', views.reminder_notification.as_view(),
         name='reminder_notification'),
    #view_reminder_notes
    path('view_reminder_notes/<int:user_id>/', views.view_reminder_notes.as_view(),
         name='view_reminder_notes'),

    url(r'^oauth/', include('social_django.urls', namespace='social')),  # <--

    url(r'^elasticsearch/', views.search, name='search'),

]


import pygame
from .vector import *

class MassPoint():
    def __init__(self, x, y, m=1, v=(0, 0)):
        self.coords = Vector(x, y)
        self.m = m
        self.velosity = Vector(v[0], v[1])
        self.shiftVector = Vector()

    def force(self, massPoint):
        if self.m and massPoint.m:
            linkVector = massPoint.coords - self.coords
            f = (massPoint.m / abs(linkVector)**3) * linkVector
            return f
        return Vector()

    def update_position(self):
        self.coords += self.shiftVector
        self.shiftVector = Vector()

    def shift(self, solar_system, dt):
        # x_n+1 - 2x_n + x_n-1 = force_n/m*dt**2
        # x_n+1 = F/m * dt**2 + x_n + (x_n - x_n-1)
        for astrObj in solar_system:
            if dt > 0 and self is not astrObj.massPoint:
                objForce = self.force(astrObj.massPoint)
                self.shiftVector += objForce * dt**2
        self.shiftVector += self.velosity * dt
        self.velosity = self.shiftVector * (1 / dt)

    def setVelosity(self, event):
        if event.key == pygame.K_RIGHT:
            self.velosity.x += 10
        if event.key == pygame.K_LEFT:
            self.velosity.x -= 10
        if event.key == pygame.K_UP:
            self.velosity.y -= 10
        if event.key == pygame.K_DOWN:
            self.velosity.y += 10


#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# 判断目录之下是否有sqlite3文件

import sys
import os

def is_sqlite(file):
    if not os.path.isfile(file):return False
    if os.path.getsize(file) < 100: return False
    else:
        f = open(file, 'r')
        header = f.read(100) # read 100 bytes
        return True if header[0:16] == 'SQLite format 3\000' else False

if __name__ == "__main__":

    check_dir = os.path.expanduser('~') if len(sys.argv) < 2 else sys.argv[1]

    if not os.path.isdir(check_dir):
        print(check_dir + ' is not a dir')
        exit(1)

    _sqlite_files = []
    for dirpath, dirnames, filenames in os.walk(check_dir):
        for file in filenames:
            if is_sqlite(file):
                print('find a sqlite file:' + os.path.join(dirpath, file))
                _sqlite_files.append(os.path.join(dirpath, file))

    if len(_sqlite_files) == 0:
        print('no sqlite file')
    else: print(_sqlite_files)


from xai.brain.wordbase.nouns._liturgy import _LITURGY

#calss header
class _LITURGIES(_LITURGY, ):
	def __init__(self,):
		_LITURGY.__init__(self)
		self.name = "LITURGIES"
		self.specie = 'nouns'
		self.basic = "liturgy"
		self.jsondata = {}


import cv2
import glob

paths = glob.glob('row/*')

for index,path in enumerate(paths):
    image = cv2.imread(path, 0)
    ret, th = cv2.threshold(image, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU )

    cv2.imwrite('bw/%06d.jpg' % index, th)


def getHostDomain():
    import socket
    fqdn = socket.getfqdn().split('.')
    host = ''
    domain=''
    if len(fqdn) > 1:
        host = fqdn[0]
        domain=fqdn[-2]+'.'+fqdn[-1]
    else :
    	host=socket.getfqdn()
    	domain=''
    return host,domain

sitesInfo = {
              'cmssdt' :
                    { 'afsPath'     : '/data/sdt/buildlogs/',
                      'OutPath'     : '/data/sdt/sdtQA/intbld/',
                      'HtmlPath'    : '/SDT/html/',
                      'CgiHtmlPath' : 'http://cmssdt.cern.ch/SDT/cgi-bin/',
                      'OutHtml'     : 'http://cmssdt.cern.ch/SDT/intbld/',
                      'macms01Path' : 'http://cmssdt.cern.ch/SDT/cgi-bin/',
                      'qaPath'      : '/data/intBld/incoming/'
                     },
            }
siteInfo = sitesInfo['cmssdt']


def op(ans, case):
    for i in map(str, range(0,25)):
        ans = ans.replace(i, chr(ord('A') + int(i)))
    print("Case #%d: %s" %(case + 1, ans))

for _ in range(int(input())):
    n = int(input())
    l = list(map(int ,input().split()))
    l = [[i, l[i]] for i in range(n)]

    tot = sum([e[1] for e in l])

    a = []
    empty = 0

    while tot!=0:
        l.sort(key = lambda x: x[1])
        if l[-1][1] == l[-2][1] and (n<=2 or l[-3][1]!=1):
            a.append(str(l[-1][0]) + str(l[-2][0]))
            l[-1][1]-=1
            l[-2][1]-=1
            tot-=2
        else:
            a.append(str(l[-1][0]))
            l[-1][1]-=1
            tot-=1

    op(" ".join(a), _)


import sys
import random
import numpy as np

from tqdm import tqdm
from agent import Agent

from collections import deque

class DDQN:
    """ Deep Q-Learning Main Algorithm
    """

    def __init__(self, action_dim, state_dim):
        """ Initialization
        """
        # Environment and DDQN parameters
        self.with_per = False
        self.action_dim = action_dim
        self.state_dim = (4,) + state_dim
        #
        self.lr = 2.5e-4
        self.gamma = 0.95
        self.epsilon = 0.8
        self.epsilon_decay = 0.99
        self.target_update_counter = 1
        #
        if(len(state_dim) < 3):
            self.tau = 1e-2
        else:
            self.tau = 1.0
        # Create actor and critic networks
        self.agent = Agent(self.state_dim, action_dim, self.lr, self.tau, True)
        # Memory Buffer for Experience Replay
        self.replay_memory=deque(maxlen=10_000)

    def policy_action(self, s):
        """ Apply an espilon-greedy policy to pick next action
        """
        if np.random.random() <= self.epsilon:
            return random.randrange(self.action_dim)
        else:
            return np.argmax(self.agent.predict(s)[0])
    def train(self, old_state, state, reward, done):

        # Start training only if certain number of samples is already saved
        if len(self.replay_memory)< 1_000:
            return

        # Get a minibatch of random samples from memory replay table
        minibatch = random.sample(self.replay_memory, 64)

        # Get current states from minibatch, then query NN model for Q values
        current_states = np.array([transition[0] for transition in minibatch])/255
        current_qs_list = self.agent.predict(current_states)

        # Get future states from minibatch, then query NN model for Q values
        # When using target network, query it, otherwise main network should be queried
        new_current_states = np.array([transition[3] for transition in minibatch])/255
        future_qs_list = self.agent.predict(new_current_states)

        X = []
        y = []

        # Now we need to enumerate our batches
        for index, (current_state, action, reward, new_current_state, done) in enumerate(minibatch):

            # If not a terminal state, get new q from future states, otherwise set it to 0
            # almost like with Q Learning, but we use just part of equation here
            if not done:
                max_future_q = np.max(future_qs_list[index])
                new_q = reward + 0.99 * max_future_q
            else:
                new_q = reward

            # Update Q value for given state
            current_qs = current_qs_list[index]
            current_qs[action] = new_q

            # And append to our training data
            X.append(current_state)
            y.append(current_qs)

        # Fit on all samples as one batch, log only on terminal state
        self.agent.fit(X, y)

        # Update target network counter every episode
        if done:
            self.target_update_counter += 1

        # If counter reaches set value, update target network with weights of main network
        if self.target_update_counter >= 5:
            MODEL_FILE='models/MODEL.h5'
            self.agent.load_weights(MODEL_FILE)
            self.target_update_counter = 0

    def memorize(self, transition):
        """ Store experience in memory buffer
        """

        td_error = 0
        self.replay_memory.append(transition)

    def save_weights(self, path):
        self.agent.save(path)

    def load_weights(self, path):
        self.agent.load_weights(path)


import numpy as np
import cv2

def harris_points(input_image):
    #noise removal
    input_img = cv2.imread(input_image)
    img_shape_x = input_img.shape[0]
    img_shape_y = input_img.shape[1]
    numerator = input_img ** 1.5
    denominator = input_img ** 0.5
    kernel = np.ones([3, 3], dtype = int)
    noise_filtered_img = cv2.filter2D(numerator, -1, kernel) / cv2.filter2D(denominator, -1, kernel)
    noise_filtered_img = noise_filtered_img.astype(np.uint8)
    #saliency detection
    salient_func = cv2.saliency.StaticSaliencyFineGrained_create()
    (stat, salient_img) = salient_func.computeSaliency(noise_filtered_img)
    salient_img = (salient_img*255).astype(np.uint8)
    #adding gaussain blur and thresholding
    blurred_img = cv2.GaussianBlur(salient_img,(3,3),0)
    thresh_img = cv2.adaptiveThreshold(blurred_img,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY_INV,3,2)
    #harris points detection algorithm
    grid_size = np.ceil(img_shape_x/100).astype(np.uint8)
    if grid_size<3: grid_size = 3
    k = 0.04
    harris_response = np.zeros((img_shape_x, img_shape_y))
    point_map = np.zeros_like(input_img)
    for i in range(0, img_shape_x, grid_size):
        for j in range(0, img_shape_y, grid_size):
            img_block = thresh_img[i:i+grid_size, j:j+grid_size]
            block_x, block_y = np.gradient(img_block) - np.mean(img_block)
            ixx = block_x**2
            iyy = block_y**2
            ixy = block_x*block_y
            # calculating the covariance matrix values
            sxx = np.sum(ixx)
            syy = np.sum(iyy)
            sxy = np.sum(ixy)
            covariance_matrix = np.array([[sxx,sxy],[sxy,syy]])
            # calculating the eigenvalues
            eig_vals = np.linalg.eigvals(covariance_matrix)
            # calculating the Harris Response
            harris_response[i,j] = min(eig_vals)
    # plotting the Harris Points
    point_map[harris_response>0] = [0,0,255]
    point_map = point_map.astype(np.uint8)
    return point_map


'''
https://www.python-course.eu/tkinter_layout_management.php
Place Geometry Manager
The Place geometry manager allows you explicitly set the position and size of a window, either in absolute terms, or relative to another window. The place manager can be accessed through the place method. It can be applied to all standard widgets.

We use the place geometry manager in the following example. We are playing around with colours in this example, i.e. we assign to every label a different colour, which we randomly create using the randrange method of the random module. We calculate the brightness (grey value) of each colour. If the brightness is less than 120, we set the foreground colour (fg) of the label to White otherwise to black, so that the text can be easier read.
'''

import Tkinter as tk
import random

root = tk.Tk()
# width x height + x_offset + y_offset:
root.geometry("170x200+30+30") #kp: it seems there cannot be any space around x & +
# kp: with the spaces, I got "_tkinter.TclError: bad geometry specifier "170 x 200 + 30 + 30""

languages = ['Python','Perl','C++','Java','Tcl/Tk']
labels = range(5) #kp: it's a list of 0, 1, 2, 3, 4

'''
List comprehensions: http://blog.teamtreehouse.com/python-single-line-loops
List comprehensions are lists that generate themselves with an internal for loop. They’re a very common feature in Python and they look something like:

[thing for thing in list_of_things]

see more below
'''

for i in range(5):
    #kp: Following line is a case of List Comprehension. Here, a list
    #    of 3 random integers between 0 and 255 (to represent color) is generated.
   ct = [random.randrange(256) for x in range(3)]
   brightness = int(round(0.299*ct[0] + 0.587*ct[1] + 0.114*ct[2]))
   ct_hex = "%02x%02x%02x" % tuple(ct)
   bg_colour = '#' + "".join(ct_hex)
   l = tk.Label(root,
                text=languages[i],
                fg='White' if brightness < 120 else 'Black',
                bg=bg_colour)
   l.place(x = 20, y = 30 + i*30, width=120, height=25)

root.mainloop()

'''
More on List comprehension:

List comprehensions save # of lines of code.

Let’s say I want to have a function that doubles the values all of the items in a list of numbers.

Equivalent code snippets

======== Code Snippet 1 ====
def list_doubler(lst):
    doubled = []
    for num in lst:
        doubled.append(num*2)
    return doubled

my_list = [21, 2, 93]
my_doubled_list = list_doubler(lst)

======== Code Snippet 2 ====
def list_doubler(lst):
    doubled = [num * 2 for num in lst]
    return doubled
my_list = [21, 2, 93]
my_doubled_list = list_doubler(lst)

======== Code Snippet 3 ====
my_list = [21, 2, 93]
my_doubled_list = [num * 2 for num in my_list]

'''


from __future__ import print_function

from http.server import BaseHTTPRequestHandler
from io import BytesIO

import signal
import pyuv

class HTTPRequest(BaseHTTPRequestHandler):
  def __init__(self, request_text):
    self.rfile = BytesIO(request_text)
    self.raw_requestline = self.rfile.readline()
    self.error_code = self.error_message = None
    self.parse_request()

  def send_error(self, code, message):
    self.error_code = code
    self.error_message = message

def on_read(client, data, error):
  if data is None:
    client.close()
    clients.remove(client)
    return
  path = HTTPRequest(data).path
  client.write(get_response(path).encode())

def on_connection(server, error):
  client = pyuv.TCP(server.loop)
  server.accept(client)
  clients.append(client)
  client.start_read(on_read)

def signal_cb(handle, signum):
  [c.close() for c in clients]
  signal_h.close()
  server.close()

def get_response(path):
  if path:
    try:
      filename = '../../res' + path
      f = open(filename, 'r')
      content = f.read()
      content_length = len(content)
      return 'HTTP/1.1 200 OK\nContent-Length: '+ str(content_length) + '\n\n'+ content + '\n'
    except FileNotFoundError as e:
      return 'HTTP/1.1 404 Not Found\n'+'Content-Length: 36\n' +'Content-Type: text/html\n'+'\n' +'Not Found\n'

print('PyUV version %s' % pyuv.__version__)

loop = pyuv.Loop.default_loop()
clients = []

server = pyuv.TCP(loop)
server.bind(('0.0.0.0', 1234))
server.listen(on_connection)

signal_h = pyuv.Signal(loop)
signal_h.start(signal_cb, signal.SIGINT)

loop.run()
print('Stopped!')


import pickle

def load_prepared(base_dir):
    try:
        with open(base_dir+'/PP.pkl', 'rb') as f:
            pp = pickle.load(f)
            f.close()
    except FileNotFoundError as e:
        print("cannot find PP.pkl")
        pp = []
    return pp

def load_finished(base_dir):
    try:
        with open(base_dir+'/FF.pkl', 'rb') as f:
            ff = pickle.load(f)
            f.close()
    except FileNotFoundError as e:
        print("cannot find FF.pkl")
        ff = []
    return ff

def shorten(s):
    if 'poly' in s:
        return s[s.find('poly'):]
    elif 'cBench' in s:
        return s[s.find('cBench'):]
    else:
        return s

def main():
    ff=load_finished('./workspace')
    pp=load_prepared('./workspace')
    print ('prepared:')
    print (len(pp))
    #for p in pp:
    #    print(shorten(p))
    print('\n')
    print ('finished:')
    print (len(ff))
    #for f in ff:
    #    print(shorten(f))

if __name__ == "__main__":
    main()


import config

import sys
import numpy as np
import matplotlib.pyplot as plt
from unityagents import UnityEnvironment
from agent.factory import AgentFactory

def train(env, agent):
    """
    Performs the main training loop.
    """

    max_score = 0
    scores = []
    scores_avg = []
    iterations = 0
    solved = False

    print('Training agent.')

    while iterations < config.MAX_ITERATIONS and not solved:
        # show a progress indication
        print('\repisode {}, max score so far is {}'.format(iterations, max_score), end='')
        sys.stdout.flush()

        iterations += 1

        done = False
        score = 0
        env_info = env.reset(train_mode=True)[agent.brain_name]  # reset the environment

        episode_steps = 0
        while not done and episode_steps < config.MAX_EPISODE_STEPS:
            episode_steps += 1

            state = env_info.vector_observations[0]
            action = agent.select_action(state)  # choose an action
            env_info = env.step(action)[agent.brain_name]  # execute that action
            reward, done = agent.step(state, action, env_info)  # give the agent the chance to learn from the results

            score += reward  # update score with the reward

        scores.append(score)  # keep track of the episode score
        avg_score = np.mean(scores[-100:])  # calculate average score over the last 100 episodes
        scores_avg.append(avg_score)  # keep track of the average score
        max_score = score if max_score < score else max_score  # keep track of max score so far

        # print periodic progress report
        if iterations % 100 == 0:
            print('\rIteration {} - avg score of {} over last 100 episodes'.format(iterations, avg_score))
            agent.save_checkpoint(name='checkpoint')

        # if the environment is solved, stop training
        if not solved and avg_score > config.SOLVED_SCORE:
            print('\rEnvironment solved in {} iterations with a score of {}'.format(iterations, avg_score))
            solved = True
            agent.save_checkpoint(name='solved')

    print('Training ended with an avg score of {} over last 100 episodes'.format(scores_avg[-1]))
    plot_scores(scores, scores_avg)

    return scores

def plot_scores(scores, scores_avg):
    """Creates plots of score track record."""

    # plot all scores
    plt.plot(np.arange(len(scores)), scores)
    plt.ylabel('Score')
    plt.xlabel('Episode #')
    plt.show()

    # plot average scores
    plt.plot(np.arange(len(scores_avg)), scores_avg)
    plt.ylabel('Avg Score over last 100 eps')
    plt.xlabel('Episode #')
    plt.show()

if __name__ == '__main__':
    """
    This shows an agent performing a single episode.
    """
    print('training a new agent to master {}'.format(config.ENV_APP))

    # Create the Unity environment
    banana_env = UnityEnvironment(file_name=config.ENV_APP)

    # Select the brain (= Unity ML agent) to work with and examine action space
    brain_name = banana_env.brain_names[0]
    brain = banana_env.brains[brain_name]
    action_size = brain.vector_action_space_size

    # Examine state space
    initial_env_info = banana_env.reset(train_mode=True)[brain_name]
    state_size = len(initial_env_info.vector_observations[0])

    # Create a new DQN agent
    agent_factory = AgentFactory()
    an_agent = agent_factory.create_agent('dqn_new', brain_name, state_size, action_size)
    an_agent.training = True  # True is default, but just in case
    print('Agent params: {}'.format(an_agent.get_params()))

    # Train the agent
    result = train(banana_env, an_agent)

    # Close the environment, no longer needed
    banana_env.close()

    print("Max score: {}".format(np.array(result).max()))


from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import os
import csv
import sys
import time
import cv2
import numpy as np
from PIL import Image
import pandas as pd
from datetime import datetime
from matplotlib import gridspec
from matplotlib import pyplot as plt

import tensorflow as tf
from collections import defaultdict

# This is needed since the notebook is stored in the object_detection folder.
TF_API="/home/ubuntu/eclipse-workspace/models/research/object_detection"
sys.path.append(os.path.split(TF_API)[0])
sys.path.append(TF_API)

from utils import np_box_ops
from utils import label_map_util
from utils import visualization_utils as vis_util
from core import box_list

label_map_filename = "pascal_label_map.pbtxt"
class ObjectDetectModel(object):
  """Class to load ObjectDetect model and run inference."""
  def __init__(self, frozen_graph):
    """Creates and loads pretrained  model."""
    if not frozen_graph.endswith('.pb'):
        raise ValueError('frozen_graph is not a correct pb file!')
    self.is_debug = True

    self.graph, \
    self.boxes_tensor,\
    self.scores_tensor, \
    self.classes_tensor ,\
    self.image_tensor = self.load_graph(frozen_graph)#boxes_tensor, scores_tensor, classes_tensor,num_detections_tensor, image_tensor

    self.sess = tf.Session(graph=self.graph)

    self.category_index = self.load_category(label_map_filename)
    self.image_height = 0
    self.image_weight = 0
    self.boxes = None
    self.scores = None
    self.classes = None
    self.qrcode_index = -1
    self.secret_cede = None
    self.plain_code = None

  def load_graph(self, frozen_graph):
    # We parse the graph_def file
    with tf.gfile.GFile(frozen_graph, "rb") as f:
        graph_def = tf.GraphDef()
        graph_def.ParseFromString(f.read())

    # We load the graph_def in the default graph
    with tf.Graph().as_default() as graph:
        boxes_tensor,scores_tensor, classes_tensor ,\
        image_tensor= \
            tf.import_graph_def(
                graph_def,
                input_map=None,
                return_elements=[
                  'detected_boxes:0',
                  'detected_scores:0',
                  'detected_classes:0',
                  'input:0'
                  ],
                name="",
                producer_op_list=None
            )
        with tf.variable_scope("coord_transform"):
            #change the coordinates of xcenter, ycenter, w, h to ymin, xmin, ymax, xmax for object detection api
            xcenter, ycenter, w, h = tf.unstack(tf.transpose(boxes_tensor))
            ymin = ycenter - h / 2.
            xmin = xcenter - w / 2.
            ymax = ycenter + h / 2.
            xmax = xcenter + w / 2.
            boxes_tensor = tf.transpose(tf.stack([ymin, xmin, ymax, xmax]))

        if(self.is_debug):
            writer = tf.summary.FileWriter("./logs_objectdetection_load", graph=graph)
            writer.close()

    return graph, \
        boxes_tensor,\
        scores_tensor, \
        classes_tensor , \
        image_tensor

  def read_tensor_from_image_file(self,
                                file_name,
                                input_height=None,
                                input_width=None,
                                input_mean=0,
                                input_std=255):
      if not tf.gfile.Exists(file_name):
          raise ValueError('file_name is not Exists!')
      input_name = "file_reader"
      output_name = "normalized"
      file_reader = tf.read_file(file_name, input_name)
      if file_name.endswith(".png"):
        image_reader = tf.image.decode_png(
            file_reader, channels=3, name="png_reader")
      elif file_name.endswith(".gif"):
        image_reader = tf.squeeze(
            tf.image.decode_gif(file_reader, name="gif_reader"))
      elif file_name.endswith(".bmp"):
        image_reader = tf.image.decode_bmp(file_reader, name="bmp_reader")
      else:
        image_reader = tf.image.decode_jpeg(
            file_reader, channels=3, name="jpeg_reader")
      if not input_height and not input_width:
          float_caster = tf.cast(image_reader, tf.float32)
          dims_expander = tf.expand_dims(float_caster, 0)
          resized = tf.image.resize_bilinear(dims_expander, [input_height, input_width])
          normalized = tf.divide(tf.subtract(resized, [input_mean]), [input_std])
      with tf.Session() as sess:
          result = sess.run(normalized)
      return result

  def save_image_to_image_file(self, image, file_name):
        convert_image = tf.image.convert_image_dtype(image, dtype=tf.uint8)
        cropped_image = tf.image.encode_jpeg(convert_image)
        with tf.Session() as sess:
            with tf.gfile.GFile(file_name, 'wb') as f:
                string = sess.run(cropped_image)
                f.write(string)

  def load_image_into_numpy_array(self, image):
      (im_width, im_height) = image.size
      return np.array(image.getdata()).reshape(
          (im_height, im_width, 3)).astype(np.uint8)

  def load_category(self, label_file):
        label_map = label_map_util.load_labelmap(label_file)
        categories = label_map_util.convert_label_map_to_categories(label_map, max_num_classes=20, use_display_name=True)
        category_index = label_map_util.create_category_index(categories)
        return category_index

  def bboxes_select(self,classes, scores, bboxes, threshold=0.1):
        """Sort bounding boxes by decreasing order and keep only the top_k
        """
        mask = scores > threshold
        classes = classes[mask]
        scores = scores[mask]
        bboxes = bboxes[mask]
        return classes, scores, bboxes

  def run(self, image_np):
    """Runs inference on a single image.
    Args:
      image:  raw input image.
    Returns:
    """

    self.image_height, self.image_weight = image_np.shape[0:2]
    print(self.image_height, self.image_weight)
    # Actual detection.
    start_time = time.time()
    (boxes, scores, classes) = self.sess.run(
            [self.boxes_tensor, self.scores_tensor, self.classes_tensor],
            feed_dict={self.image_tensor: image_np})
    duration = time.time() - start_time
    print ('%s: ObjectDetectModel.run(), duration = %.3f' %(datetime.now(), duration))

    self.boxes, self.scores, self.classes = self.bboxes_select(boxes, scores, classes,0.01)

    if(self.is_debug):
        print('boxes:',self.boxes)
        print('scores:',self.scores)
        print('classes:',self.classes)
        #print('center_coordinates:',self.get_center_coordinates(self.boxes))

    return self.boxes, self.scores, self.classes, self.category_index

  def slice_qrcode(self, image_np):
        if(self.qrcode_index > 0 and  self.boxes is not None):
            ymin, xmin, ymax, xmax = self.boxes[self.qrcode_index]
            QR_width = xmax - xmin
            QR_height = ymax - ymin
            crop_bounding_image = tf.image.crop_to_bounding_box(image_np,
                                                            int(ymin * self.image_height),
                                                            int(xmin * self.image_weight),
                                                            int(QR_height * self.image_height),
                                                            int(QR_width * self.image_weight) )
            crop_file_name = os.path.join("crop_result", 'qrcode.jpg')
            convert_image = tf.image.convert_image_dtype(crop_bounding_image, dtype=tf.uint8)
            cropped_image = tf.image.encode_jpeg(convert_image)
            with tf.Session() as sess:
                with tf.gfile.GFile(crop_file_name, 'wb') as f:
                    string = sess.run(cropped_image)
                    f.write(string)
                    return convert_image.eval()

  def get_center_coordinates(self, boxes):
        ymin, xmin, ymax, xmax = tf.unstack(tf.transpose(boxes))
        width = xmax - xmin
        height = ymax - ymin
        ycenter = ymin + height / 2.
        xcenter = xmin + width / 2.
        center_coordinates = tf.transpose(tf.stack([ycenter, xcenter, height, width], axis=0))
        with tf.Session() as sess:
            center_box = sess.run(center_coordinates)
        #ycenter, xcenter, height, width
        return center_box

def vis_bounding_box(image_np,boxes, scores, classes,category_index):
    vis_util.visualize_boxes_and_labels_on_image_array(
                image_np,
                boxes,
                classes.astype(np.int32),
                scores,
                category_index,
                use_normalized_coordinates=True,
                min_score_thresh=0.01,
                line_thickness=2)
    plt.figure(figsize=(6, 6))
    plt.imshow(image_np)
    plt.axis('off')
    plt.title('input image')
    plt.show()

def run_object_detection(ObjectDetectModel, path):
    """Inferences classify model and visualizes result."""
    print(path)
#     image = Image.open(path)
#     image_np = ObjectDetectModel.load_image_into_numpy_array(image)
    image = cv2.imread(path)
    image_np = cv2.cvtColor(image,cv2.COLOR_BGR2RGB)
    boxes, scores, classes ,category_index= ObjectDetectModel.run(image_np)

    vis_bounding_box(image_np, boxes, scores, classes, category_index)
    ObjectDetectModel.save_image_to_image_file(image_np,"detection.jpg")

def main():
    BASE_PATH = 'image'
    TEST_IMAGES = os.listdir(BASE_PATH)
    TEST_IMAGES.sort()
    print(TEST_IMAGES)

    MODEL = ObjectDetectModel("models/yolov1_frozen_graph.pb")
    print('model loaded successfully!')

    for image in TEST_IMAGES:
        image_path = os.path.join(BASE_PATH, image)
        run_object_detection(MODEL,image_path)

main()


import os
import logging
import argparse

import numpy as np
import tensorflow as tf
from tqdm import tqdm

from wordcnn import WordCNN

from utils.core import train, evaluate, predict
from utils.misc import load_data, build_metric
from utils.misc import ReverseEmbedding
from utils.misc import postfn

from attacks import fgm

os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'

logging.basicConfig(format='%(asctime)-15s %(message)s', level=logging.INFO)
logger = logging.getLogger(__name__)
info = logger.info

def parse_args():
    parser = argparse.ArgumentParser(description='Classify text with WordCNN')

    parser.add_argument('--batch_size', metavar='N', type=int, default=64)
    parser.add_argument('--data', metavar='FILE', type=str, required=True)
    parser.add_argument('--drop_rate', metavar='N', type=float, default=0.2)
    parser.add_argument('--embedding', metavar='FILE', type=str)
    parser.add_argument('--epochs', metavar='N', type=int)
    parser.add_argument('--filters', metavar='N', type=int, default=128)
    parser.add_argument('--indexer', metavar='IDX', type=str)
    parser.add_argument('--kernel_size', metavar='N', type=int, default=3)
    parser.add_argument('--n_classes', metavar='N', type=int, required=True)
    parser.add_argument('--name', metavar='MODEL', type=str)
    parser.add_argument('--outfile', metavar='FILE', type=str, required=True)
    parser.add_argument('--seqlen', metavar='N', type=int, default=300)
    parser.add_argument('--units', metavar='N', type=int, default=512)

    bip = parser.add_mutually_exclusive_group()
    bip.add_argument('--bipolar', dest='bipolar', action='store_true',
                     help='-1/1 for output.')
    bip.add_argument('--unipolar', dest='bipolar', action='store_false',
                     help='0/1 for output.')

    parser.add_argument('--adv_batch_size', metavar='N', type=int, default=64)
    parser.add_argument('--adv_epochs', metavar='N', type=int, default=5)
    parser.add_argument('--adv_eps', metavar='EPS', type=float)
    parser.add_argument('--w2v', metavar='w2v', type=str)

    sig = parser.add_mutually_exclusive_group()
    sig.add_argument('--fgsm', dest='sign', action='store_true', help='FGSM')
    sig.add_argument('--fgvm', dest='sign', action='store_false', help='FGVM')
    parser.set_defaults(sign=True)

    return parser.parse_args()

def config(args, embedding):
    class _Dummy():
        pass
    cfg = _Dummy()

    cfg.batch_size = args.batch_size
    cfg.bipolar = args.bipolar
    cfg.data = os.path.expanduser(args.data)
    cfg.drop_rate = args.drop_rate
    cfg.epochs = args.epochs
    cfg.filters = args.filters
    cfg.indexer = args.indexer
    cfg.kernel_size = args.kernel_size
    cfg.n_classes = args.n_classes
    cfg.name = args.name
    cfg.outfile = args.outfile
    cfg.seqlen = args.seqlen
    cfg.units = args.units

    if args.n_classes > 2:
        cfg.output = tf.nn.softmax
    elif 2 == args.n_classes:
        cfg.output = tf.tanh if args.bipolar else tf.sigmoid

    cfg.embedding = tf.placeholder(tf.float32, embedding.shape)
    cfg.vocab_size = embedding.shape[0]
    cfg.embedding_dim = embedding.shape[1]

    cfg.adv_batch_size = args.adv_batch_size
    cfg.adv_epochs = args.adv_epochs
    cfg.adv_eps = args.adv_eps
    cfg.sign = args.sign
    cfg.w2v = os.path.expanduser(args.w2v)

    return cfg

def build_graph(cfg):
    class _Dummy:
        pass

    env = _Dummy()

    env.x = tf.placeholder(tf.int32, [None, cfg.seqlen + 1], 'x')
    env.y = tf.placeholder(tf.int32, [None, 1], 'y')
    env.training = tf.placeholder_with_default(False, (), 'mode')

    m = WordCNN(cfg)
    env.ybar = m.predict(env.x, env.training)
    env.model = m

    # we do not save the embedding here since embedding is not trained.
    env.saver = tf.train.Saver(var_list=m.varlist)

    env = build_metric(env, cfg)

    with tf.variable_scope('adv'):
        env.adv_epochs = tf.placeholder(tf.int32, (), name='epochs')
        env.adv_eps = tf.placeholder(tf.float32, (), name='eps')
        env.xadv = fgm(m, env.x, epochs=env.adv_epochs, eps=env.adv_eps,
                       sign=cfg.sign, clip_min=-10, clip_max=10)
    return env

def make_adversarial(env, X_data):
    batch_size = env.cfg.adv_batch_size
    n_sample = X_data.shape[0]
    n_batch = int((n_sample + batch_size - 1) / batch_size)
    X_adv = np.empty_like(X_data)
    X_sents = []
    for batch in tqdm(range(n_batch), total=n_batch):
        end = min((batch + 1) * batch_size, n_sample)
        start = end - batch_size
        X_cur = X_data[start:end]
        feed_dict = {env.x: X_cur,
                     env.adv_epochs: env.cfg.adv_epochs,
                     env.adv_eps: env.cfg.adv_eps}
        xadv = env.sess.run(env.xadv, feed_dict=feed_dict)
        inds, sents = env.re.reverse_embedding(xadv, X_cur)
        X_adv[start:end] = inds
        X_sents += sents
    return (X_adv, X_sents)

def main(args):
    info('loading embedding vec')
    embedding = np.load(os.path.expanduser(args.embedding))

    info('constructing config')
    cfg = config(args, embedding)

    info('constructing graph')
    env = build_graph(cfg)
    env.cfg = cfg

    info('initializing session')
    sess = tf.Session()
    sess.run(tf.global_variables_initializer(),
             feed_dict={cfg.embedding: embedding})
    sess.run(tf.local_variables_initializer())
    env.sess = sess

    info('loading data')
    (_, _), (X_data, y_data) = load_data(cfg.data, cfg.bipolar, -1)

    info('loading model')
    train(env, load=True, name=cfg.name)
    info('evaluating against clean test samples')
    evaluate(env, X_data, y_data, batch_size=cfg.batch_size)

    env.re = ReverseEmbedding(w2v_file=cfg.w2v, index_file=cfg.indexer)

    info('making adversarial texts')
    X_adv, X_sents = make_adversarial(env, X_data)
    info('evaluating against adversarial texts')
    evaluate(env, X_adv, y_data, batch_size=cfg.batch_size)
    y_adv = predict(env, X_adv, batch_size=cfg.batch_size)
    env.sess.close()
    postfn(cfg, X_sents, y_data, y_adv)

if __name__ == '__main__':
    info('THE BEGIN')
    main(parse_args())
    info('THE END')