import pandas as pd
import numpy as np
from gluonts_forecasts.model_config_registry import ModelConfigRegistry
from gluonts_forecasts.gluon_dataset import remove_unused_external_features
from gluonts_forecasts.utils import (
    concat_timeseries_per_identifiers,
    concat_all_timeseries,
    add_row_origin,
    quantile_forecasts_series,
)
from dku_constants import (
    METRICS_DATASET,
    METRICS_COLUMNS_DESCRIPTIONS,
    TIMESERIES_KEYS,
    ROW_ORIGIN,
    CUSTOMISABLE_FREQUENCIES_OFFSETS,
)
from gluonts.model.forecast import QuantileForecast
from safe_logger import SafeLogger

logger = SafeLogger("Forecast plugin")

class TrainedModel:
    """
    Wrapper class to make forecasts using a GluonTS Predictor and a training GluonTS ListDataset, and to output a well formatted forecasts dataframe

    Attributes:
        predictor (gluonts.model.predictor.Predictor)
        gluon_dataset (gluonts.dataset.common.ListDataset): GluonTS ListDataset generated by the GluonDataset class (with extra fields to name timeseries)
        prediction_length (int): Number of time steps to predict (at most the prediction length used in training)
        quantiles (list): List of forecasts quantiles to compute in the forecasts_df
        include_history (bool): True to append to the forecasts dataframe the training data
        history_length_limit (int): Maximum number of values to retrieve from historical data per timeseries. Default to None which means all.
        time_column_name (str): Time column name used in training
        identifiers_columns (list): List of timeseries identifiers column names used in training.
        forecasts_df (DataFrame): Dataframe with the different quantiles forecasts and the training data if include_history is True
        model_name (str, optional)
    """

    def __init__(
        self,
        predictor,
        gluon_dataset,
        prediction_length,
        quantiles,
        include_history,
        history_length_limit=None,
        model_name=None,
    ):
        self.predictor = predictor
        self.gluon_dataset = gluon_dataset
        self.prediction_length = predictor.prediction_length if prediction_length == -1 else prediction_length
        self.quantiles = quantiles
        self.include_history = include_history
        self.time_column_name = None
        self.identifiers_columns = None
        self.forecasts_df = None
        self.frequency = gluon_dataset.process.trans[0].freq
        self.history_length_limit = history_length_limit
        self.model_name = model_name
        self._check()

    def predict(self):
        """
        Use the gluon dataset of training to predict future values and
        concat all forecasts timeseries of different identifiers and quantiles together
        """
        model_config = ModelConfigRegistry().get_model(self.model_name)
        if (
            self.model_name
            and not model_config.can_use_external_feature()
            and TIMESERIES_KEYS.FEAT_DYNAMIC_REAL in self.gluon_dataset.list_data[0]
        ):
            # remove external features from the ListDataset used for predictions if the model cannot use them
            gluon_dataset_without_external_features = remove_unused_external_features(
                self.gluon_dataset, self.frequency
            )
            forecasts = self.predictor.predict(gluon_dataset_without_external_features)
        else:
            forecasts = self.predictor.predict(self.gluon_dataset)

        forecasts_list = list(forecasts)

        forecasts_timeseries = self._compute_forecasts_timeseries(forecasts_list)

        multiple_df = concat_timeseries_per_identifiers(forecasts_timeseries)

        self.forecasts_df = concat_all_timeseries(multiple_df)

        self.time_column_name = self.gluon_dataset.list_data[0][TIMESERIES_KEYS.TIME_COLUMN_NAME]
        self.identifiers_columns = (
            list(self.gluon_dataset.list_data[0][TIMESERIES_KEYS.IDENTIFIERS].keys())
            if TIMESERIES_KEYS.IDENTIFIERS in self.gluon_dataset.list_data[0]
            else []
        )

        if self.include_history:
            self.forecasts_df = self._include_history(self.frequency, history_length_limit=self.history_length_limit)

        self.forecasts_df = add_row_origin(self.forecasts_df, both=ROW_ORIGIN.FORECAST, left_only=ROW_ORIGIN.HISTORY)

        self.forecasts_df = self.forecasts_df.rename(columns={"index": self.time_column_name})

    def _include_history(self, frequency, history_length_limit=None):
        """Include the historical data on which the model was trained to the forecasts dataframe.

        Args:
            frequency (str): Used to reconstruct the date range (because a gluon ListDataset only store the start date).
            history_length_limit (int): Maximum number of values to retrieve from historical data per timeseries. Default to None which means all.

        Returns:
            DataFrame containing both the historical data and the forecasted values.
        """
        history_timeseries = self._retrieve_history_timeseries(frequency, history_length_limit)
        multiple_df = concat_timeseries_per_identifiers(history_timeseries)
        history_df = concat_all_timeseries(multiple_df)
        return history_df.merge(self.forecasts_df, on=["index"] + self.identifiers_columns, how="left", indicator=True)

    def _generate_history_target_series(self, timeseries, frequency, history_length_limit=None):
        """Creates a pandas time series from the past target values with Nan values for the prediction_length future dates.

        Args:
            timeseries (dict): Univariate timeseries dictionary created with the GluonDataset class.
            frequency (str): Used in pandas.date_range.
            history_length_limit (int): Maximum number of values to retrieve from historical data per timeseries. Default to None which means all.

        Returns:
            Series with DatetimeIndex.
        """
        target_series = pd.Series(
            np.append(timeseries[TIMESERIES_KEYS.TARGET], np.repeat(np.nan, self.prediction_length)),
            name=timeseries[TIMESERIES_KEYS.TARGET_NAME],
            index=pd.date_range(
                start=timeseries[TIMESERIES_KEYS.START],
                periods=len(timeseries[TIMESERIES_KEYS.TARGET]) + self.prediction_length,
                freq=frequency,
            ),
        )
        if history_length_limit:
            target_series = target_series.iloc[-(history_length_limit + self.prediction_length) :]
        return target_series

    def _generate_history_external_features_dataframe(self, timeseries, frequency, history_length_limit=None):
        """Creates a pandas time series from the past and future external features values.

        Args:
            timeseries (dict): Univariate timeseries dictionary created with the GluonDataset class.
            frequency (str): Used in pandas.date_range.
            history_length_limit (int): Maximum number of values to retrieve from historical data per timeseries. Default to None which means all.

        Returns:
            DataFrame with DatetimeIndex.
        """
        external_features_df = pd.DataFrame(
            timeseries[TIMESERIES_KEYS.FEAT_DYNAMIC_REAL].T[
                : len(timeseries[TIMESERIES_KEYS.TARGET]) + self.prediction_length
            ],
            columns=timeseries[TIMESERIES_KEYS.FEAT_DYNAMIC_REAL_COLUMNS_NAMES],
            index=pd.date_range(
                start=timeseries[TIMESERIES_KEYS.START],
                periods=len(timeseries[TIMESERIES_KEYS.TARGET]) + self.prediction_length,
                freq=frequency,
            ),
        )
        if history_length_limit:
            external_features_df = external_features_df.iloc[-(history_length_limit + self.prediction_length) :]
        return external_features_df

    def _retrieve_history_timeseries(self, frequency, history_length_limit=None):
        """Reconstruct the history timeseries from the gluon_dataset object and fill the dates to predict with Nan values.

        Args:
            frequency (str)
            history_length_limit (int): Maximum number of values to retrieve from historical data per timeseries. Default to None which means all.

        Returns:
            Dictionary of list of timeseries by identifiers (None if no identifiers)
        """
        history_timeseries = {}
        for i, timeseries in enumerate(self.gluon_dataset.list_data):
            if TIMESERIES_KEYS.IDENTIFIERS in timeseries:
                timeseries_identifier_key = tuple(sorted(timeseries[TIMESERIES_KEYS.IDENTIFIERS].items()))
            else:
                timeseries_identifier_key = None

            target_series = self._generate_history_target_series(timeseries, frequency, history_length_limit)

            if TIMESERIES_KEYS.FEAT_DYNAMIC_REAL_COLUMNS_NAMES in timeseries:
                assert (
                    timeseries[TIMESERIES_KEYS.FEAT_DYNAMIC_REAL].shape[1]
                    >= len(timeseries[TIMESERIES_KEYS.TARGET]) + self.prediction_length
                )
                if timeseries_identifier_key not in history_timeseries:
                    external_features_df = self._generate_history_external_features_dataframe(
                        timeseries, frequency, history_length_limit
                    )
                    history_timeseries[timeseries_identifier_key] = [external_features_df]

            if timeseries_identifier_key in history_timeseries:
                history_timeseries[timeseries_identifier_key] += [target_series]
            else:
                history_timeseries[timeseries_identifier_key] = [target_series]
        return history_timeseries

    def _compute_forecasts_timeseries(self, forecasts_list):
        """Compute all forecasts timeseries for each quantile.

        Args:
            forecasts_list (list): List of gluonts.model.forecast.Forecast (objects storing the predicted distributions as samples).

        Returns:
            Dictionary of list of forecasts timeseries by identifiers (None if no identifiers)
        """
        forecasts_timeseries = {}
        for i, sample_forecasts in enumerate(forecasts_list):
            if TIMESERIES_KEYS.IDENTIFIERS in self.gluon_dataset.list_data[i]:
                timeseries_identifier_key = tuple(
                    sorted(self.gluon_dataset.list_data[i][TIMESERIES_KEYS.IDENTIFIERS].items())
                )
            else:
                timeseries_identifier_key = None

            if i == 0 and isinstance(sample_forecasts, QuantileForecast):
                self.quantiles = self._round_to_existing_quantiles(sample_forecasts)

            for quantile in self.quantiles:
                forecasts_label_prefix = "forecast"
                if quantile < 0.5:
                    forecasts_label_prefix += "_lower"
                elif quantile > 0.5:
                    forecasts_label_prefix += "_upper"

                forecasts_series = (
                    quantile_forecasts_series(sample_forecasts, quantile, self.frequency)
                    .rename(f"{forecasts_label_prefix}_{self.gluon_dataset.list_data[i][TIMESERIES_KEYS.TARGET_NAME]}")
                    .iloc[: self.prediction_length]
                )
                if timeseries_identifier_key in forecasts_timeseries:
                    forecasts_timeseries[timeseries_identifier_key] += [forecasts_series]
                else:
                    forecasts_timeseries[timeseries_identifier_key] = [forecasts_series]
        return forecasts_timeseries

    def _reorder_forecasts_df(self):
        """Reorder columns with timeseries identifiers columns right after time column"""
        forecasts_columns = [
            column for column in self.forecasts_df if column not in [self.time_column_name] + self.identifiers_columns
        ]
        self.forecasts_df = self.forecasts_df[[self.time_column_name] + self.identifiers_columns + forecasts_columns]

    def get_forecasts_df(self, session=None):
        """Add the session timestamp and model label to the forecasts dataframe. Sort timeseries in revert order to display predictions on top.

        Args:
            session (Timstamp, optional)

        Returns:
            Forecasts DaaFrame
        """
        if TIMESERIES_KEYS.IDENTIFIERS in self.gluon_dataset.list_data[0]:
            self._reorder_forecasts_df()
        if session:
            self.forecasts_df[METRICS_DATASET.SESSION] = session
        if self.model_name:
            self.forecasts_df[METRICS_DATASET.MODEL_COLUMN] = (
                ModelConfigRegistry().get_model(self.model_name).get_label()
            )

        self.forecasts_df = self.forecasts_df.sort_values(
            by=self.identifiers_columns + [self.time_column_name],
            ascending=[True] * len(self.identifiers_columns) + [False],
        )

        return self.forecasts_df

    def create_forecasts_column_description(self):
        """Explain the meaning of the forecasts columns"""
        column_descriptions = METRICS_COLUMNS_DESCRIPTIONS
        confidence_interval = self._retrieve_confidence_interval()
        for column in self.forecasts_df.columns:
            if "forecast_lower_" in column:
                column_descriptions[
                    column
                ] = f"Lower bound of the {confidence_interval}% forecasts confidence interval."
            elif "forecast_upper_" in column:
                column_descriptions[
                    column
                ] = f"Upper bound of the {confidence_interval}% forecasts confidence interval."
            elif "forecast_" in column:
                column_descriptions[column] = "Median of probabilistic forecasts"
        return column_descriptions

    def _check(self):
        """Raises ValueError if the selected prediction_length is higher than the one used in training"""
        if self.predictor.prediction_length < self.prediction_length:
            raise ValueError(
                f"Please choose a forecasting horizon lower or equal to the one chosen when training: {self.predictor.prediction_length}"
            )

    def _round_to_existing_quantiles(self, sample_forecasts):
        """Find the quantiles that exists in sample_forecasts that are closest to the selected quantiles.
        QuantileForecast cannot predict all quantiles but only a list predifined during training.

        Args:
            sample_forecasts (QuantileForecast)

        Returns:
            List of quantiles that exists in the sample_forecasts
        """
        new_quantiles = []
        possible_quantiles = list(map(float, sample_forecasts.forecast_keys))
        for quantile in self.quantiles:
            new_quantiles += [min(possible_quantiles, key=lambda x: abs(x - quantile))]
        return new_quantiles

    def _retrieve_confidence_interval(self):
        """Retrieve the confidence interval percentage from the minimum and maximum quantiles.
        If they are not symetric around 0.5, log a warning.

        Returns:
            Integer representing the percentage of the confidence interval.
        """
        lower_quantile, upper_quantile = min(self.quantiles), max(self.quantiles)
        confidence_interval = round((upper_quantile - lower_quantile) * 100)
        if round((1 - upper_quantile) * 100, 2) != round(lower_quantile * 100, 2):
            logger.warning(
                f"The output confidence interval is not centered around the median. Lower and upper quantiles are [{lower_quantile}, {upper_quantile}]"
            )
        return confidence_interval


from app import db

from ..table.expense import ExpenseTable
from ..table.expense_tag import ExpenseTagTable

from ext.core.exception import LogicException

class ExpenseModel(ExpenseTable):

  @staticmethod
  def remove_by_id(id):
    '''
      - It deletes a user by his id.
    '''
    ExpenseTable.query.filter(ExpenseTable.id==id).delete()

  @staticmethod
  def load_by_id(user_id):
    '''
      - It loads a user by his id.
    '''
    return ExpenseTable.query.filter(ExpenseTable.id==user_id).first()

  @staticmethod
  def create(budget_id, user_id, amount, tag_list=[], description=""):
    '''
      - An expense is created and attached to the budget.
    '''
    expense = ExpenseTable(budget_id, user_id, amount, description)
    db.session.add(expense)
    db.session.commit()
    for tag in tag_list:
      if tag.budget_id != budget_id:
        raise LogicException('You should not attach a tag from another budget.')
      expense_tag = ExpenseTagTable(expense.id, tag.id)
      db.session.add(expense_tag)
    db.session.commit()
    return expense

  def load_tags(self):
    if not hasattr(self, loaded_tags):
      loaded_tags = []


import random
import json

from locust import HttpLocust, TaskSet, task

NAME = "mapresty"
TOTAL = 3000000
LIMIT = 2000

DATABASE = "sdb"
LAYER_ID = "country_point"

jsonEncoder = json.JSONEncoder()
jsonDecoder = json.JSONDecoder()

def check_response(response):
    if response.content is None:
        response.failure("empty content")
    elif response.content.rfind('"success":false') > 0:
        r = jsonDecoder.decode(response.content)
        response.failure(r.get("error") or "success: false")
    else:
        response.success()

class Query(TaskSet):

    @task
    def query_by_condition(self):
        samples = random.sample(xrange(1, TOTAL), LIMIT)
        where = "gid in (" + ",".join(str(v) for v in samples) + ")"
        data = {
            "page": 0,
            "count": LIMIT,
            "condition": where
        }
        with self.client.post(
                "/rest/sdb/databases/%(db)s/layers/%(layerid)s/data?op=query" %
                {"db": DATABASE, "layerid": LAYER_ID},
                data,
                catch_response=True,
                name="(%s) query by condition" % NAME) as response:
            check_response(response)

    @task
    def query_by_spatial(self):
        spatial_filter = {
            "relation": 0,
            "geometry": {
                "type": "Polygon",
                "coordinates": [[
                    [110.588, 32.575],
                    [112.492, 32.118],
                    [113.862, 31.166],
                    [113.234, 29.929],
                    [111.445, 30.290],
                    [110.170, 28.235]
                ]]
            }
        }
        data = {
            "page": 0,
            "count": LIMIT,
            "resultCRS": "WGS84",
            "spatialFilter": jsonEncoder.encode(spatial_filter)
        }
        with self.client.post(
                "/rest/sdb/databases/%(db)s/layers/%(layerid)s/data?op=query" %
                {"db": DATABASE, "layerid": LAYER_ID},
                data,
                catch_response=True,
                name="(%s) query by spatial" % NAME) as response:
            check_response(response)

class QueryUser(HttpLocust):
    task_set = Query
    host = "http://maptalks-server:11215"


from olc_webportalv2.geneseekr import views
from django.conf.urls import url, include

urlpatterns = [
    # GeneSeekr Stuff
    url(r'^geneseekr_home/', views.geneseekr_home, name='geneseekr_home'),
    url(r'^geneseekr_query/', views.geneseekr_query, name='geneseekr_query'),
    url(r'^geneseekr_processing/(?P<geneseekr_request_pk>\d+)/$', views.geneseekr_processing, name='geneseekr_processing'),
    url(r'^geneseekr_results/(?P<geneseekr_request_pk>\d+)/$', views.geneseekr_results, name='geneseekr_results'),

    # Tree stuff
    url(r'^tree_home/', views.tree_home, name='tree_home'),
    url(r'^tree_request/', views.tree_request, name='tree_request'),
    url(r'^tree_result/(?P<parsnp_request_pk>\d+)/$', views.tree_result, name='tree_result'),
]


import os,csv,sys, operator
from django.conf import settings
from django import template

class CSVFile:

	def __init__(self, file_name, data, header=False):
		self.filename = file_name
		self.data = data
		self.type = [[0]*3]*len(data[0])
		self.validation_check()

	def validation_check(self):
		for j in range(len(self.data[0])):
			column = self.data[:][j]
			for i in range(len(column)):
				data_type = classify(column[i])
				self.type[j][data_type] += 1

def csvparse():
	files = []
	for filename in os.listdir(settings.BASE_DIR+'/static/datastash'):
		csvfile = open(settings.BASE_DIR+'/static/datastash/'+filename, 'rU')
		reader = csv.reader(csvfile)
		data = []
		for row in reader:
			data.append(row)
		file_obj = CSVFile(filename, data)
		files.append(file_obj)
	return files

register = template.Library()

def classify(s):
	try:
		int(s)
		return 0
	except:
		try:
			float(s)
			return 1
		except:
			return 2

@register.filter
def get_type(value):
    return type(value)


from math import floor
import string

def encode(num, b=62):
    """
    Base62 encoding
    """
    if b <= 0 or b > 62:
        return 0
    base = string.digits + string.ascii_lowercase + string.ascii_uppercase
    r = num % b
    encoded_string = base[r]
    q = floor(num / b)
    while q:
        r = q % b
        q = floor(q / b)
        encoded_string = base[int(r)] + encoded_string
    return encoded_string

def decode(num, b=62):
    """
    Base62 decoding
    """
    base = string.digits + string.ascii_lowercase + string.ascii_uppercase
    limit = len(num)
    decoded_number = 0
    for i in range(limit):
        decoded_number = b * decoded_number + base.find(num[i])
    return decoded_number


#! /usr/bin/env python

# Copyright 2018-2022 Mailgun Technologies Inc
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

from gubernator import ratelimit_pb2 as pb
import gubernator
import argparse

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='Gubernator CLI')

    parser.add_argument('--endpoint', '-e', action="store", dest="endpoint", default='127.0.0.1:9090')
    parser.add_argument('--timeout', '-t', action="store", dest="timeout", default=None)

    parser.add_argument('--namespace', '-n', action="store", dest="namespace", default="cli_ns")
    parser.add_argument('--key', '-k', action="store", dest="unique_key", default="cli_key")
    parser.add_argument('--hits', '-H', action="store", dest="hits", type=int, default=1)
    parser.add_argument('--duration', '-d', action="store", dest="duration", type=int, default=10000)
    parser.add_argument('--limit', '-l', action="store", dest="limit", type=int, default=5)

    opts = parser.parse_args()

    req = pb.Requests()
    rate_limit = req.requests.add()

    rate_limit.algorithm = pb.TOKEN_BUCKET
    rate_limit.duration = opts.duration
    rate_limit.limit = opts.limit
    rate_limit.namespace = opts.namespace
    rate_limit.unique_key = opts.unique_key
    rate_limit.hits = opts.hits

    client = gubernator.V1Client(endpoint=opts.endpoint)
    resp = client.GetRateLimits(req, timeout=opts.timeout)
    print(resp)


import numpy as np
import pandas as pd
import re
from scipy import stats

from . import utils
from .chart import Dashboard
from .models import arima

class CoinSeer:
    """
    The core Coin Seer class that provides a simple interface for managing a
    predictive model of a cryptocurrency time series.

    Parameters
    ----------
    ts : pandas.Series
        Datetime-indexed cryptocurrency time series
    currency_pair : str
        The currency pair for the time series, e.g., 'btc_usd', 'eth-xrp';
        must contain at least one separator character
    freq : pandas.tseries.offsets or None, optional, default: None
        The frequency of the time series; if None, inferred automatically
    preprocess : bool, optional, default: True
        Whether to preprocess the time series
    logret : int, optional, default: 1
        The k-step log return; if 0, do not calculate log returns

    Attributes
    ----------
    ts : pandas.Series
        Datetime-indexed cryptocurrency time series
    self.bc, self.qc : str
        Base and quote (counter) currencies
    self.logret : int
        The k-step log return; if 0, not modelling the log returns
    self.model : coin-seer model
        A coin-seer model, e.g., arima.Rolling
    self.statistics : dict
        Descriptive statistics for the time series or its log returns
    """
    def __init__(self, ts, currency_pair, freq=None,
                 preprocess=True, logret=1):
        self.ts = ts
        currency_pair = currency_pair.upper()
        self.bc, self.qc = re.split(r'[ ,-./:;_|]+', currency_pair)
        self.logret = logret
        self.model = None

        if preprocess:
            if isinstance(self.ts.index.dtype, np.object):
                self.ts.index = pd.to_datetime(self.ts.index)
            if freq is None:
                if self.ts.index.freq is None:
                    freq = pd.infer_freq(self.ts.index)
                else:
                    freq = self.ts.index.freq
            if logret > 0:
                _ts = np.where(self.ts == 0, np.nan, self.ts)
                self.ts = pd.Series(_ts, index=self.ts.index)
            self.ts = utils.preprocess(self.ts, freq=freq)

        if logret > 0:
            self.ts = utils.log_returns(self.ts, logret)

        self.statistics = {
            'Length': len(self.ts),
            'Number of null data': self.ts.isnull().sum(),
            'Minimum': self.ts.min(),
            'Maximum': self.ts.max(),
            'Mean': self.ts.mean(),
            'Median': self.ts.median(),
            'Interquartile range': stats.iqr(self.ts.values),
            'Standard deviation': self.ts.std(),
            'Skewness': stats.skew(self.ts.values),
            'Kurtosis': stats.kurtosis(self.ts.values)
        }

    def describe(self):
        """Retrieve a collection of descriptive statistics."""
        return self.statistics

    def dashboard(self, save=False, save_to=''):
        """
        Generate a dashboard containing the following elements:
        - a plot of the base time series or its k-step log returns;
        - a box plot, showing distribution characteristics;
        - autocorrelation function (ACF), partial ACF, and quantile-quantile
          plots; and
        - a power spectral density plot computed using Welch's method for
          identifying seasonality.

        Parameters
        ----------
        save : bool, optional, default: False
            Whether to export the dashboard in scalable vector graphics format
        save_to : str, optional, default: ''
            The directory to which to export; used only if `save` is True
        """
        db = Dashboard(self)
        db.make(save, save_to)

    def select(self, model, **hyperparameters):
        """
        Specify the model.

        Parameters
        ----------
        model : str {'arima', 'rolling'}
        hyperparameters : dict, optional
        """
        hyperparameters.update({
            'bc': self.bc,
            'qc': self.qc,
            'logret': self.logret
        })
        models = {'arima': arima.ARIMA, 'rolling': arima.Rolling}
        self.model = models[model](self.ts, **hyperparameters)

    def run(self, **run_args):
        """
        Prepare forecasts according to the given model and hyperparameters.

        Parameters
        ----------
        run_args : dict, optional
            Arguments to be passed to the model's `run` method
        """
        self.model.run(**run_args)

    def log(self):
        """Retrieve the forecast log."""
        if len(self.model.log) == 0:
            print('No log available. '
                  'Refit the model(s) with logging enabled.')
            return None
        return self.model.log

    def evaluate(self):
        """Compute and retrieve evaluation metrics."""
        return self.model.evaluate()

    def forecasts(self):
        """Retrieve the forecast(s)."""
        return self.model.fc

    def display_results(self, save=False, save_to=''):
        """
        Display the forecast results graphically.

        Parameters
        ----------
        save : bool, optional, default: False
            Whether to export the dashboard in scalable vector graphics format
        save_to : str, optional, default: ''
            The directory to which to export; used only if `save` is True
        """
        self.model.display_results(save, save_to)


"""
CTD evaluation.

Note: the CTD training set has some oddities

E.g. scopolamine induces drug overdose

Biocreativ results here:

https://biocreative.bioinformatics.udel.edu/media/store/files/2015/BC5CDR_overview.final.pdf

A total of 18 teams successfully submitted CID results in 46 runs. As
shown in Table 3 (only the best run of each team is included),
the Fscore ranges from 32.01% to 57.03% (team 288) with an average of
43.37%. All teams outperformed the baseline results by the simple abstract-level
co-occurrence method (16.43% in precision, 76.45% in recall and 27.05% in F-score).

"""
import gzip
import logging
from collections import defaultdict
from dataclasses import dataclass
from pathlib import Path
from random import shuffle
from typing import Any, Dict, Iterable, List, Set, Tuple

import yaml
from bioc import biocxml
from oaklib import BasicOntologyInterface, get_implementation_from_shorthand
from pydantic.v1 import BaseModel

from ontogpt.engines.knowledge_engine import chunk_text
from ontogpt.engines.spires_engine import SPIRESEngine
from ontogpt.evaluation.evaluation_engine import SimilarityScore, SPIRESEvaluationEngine
from ontogpt.templates.core import Publication, Triple
from ontogpt.templates.ctd import (
    ChemicalToDiseaseDocument,
    ChemicalToDiseaseRelationship,
    TextWithTriples,
)

THIS_DIR = Path(__file__).parent
DATABASE_DIR = Path(__file__).parent / "database"
TEST_SET_BIOC = DATABASE_DIR / "CDR_TestSet.BioC.xml.gz"
TRAIN_SET_BIOC = DATABASE_DIR / "CDR_TrainSet.BioC.xml.gz"

RMAP = {"CID": "induces"}

logger = logging.getLogger(__name__)

def negated(Triple) -> bool:
    return Triple.qualifier and Triple.qualifier.lower() == "not"

class PredictionRE(BaseModel):
    """A prediction for a relationship extraction task."""

    test_object: TextWithTriples = None
    """source of truth to evaluate against"""

    true_positives: List[Tuple] = None
    num_true_positives: int = None
    false_positives: List[Tuple] = None
    num_false_positives: int = None
    false_negatives: List[Tuple] = None
    num_false_negatives: int = None
    scores: Dict[str, SimilarityScore] = None
    predicted_object: TextWithTriples = None
    named_entities: List[Any] = None

    def calculate_scores(self, labelers: List[BasicOntologyInterface] = None):
        self.scores = {}

        def label(x):
            if labelers:
                for labeler in labelers:
                    lbl = labeler.label(x)
                    if lbl:
                        return f"{x} {lbl}"
            return x

        def all_objects(dm: TextWithTriples):
            return list(
                set(link.subject for link in dm.triples if not negated(link))
                | set(link.object for link in dm.triples if not negated(link))
            )

        def pairs(dm: TextWithTriples) -> Set:
            return set(
                (label(link.subject), label(link.object))
                for link in dm.triples
                if not negated(link)
            )

        self.scores["similarity"] = SimilarityScore.from_set(
            all_objects(self.test_object),
            all_objects(self.predicted_object),
            labelers=labelers,
        )
        pred_pairs = pairs(self.predicted_object)
        test_pairs = pairs(self.test_object)
        self.true_positives = list(pred_pairs.intersection(test_pairs))
        self.false_positives = list(pred_pairs.difference(test_pairs))
        self.false_negatives = list(test_pairs.difference(pred_pairs))
        self.num_false_negatives = len(self.false_negatives)
        self.num_false_positives = len(self.false_positives)
        self.num_true_positives = len(self.true_positives)

class EvaluationObjectSetRE(BaseModel):
    """A result of predicting relationextractions."""

    precision: float = None
    recall: float = None
    f1: float = None

    training: List[TextWithTriples] = None
    predictions: List[PredictionRE] = None
    test: List[TextWithTriples] = None

@dataclass
class EvalCTD(SPIRESEvaluationEngine):
    # ontology: OboGraphInterface = None
    subject_prefix = "MESH"
    object_prefix = "MESH"

    def __post_init__(self):
        self.extractor = SPIRESEngine("ctd.ChemicalToDiseaseDocument")
        # synonyms are derived entirely from training set
        self.extractor.load_dictionary(DATABASE_DIR / "synonyms.yaml")

    def load_test_cases(self) -> Iterable[ChemicalToDiseaseDocument]:
        return self.load_cases(TEST_SET_BIOC)

    def load_training_cases(self) -> Iterable[ChemicalToDiseaseDocument]:
        return self.load_cases(TRAIN_SET_BIOC)

    def load_cases(self, path: Path) -> Iterable[ChemicalToDiseaseDocument]:
        logger.info(f"Loading {path}")
        with gzip.open(str(path), "rb") as f:
            collection = biocxml.load(f)
            triples_by_text = defaultdict(list)
            for document in collection.documents:
                doc = {}
                for p in document.passages:
                    doc[p.infons["type"]] = p.text
                title = doc["title"]
                abstract = doc["abstract"]
                # text = f"Title: {title} Abstract: {abstract}"
                for r in document.relations:
                    i = r.infons
                    t = Triple(
                        subject=f"{self.subject_prefix}:{i['Chemical']}",
                        predicate=RMAP[i["relation"]],
                        object=f"{self.object_prefix}:{i['Disease']}",
                    )
                    triples_by_text[(title, abstract)].append(t)
        for (title, abstract), triples in triples_by_text.items():
            pub = Publication(title=title, abstract=abstract)
            logger.debug(f"Triples: {len(triples)} for Title: {title} Abstract: {abstract}")
            yield ChemicalToDiseaseDocument(publication=pub, triples=triples)

    def create_training_set(self, num=100):
        ke = self.extractor
        docs = list(self.load_test_cases())
        shuffle(docs)
        for doc in docs[0:num]:
            text = doc.text
            prompt = ke.get_completion_prompt(None, text)
            completion = ke.serialize_object(m)
            yield dict(prompt=prompt, completion=completion)

    def eval(self) -> EvaluationObjectSetRE:
        """Evaluate the ability to extract relations."""
        labeler = get_implementation_from_shorthand("sqlite:obo:mesh")
        num_test = self.num_tests
        ke = self.extractor
        docs = list(self.load_test_cases())
        shuffle(docs)
        eos = EvaluationObjectSetRE(
            test=docs[:num_test],
            training=[],
            predictions=[],
        )
        n = 1
        for doc in eos.test:
            logger.info(f"Iteration {n} of {num_test}")
            n += 1
            logger.info(doc)
            text = f"Title: {doc.publication.title} Abstract: {doc.publication.abstract}"
            predicted_obj = None
            named_entities = []
            for chunked_text in chunk_text(text):
                extraction = ke.extract_from_text(chunked_text)
                logger.info(
                    f"{len(extraction.extracted_object.triples)}\
                        triples from window: {chunked_text}"
                )
                if not predicted_obj:
                    predicted_obj = extraction.extracted_object
                else:
                    predicted_obj.triples.extend(extraction.extracted_object.triples)
                    logger.info(f"{len(predicted_obj.triples)} total triples, after concatenation")
                    logger.debug(f"concatenated triples: {predicted_obj.triples}")
                named_entities.extend(extraction.named_entities)

            # title_extraction = ke.extract_from_text(doc.publication.title)
            # logger.info(f"{len(title_extraction.extracted_object.triples)}\
            # triples from: Title {doc.publication.title}")
            # abstract_extraction = ke.extract_from_text(doc.publication.abstract)
            # logger.info(f"{len(abstract_extraction.extracted_object.triples)}\
            # triples from: Abstract {doc.publication.abstract}")
            # ke.merge_resultsets([results, results2])
            # predicted_obj = title_extraction.extracted_object
            # predicted_obj.triples.extend(abstract_extraction.extracted_object.triples)
            # logger.info(f"{len(predicted_obj.triples)} total triples, after concatenation")
            # logger.debug(f"concatenated triples: {predicted_obj.triples}")

            def included(t: ChemicalToDiseaseRelationship):
                return (
                    t
                    and t.subject
                    and t.object
                    and t.subject.startswith("MESH:")
                    and t.object.startswith("MESH:")
                    and t.predicate.lower() == "induces"
                )

            predicted_obj.triples = [t for t in predicted_obj.triples if included(t)]
            logger.info(
                f"{len(predicted_obj.triples)} filtered triples (CID only, between MESH only)"
            )
            pred = PredictionRE(predicted_object=predicted_obj, test_object=doc)
            pred.named_entities = named_entities
            logger.info("PRED")
            logger.info(yaml.dump(pred.dict()))
            logger.info("Calc scores")
            pred.calculate_scores(labelers=[labeler])
            logger.info(yaml.dump(pred.dict()))
            eos.predictions.append(pred)
        self.calc_stats(eos)
        return eos

    def calc_stats(self, eos: EvaluationObjectSetRE):
        num_true_positives = sum(p.num_true_positives for p in eos.predictions)
        num_false_positives = sum(p.num_false_positives for p in eos.predictions)
        num_false_negatives = sum(p.num_false_negatives for p in eos.predictions)
        if num_true_positives + num_false_positives == 0:
            logger.warning("No true positives or false positives")
            return
        eos.precision = num_true_positives / (num_true_positives + num_false_positives)
        eos.recall = num_true_positives / (num_true_positives + num_false_negatives)
        if eos.precision + eos.recall == 0:
            logger.warning("No precision or recall")
            return
        eos.f1 = 2 * (eos.precision * eos.recall) / (eos.precision + eos.recall)


import os
from . import bpyhelper
from . import read_owmat
from . import owm_types
import bpy

def cleanUnusedMaterials(materials):
    if materials is None:
        return
    m = {}
    for name in materials[1]:
        mat = materials[1][name]
        if mat.users == 0:
            print('[import_owmat]: removed material: {}'.format(mat.name))
            bpy.data.materials.remove(mat)
        else:
            m[name] = mat
    bpyhelper.scene_update()
    t = {}
    for name in materials[0]:
        tex = materials[0][name]
        if tex.users == 0:
            bpy.data.textures.remove(tex)
        else:
            t[name] = tex
    bpyhelper.scene_update()
    return (t, m)

def mutate_texture_path(file, new_ext):
    return os.path.splitext(file)[0] + new_ext

def load_textures(texture, root, t):
    ''' Loads an overwatch texture.

    Priority (high to low): TIFF, TGA, DDS (doesn't work properly)
    '''
    realpath = bpyhelper.normpath(texture)
    if not os.path.isabs(realpath):
        realpath = bpyhelper.normpath('%s/%s' % (root, realpath))

    tga_file = mutate_texture_path(realpath, '.tga')
    if os.path.exists(tga_file):
        realpath = tga_file

    tif_file = mutate_texture_path(realpath, '.tif')
    if os.path.exists(tif_file):
        realpath = tif_file

    fn = os.path.splitext(os.path.basename(realpath))[0]

    try:
        tex = None
        if fn in t:
            tex = t[fn]
        else:
            img = None
            for eimg in bpy.data.images:
                if eimg.name == fn or eimg.filepath == realpath:
                    img = eimg
            if img is None:
                img = bpy.data.images.load(realpath, check_existing=True)
                img.name = fn
            tex = None
            for etex in bpy.data.textures:
                if etex.name == fn:
                    tex = etex
            if tex == None:
                tex = bpy.data.textures.new(fn, type='IMAGE')
                tex.image = img
            t[fn] = tex
        return tex
    except Exception as e:
        print('[import_owmat]: error loading texture: {}'.format(bpyhelper.format_exc(e)))
    return None

def read(filename, prefix = ''):
    root, file = os.path.split(filename)
    data = read_owmat.read(filename)
    if not data:
        return None

    t = {}
    m = {}

    for i in range(len(data.materials)):
        m[data.materials[i].key] = process_material(data.materials[i], prefix, root, t)

    return (t, m)

def process_material(material, prefix, root, t):
    if bpy.context.scene.render.engine == 'CYCLES':
        return process_material_Cycles(material, prefix, root, t)
    else:
        return process_material_BI(material, prefix, root, t)

def process_material_Cycles(material, prefix, root, t):
    mat = bpy.data.materials.new('%s%016X' % (prefix, material.key))

    # print('Processing material: ' + mat.name)
    mat.use_nodes = True

    tile = 300
    nodes = mat.node_tree.nodes
    links = mat.node_tree.links

    # Remove default nodes
    for node in [node for node in nodes if node.type != 'OUTPUT_MATERIAL']:
        nodes.remove(node)

    # Get material output node
    material_output = None
    try:
        material_output = [node for node in nodes if node.type == 'OUTPUT_MATERIAL'][0]
    except:
        material_output = nodes.new('ShaderNodeOutputMaterial')
    material_output.location = (tile, 0)

    # Create Overwatch NodeGroup Instance
    nodeOverwatch = nodes.new('ShaderNodeGroup')
    if material.shader != 0:
        print('[import_owmat]: {} uses shader {}'.format(mat.name, material.shader))
        nodeOverwatch.label = 'OWM Shader %d' % (material.shader)

    if str(material.shader) in owm_types.TextureTypes['NodeGroups'] and owm_types.TextureTypes['NodeGroups'][str(material.shader)] in bpy.data.node_groups:
        nodeOverwatch.node_tree = bpy.data.node_groups[owm_types.TextureTypes['NodeGroups'][str(material.shader)]]
    else:
        # print('[import_owmat]: could not find node group for shader %s, using default' % (material.shader))
        if owm_types.TextureTypes['NodeGroups']['Default'] in bpy.data.node_groups:
            nodeOverwatch.node_tree = bpy.data.node_groups[owm_types.TextureTypes['NodeGroups']['Default']]
        # else:
        #     print('[import_owmat]: could not find fallback shader %s' % (owm_types.TextureTypes['NodeGroups']['Default']))
    nodeOverwatch.location = (0, 0)
    nodeOverwatch.width = 250
    if nodeOverwatch.node_tree is not None:
        links.new(nodeOverwatch.outputs[0], material_output.inputs[0])

    tt = owm_types.TextureTypesById
    tm = owm_types.TextureTypes
    scratchSocket = {}
    for i, texData in enumerate(material.textures):
        nodeTex = nodes.new('ShaderNodeTexImage')
        nodeTex.location = (-tile, -tile*(i))
        nodeTex.width = 250
        nodeTex.color_space = 'NONE'

        tex = load_textures(texData[0], root, t)
        if tex is None:
            print('[import_owmat]: failed to load texture: {}'.format(texData[0]))
            continue
        nodeTex.image = tex.image

        if len(texData) == 2:
            continue

        if nodeOverwatch.node_tree is None:
            continue

        typ = texData[2]
        nodeTex['owm.material.typeid'] = str(typ)
        nodeTex.label = str(typ)
        if typ in tt:
            bfTyp = tm['Mapping'][tt[typ]]
            print('[import_owmat]: {} is {}'.format(os.path.basename(texData[0]), tt[typ]))
            nodeTex.label = str(tt[typ])
            nodeTex.name = str(tt[typ])
            for colorSocketPoint in bfTyp[0]:
                nodeSocketName = colorSocketPoint
                if colorSocketPoint in tm['Alias']:
                    nodeSocketName = tm['Alias'][colorSocketPoint]
                if colorSocketPoint not in scratchSocket:
                    if nodeSocketName in nodeOverwatch.inputs:
                        links.new(nodeTex.outputs['Color'], nodeOverwatch.inputs[nodeSocketName])
                        scratchSocket[colorSocketPoint] = nodeTex.outputs['Color']
                    else:
                        print('[import_owmat] could not find node %s on shader group' % (nodeSocketName))
            for alphaSocketPoint in bfTyp[1]:
                nodeSocketName = alphaSocketPoint
                if alphaSocketPoint in tm['Alias']:
                    nodeSocketName = tm['Alias'][alphaSocketPoint]
                if alphaSocketPoint not in scratchSocket:
                    if nodeSocketName in nodeOverwatch.inputs:
                        links.new(nodeTex.outputs['Alpha'], nodeOverwatch.inputs[nodeSocketName])
                        scratchSocket[alphaSocketPoint] = nodeTex.outputs['Alpha']
                    else:
                        print('[import_owmat] could not find node %s on shader group' % (nodeSocketName))

    if nodeOverwatch.node_tree is None:
        return mat

    for envPoint, basePoint in tm['Env'].items():
        if envPoint in scratchSocket or basePoint not in scratchSocket: continue
        nodeSocketName = envPoint
        if envPoint in tm['Alias']:
            nodeSocketName = tm['Alias'][envPoint]
        if nodeSocketName in nodeOverwatch.inputs:
            links.new(scratchSocket[basePoint], nodeOverwatch.inputs[nodeSocketName])
            scratchSocket[envPoint] = scratchSocket[basePoint]

    for activeNodePoint in tm['Active']:
        if activeNodePoint in scratchSocket:
            nodes.active = scratchSocket[activeNodePoint].node
            break

    for colorNodePoint in tm['Color']:
        if colorNodePoint in scratchSocket:
            scratchSocket[colorNodePoint].node.color_space = 'COLOR'

    return mat

def process_material_BI(material, prefix, root, t):
    mat = bpy.data.materials.new('%s%016X' % (prefix, material.key))
    mat.diffuse_intensity = 1.0

    mat.texture_slots.add() # for some reason the first texture duplicates itself

    tt = owm_types.TextureTypesById

    ti = 1

    for texturetype in material.textures:
        typ = texturetype[2]
        texture = texturetype[0]

        tex = load_textures(texture, root, t)

        if tex is None:
            print('[import_owmat]: failed to load texture: {}'.format(texturetype[0]))
            continue

        ti += 1

        mattex = mat.texture_slots.add()

        mattex.use_map_color_diffuse = True
        mattex.texture = tex
        mattex.texture_coords = 'UV'

        if typ in tt:
            if not tex.name.endswith(')'): tex.name = '%s (%s)' % (tt[typ], tex.name)
            if tt[typ].startswith('Normal'):
                tex.use_alpha = False
                tex.use_normal_map = True
                mattex.use_map_color_diffuse = False
                mattex.use_map_normal = True
                mattex.normal_factor = 1
            elif tt[typ].startswith('Diffuse'):
                mattex.diffuse_factor = 1
            else:
                mattex.use = False
        else:
            if not tex.name.endswith(')'): tex.name = '%s (%s)' % (str(typ), tex.name)
            mattex.use = False
    return mat


###################################
#  application for ecYeast
###################################
from cobra.io import load_matlab_model, read_sbml_model
import os
import sys
import matplotlib.pyplot as plt # For python 3.6: sudo apt-get install python3.6-tk   TO INSTALL Tkinter
import pandas as pd
from cobra.flux_analysis import pfba
from cobra.flux_analysis import (
    single_gene_deletion, single_reaction_deletion, double_gene_deletion,
    double_reaction_deletion)

from cobra.manipulation import remove_genes
from cobra.manipulation import *
from cobra.flux_analysis.moma import moma

sys.path.append(r"/Users/luho/PycharmProjects/model/cobrapy/code")
sys.path.append(r"/Users/luho/PycharmProjects/model/strain_design/code")
os.chdir('/Users/luho/PycharmProjects/model/strain_design/code')

# import self function
from mainFunction import *
from in_silico_strain_design_scripts import *

# load the ecYeast model
ecYeast = load_matlab_model("../data/ec3HP.mat")

"""knock-out"""
# pFBA method is used
# run the gene deletion with pFBA method, minimization of proteins pool
# in this simulation, 3HP production is as the objective function
# qs is unconstrait
def getModelWithRemoveGene (model0, gene_remove0):
    model1 = model0.copy()
    remove_genes(model1, gene_remove0, remove_reactions=True) # this script can't be used
    return model1

def solveEcModel(model, obj_id, target_id, glucose_uptake ='r_1714_REV'):
    model.objective = obj_id  # we put it in the mutant model
    solution = model.optimize()  # we put it in the mutant model
    # mutModel.summary() # we put it in the mutant model
    solution_value0 = solution.objective_value  # we put it in the mutant model
    model.reactions.get_by_id(obj_id).bounds = (0.999 * solution_value0, solution_value0)  # we put it in the mutant model
    model.objective = {model.reactions.prot_pool_exchange: -1}
    solution2 = model.optimize()
    yield_p = solution2.fluxes[target_id]/solution2.fluxes[glucose_uptake]
    return  yield_p

# pipeline

# prepare the geneID
geneID = []
for x in ecYeast.genes:
    print(x.id)
    geneID.append(x.id)

# prepare ecModel for calculation
model2 = ecYeast.copy()
model2 = ecYeastMinimalMedia(model2)
model2.reactions.get_by_id("r_1714_REV").bounds = (0,1000)  # D-glucose exchange (reversible)

# using pfba
yield_p_ref0 =[]
yield_p_mutant0 =[]
for i, x in enumerate(geneID):
    print(i)
    gene_remove = []
    gene_remove.append(x)
    mutModel = getModelWithRemoveGene(model0=model2, gene_remove0=gene_remove)

    try:
        yield_p_ref = solveEcModel(model=model2, obj_id = 'newRxn3', target_id = 'newRxn3')
        yield_p_mutant = solveEcModel(model=mutModel, obj_id='newRxn3', target_id='newRxn3')
        print(yield_p_ref)
        print(yield_p_mutant)
        yield_p_ref0.append(yield_p_ref)
        yield_p_mutant0.append(yield_p_mutant)
    except:
        yield_p_ref = None
        yield_p_mutant = None
        yield_p_ref0.append(yield_p_ref)
        yield_p_mutant0.append(yield_p_mutant)
pfba_result = pd.DataFrame({'gene':geneID, 'yield_p_ref0': yield_p_ref0, 'yield_p_mutant0': yield_p_mutant0 })
saveExcel(pfba_result, "../result/pfba_result.xlsx")


import json

from django.http import HttpResponse, JsonResponse
from ResModel.models import HubUser

def changeHead(request):
    if request.method == "POST":
        userEmail = request.POST.get("userId")
        userHead =  request.POST.get("url")
        if userEmail is not None and userHead is not None:
            user = HubUser.objects.filter(UserEmail=userEmail).update(UserImage=userHead)
            return JsonResponse({
                "status": 1,
                "message": "更换头像成功",
            }, safe=False)
        else:
            return JsonResponse({
                "status": 2,
                "message": "请求参数错误"
            })
    else:
        return JsonResponse({
          "status": 3,
          "message": "请求方法错误"
        })


from cltk.stem.sanskrit.code import configuration
from cltk.stem.sanskrit.code.apply import *
from cltk.stem.sanskrit.code.iast_dev import *
from cltk.stem.sanskrit.code.dev_iast import *
from git import Repo
import os

config = configuration.config
class SandhiSplitter():
    def __init__(self, text, isIAST=False):
        self.text = text
        self.isiast = isIAST
        if self.isiast == False:
            self.text = dviast(self.text)

    def getSandhi(self):
        if os.path.exists("../data/input/additional-data-0-128.json") == False:
            print("Trained model not found, Downloading....")
            Repo.clone_from("https://github.com/sainimohit23/SanskritModel", "../data")
        preds = split_sandhi(self.text, config)
        textSplitted = self.text.split()
        predsSplitted = preds.split()
        d = {}
        for i in range(len(predsSplitted)):
            li = []
            for word in predsSplitted[i].split('-'):
                if len(word)>0:
                    li.append(iastdv(word))
            d[iastdv(textSplitted[i])] = li

        return d


from PyQt4.QtCore import QObject, pyqtSignal
from PyQt4.QtGui import QMainWindow, QFileDialog
from DCGUI.Windows.ui_DemandGraphEditor import Ui_DemandGraphEditor
from DCGUI.DemandGraphCanvas import DemandGraphCanvas, State

class DemandGraphEditor(QMainWindow):
    xmlfile = None
    demand_changed = pyqtSignal()

    def __init__(self):
        QMainWindow.__init__(self)
        self.ui = Ui_DemandGraphEditor()
        self.ui.setupUi(self)
        self.canvas = DemandGraphCanvas(self.ui.graphArea)
        self.ui.graphArea.setWidget(self.canvas)
        self.basename = self.windowTitle()

    def setData(self, data):
        self.demand = data
        self.setWindowTitle(self.demand.id + " - " + self.basename)
        self.ui.startTime.setText(str(self.demand.startTime))
        self.ui.endTime.setText(str(self.demand.endTime))
        self.canvas.Clear()
        self.canvas.Visualize(self.demand)

    def toggleSelect(self):
        self.ui.actionSelect.setChecked(True)
        self.ui.actionVM.setChecked(False)
        self.ui.actionDemandStorage.setChecked(False)
        self.ui.actionEdge.setChecked(False)
        self.canvas.state = State.Select

    def toggleVM(self):
        self.ui.actionSelect.setChecked(False)
        self.ui.actionVM.setChecked(True)
        self.ui.actionDemandStorage.setChecked(False)
        self.ui.actionEdge.setChecked(False)
        self.canvas.state = State.VM

    def toggleDemandStorage(self):
        self.ui.actionSelect.setChecked(False)
        self.ui.actionVM.setChecked(False)
        self.ui.actionDemandStorage.setChecked(True)
        self.ui.actionEdge.setChecked(False)
        self.canvas.state = State.DemandStorage

    def toggleEdge(self):
        self.ui.actionSelect.setChecked(False)
        self.ui.actionVM.setChecked(False)
        self.ui.actionDemandStorage.setChecked(False)
        self.ui.actionEdge.setChecked(True)
        self.canvas.state = State.Edge

    def resizeEvent(self, e):
        super(QMainWindow, self).resizeEvent(e)
        self.canvas.ResizeCanvas()

    def showEvent(self, e):
        super(QMainWindow, self).showEvent(e)
        self.canvas.ResizeCanvas()

    def LoadPositions(self, lst):
        pass

    def SavePositions(self):
        pass

    def New(self):
        self.demand.vertices = []
        self.demand.edges = []
        self.demand.startTime = 0
        self.demand.endTime = 0
        self.ui.startTime.setText("0")
        self.ui.endTime.setText("0")
        self.canvas.Clear()
        self.canvas.Visualize(self.demand)
        self.canvas.changed = True
        self.xmlfile = None

    def Open(self):
        name = QFileDialog.getOpenFileName(filter="*.xml")
        if name == None or name == '':
            return
        self.demand.LoadFromXml(name)
        self.ui.startTime.setText(str(self.demand.startTime))
        self.ui.endTime.setText(str(self.demand.endTime))
        self.setWindowTitle(self.demand.id + " - " + self.basename)
        self.canvas.Clear()
        self.canvas.Visualize(self.demand)
        self.canvas.changed = True
        self.xmlfile = name

    def Save(self):
        self.changeTime()
        self.canvas.updatePos()
        if self.xmlfile == None:
            self.SaveAs()
        else:
            output = open(self.xmlfile, 'w')
            output.write(self.demand.ExportToXml())
            output.close()

    def SaveAs(self):
        self.changeTime()
        self.canvas.updatePos()
        self.xmlfile = QFileDialog.getSaveFileName(directory=".xml", filter="*.xml")
        if self.xmlfile != '':
            output = open(self.xmlfile, 'w')
            output.write(self.demand.ExportToXml())
            output.close()

    def closeEvent(self, e):
        self.canvas.updatePos()
        self.changeTime()
        self.demand_changed.emit()

    def changeTime(self):
        self.demand.startTime = int(self.ui.startTime.text())
        self.demand.endTime = int(self.ui.endTime.text())


from marvelrooms import *

# this runs the game
class Engine(object):

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

	def play(self):
		current_scene = self.scene_map.opening_scene()
		last_scene = self.scene_map.next_scene('climax')

		while current_scene != last_scene:
			next_scene_name = current_scene.enter()
			current_scene = self.scene_map.next_scene(next_scene_name)

		current_scene.enter()

class Map(object):

	scenes = {
		'shield_hq': SHIELDHQ(),
		'sanctum_sanctorum': SanctumSanctorum(),
		'stark_tower': StarkTower(),
		'birnin_zana': BirninZana(),
		'baxter_building': BaxterBuilding(),
		'attilan': Attilan(),
		'x_mansion': XMansion(),
		'death': Death(),
		'climax': Climax()
	}

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

	def next_scene(self, scene_name):
		val = Map.scenes.get(scene_name)
		return val

	def opening_scene(self):
		return self.next_scene(self.start_scene)

a_map = Map('shield_hq')
a_game = Engine(a_map)
a_game.play()


""""
===================================================
梯度下降作业(代码)：
目标函数：
y = x**2 + b * x + c
需求：求解最小值对应的x和y(这里的最小值指的是函数y在所有数据上的一个累计最小值)
要求：写代码
数据：
b: 服从均值为-1，方差为10的服从高斯分布随机数
c：服从均值为0，方差为1的服从高斯分布随机数
假定b、c这样的数据组合总共1、2、10、100、10w、100w条数据,求解在现在的数据情况下，目标函数的取最小值的时候，x和y分别对应多少？
===================================================
"""""

import numpy as np
import matplotlib as mlt
import matplotlib.pyplot as plt

# 解决画图中文问题
plt.rcParams['font.sans-serif'] = ['SimHei']    # 步骤一（替换sans-serif字体）
plt.rcParams['axes.unicode_minus'] = False      # 步骤二（解决坐标轴负数的负号显示问题）

np.random.seed(18)

n = 8
# 产生均值为loc，标准差为scale的随机数列组成的数组，这个数组的形式为size
# size = (x, y): x行, y列
# size = n: n条数据
b_values = np.random.normal(loc=-1.0, scale=10, size=n)
print(b_values)


from __future__ import division

# N, J = 16, 50
N, J = 32, 500

def gen_bin(k=0):
    n = N - 2
    while True:
        b = bin(k)[2:]
        if len(b) > n:
            yield None
        m = '0' * (n - len(b)) + b
        s = '1' + m + '1'
        k += 1
        yield s

bins = gen_bin()

def is_prime(n):
    if n == 2 or n == 3:
        return True
    if n < 2 or n % 2 == 0:
        return False
    if n < 9:
        return True
    if n % 3 == 0:
        return False
    r = int(n**0.5)
    f = 5
    while f <= r:
        if n % f == 0:
            return False
        if n % (f + 2) == 0:
            return False
        f += 6
    return True

test = ['0011', 5, 13, 147, 31, 43, 1121, 73, 77, 629]
case_list = []

def first_factor(n):
    for i in range(2, int(n**0.5) + 1):
        if n % i == 0:
            return i
    return -1

def get_factors(bases):
    for k in bases:
        if is_prime(k):
            return None
    factors = [first_factor(n) for n in bases]
    if -1 in factors:
        return None
    return factors

def make_cases():
    b = bins.next()
    while b is not None and len(case_list) < J:
        bases = [int(b, k) for k in range(2, 11)]
        f = get_factors(bases)
        if f is not None:
            case_list.append([b] + f)
            # print case_list[-1]
        b = bins.next()

def write(fname, case_list):
    with open(fname, 'wb') as fid:
        fid.write('Case #1:\n')
        for case in case_list:
            r = ' '.join(str(x) for x in case[1:])
            s = '{} {}\n'.format(case[0], r)
            # s = s.format(case[0])
            fid.write(s)

def main():
    make_cases()
    outfile = 'C-large_small.txt'
    write(outfile, case_list)

if __name__ == '__main__':
    main()


##############################################################################
#   Copyright (c) 2018 Eynes/E-MIPS (www.eynes.com.ar)
#   License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
##############################################################################

from lxml import etree
from datetime import datetime
import time
import email
import urllib.error as Urllib
from xml.sax import SAXParseException
import logging
import pytz

# Configuracion del logger
logger = logging.getLogger('afipws')
logger.setLevel(logging.DEBUG)
try:
    from suds.client import Client
except (ImportError, IOError) as e:
    logger.debug("Cannot import Client from Suds-py3:\n%s" % e)
try:
    from M2Crypto import BIO, SMIME
except (ImportError, IOError) as e:
    logger.debug("Cannot import BIO & SMIME from M2Crypto: \n%s" % e)

class WSAA:
    def __init__(self, cert, private_key, wsaaurl, service, tz):
        """Init."""
        self.token = None
        self.sign = None
        self.wsaaurl = wsaaurl
        self.service = service
        self.expiration_time = None
        self.ta = None
        self.connected = True
        self.timezone = tz

        try:
            self._create_client()
        except Urllib.URLError as e:
            logger.error("No hay conexion disponible")
            self.connected = False
            raise Exception('No se puede conectar con AFIP: %s' % str(e))
        except SAXParseException as e:
            raise Exception('WSAA URL malformada: %s' % e.getMessage())
        except Exception as e:
            raise Exception('Unknown Error: %s' % e)

    def _create_client(self):
        # Creamos el cliente contra la URL
        self.client = Client(self.wsaaurl)

    def _create_tra(self):
        """Funcion para crear el TRA."""
        # Creamos el root
        logger.debug("Creando TRA")
        root = etree.Element('loginTicketRequest')
        doc = etree.ElementTree(root)
        root.set('version', '1.0')

        # Creamos los childs de loginTicketRequest
        header = etree.SubElement(root, 'header')

        # UniqueId
        uniqueid = etree.SubElement(header, 'uniqueId')
        timestamp = int(time.mktime(datetime.now().timetuple()))
        uniqueid.text = str(timestamp)

        # generationTime
        tsgen = datetime.fromtimestamp(timestamp-2400)
        tsgen = pytz.utc.localize(tsgen).astimezone(self.timezone)
        gentime = etree.SubElement(header, 'generationTime')
        gentime.text = tsgen.isoformat()

        # expirationTime
        tsexp = datetime.fromtimestamp(timestamp+14400)
        tsexp = pytz.utc.localize(tsexp).astimezone(self.timezone)
        exptime = etree.SubElement(header, 'expirationTime')
        exptime.text = tsexp.isoformat()

        # service
        serv = etree.SubElement(root, 'service')
        serv.text = self.service

        # try:
        #     f = open('tra.xml', 'w')
        #     doc.write(f, xml_declaration=True, encoding='UTF-8',
        #               pretty_print=True)
        # except Exception, e:
        #     print 'No se puede grabar el archivo: %s' % e
        #     return None

        logger.debug("TRA Creado")
        return etree.tostring(doc)

    def _sign_tra(self, tra, cert, key):
        """Funcion que firma el tra."""

        # Creamos un buffer a partir del TRA
        buf = BIO.MemoryBuffer(tra)
        key_bio = BIO.MemoryBuffer(key.encode('ascii'))
        cert_bio = BIO.MemoryBuffer(cert.encode('ascii'))

        # Firmamos el TRA
        s = SMIME.SMIME()
        s.load_key_bio(key_bio, cert_bio)
        p7 = s.sign(buf, 0)
        out = BIO.MemoryBuffer()
        s.write(out, p7)

        # Extraemos la parte que nos interesa
        msg = email.message_from_string(out.read().decode('utf-8'))
        for part in msg.walk():
            filename = part.get_filename()
            if filename == "smime.p7m":
                logger.debug("TRA Firmado")
                return part.get_payload(decode=False)

    def _call_wsaa(self, cms):
        """ Funcion para llamar al WSAA y loguearse """

        # Si no esta conectado, probamos conectar nuevamente
        if not self.connected:
            try:
                self._create_client()
            except Urllib.URLError as e:
                logger.warning("No hay conexion disponible")
                self.connected = False
                raise Exception('No hay conexion: %s' % e)

        # Llamamos a loginCms y obtenemos el resultado
        logger.debug("Llamando a loginCms:\n%s", cms)
        try:
            result = self.client.service.loginCms(cms)
        except Exception as e:
            logger.exception("Excepcion al llamar a loginCms")
            raise Exception('Exception al autenticar: %s' % str(e))

        self.ta = result
        return result

    def parse_ta(self, ta=None):
        if not ta:
            ta = self.ta
            if not ta:
                return

        # Quitamos la declaracion de XML
        tas = ta.split('\n')
        if tas[0].find("?xml"):
            ta = '\n'.join(tas[1:])

        # Parseamos el resultado
        root = etree.XML(ta)

        # Buscamos el expirationTime
        header = root.find('header')
        exptime = header.find('expirationTime')
        exptime_iso = exptime.text[0:exptime.text.rfind('-')]
        self.expiration_time = datetime.strptime(exptime_iso,
                                                 '%Y-%m-%dT%H:%M:%S.%f')

        # Si no expiro, obtenemos el token y el sign
        cred = root.find('credentials')
        self.token = cred.find('token').text
        self.sign = cred.find('sign').text

        return True

    # TODO: Agregar una flag de force para tomarlo igual
    # TODO: Hacer chequeo de errores
    def get_token_and_sign(self, cert, key, force=True):
        # Primero chequeamos si ya tenemos un token
        if not force:
            if self.ta and self.expiration_time and self.token and self.sign:
                # Si todavia no expiro el que tenemos, lo retornamos
                if datetime.now() < self.expiration_time:
                    return self.token, self.sign

        tra = self._create_tra()
        cms = self._sign_tra(tra, cert, key)
        try:
            self._call_wsaa(cms)
        except Exception as e:
            raise e

        self.parse_ta(self.ta)
        return True

# El certificado X.509 obtenido de Seg. Inf.
# CERT = "/home/skennedy/proyectos/afipws/certs2012/eynes/cert_eynes.crt"
CERT = ""
# La clave privada del certificado CERT
# PRIVATEKEY = "/home/skennedy/proyectos/afipws/certs2012/eynes/ \
#     privada_eynes.key"
PRIVATEKEY = ""
# homologacion (pruebas)
# WSAAURL = "https://wsaahomo.afip.gov.ar/ws/services/LoginCms?wsdl"
WSAAURL = ""
# WSAAURL="https://wsaa.afip.gov.ar/ws/services/LoginCms?wsdl"

if __name__ == '__main__':
    wsaa = WSAA(CERT, PRIVATEKEY, WSAAURL, "wsfe")
    token = None
    sign = None
    expiration_time = None
    try:
        # Se puede llamar a get_token_and_sign o pasarle un TA
        # anterior a wsaa.parse_ta
        wsaa.get_token_and_sign()
        token = wsaa.token
        expiration_time = wsaa.expiration_time
        sign = wsaa.sign
    except Exception as e:
        print(e)

    # Vemos si ya expiro
    if datetime.now() > expiration_time:
        print("Certificado expirado")

    print('Token: ', token)
    print('Sign: ', sign)
    print('Expiration Time: ', expiration_time.strftime("%d/%m/%Y %H:%M:%S"))


import csv
import pandas as pd

file1 = "dwarf_stars.csv"
file2 = "unit_converted_stars.csv"
d1=[]
d2=[]

with open(file1, 'r', encoding='utf8') as f:
    csv_reader=csv.reader(f)
    for i in csv_reader:
        d1.appned(i)

with open (file2,'r', encoding='utf8') as f:
    csv_reader=csv.reader(f)
    for i in csv_reader:
        d2.append(i)

h1= d1[0]
h2= d2=[0]

data_d1= d1[1:]
data_d2= d2[1:]

h=h1+h2

data=[]
for i in data_d1:
    data.append(i)

for j in data_d2:
    data.append(j)

with open("total_stars.csv",'w',encoding='utf8') as f:
    csv_writer=csv.writer(f)
    csv_writer.writerow(h)
    csv_writer.writerows(data)


import sys
import random
import time

def output(msg, *args, **kwargs):
    msg = msg.format(*args, **kwargs)
    sys.stdout.write(msg)
    sys.stdout.flush()

def test_proc(name):
    output("Starting job {0} ...", name)

    steps = 5
    delay = 1
    # steps = random.randint(1, 10)
    # delay = random.random() * 5.0

    output("{0} : {1} steps, {2}s delay", name, steps, delay)
    for i in range(1, steps + 1):
        output("{0} {1} / {2}", name, i, steps)
        time.sleep(delay)

    output("Finishing job {0} ...", name)

if __name__ == "__main__":
    test_proc(sys.argv[1])


# uncompyle6 version 3.7.4
# Python bytecode 2.7 (62211)
# Decompiled from: Python 3.6.9 (default, Apr 18 2020, 01:56:04)
# [GCC 8.4.0]
# Embedded file name: build/bdist.linux-i686/egg/cspace/hgsite/genshi.py
# Compiled at: 2013-06-09 10:57:05
"""Genshi rendering
Copyright (C) 2012 Remy Blank
"""
from __future__ import absolute_import
import os.path, weakref
try:
    from genshi import QName, Stream
    from genshi.core import Attrs, END, START, TEXT
    from genshi.template import Context, MarkupTemplate, NewTextTemplate, TemplateLoader
    from genshi.template.eval import Suite
    has_genshi = True
except ImportError:
    TemplateLoader = object
    has_genshi = False

try:
    from pygments.lexers import get_lexer_by_name
    from pygments.formatters.html import HtmlFormatter, _get_ttype_class
    from pygments.styles import get_style_by_name
    has_pygments = True
except ImportError:
    has_pygments = False

from .site import cache_must_revalidate, renderer
from .util import guess_mimetype, hex_node

class Loader(TemplateLoader):
    """A template loader propagating the revision to included templates"""

    def load(self, filename, relative_to=None, cls=None, encoding=None):
        if relative_to is not None and '@' not in filename:
            parts = relative_to.rsplit('@', 1)
            if len(parts) == 2:
                filename += '@' + parts[1]
        return super(Loader, self).load(filename, relative_to, cls, encoding)

_loaders = weakref.WeakKeyDictionary()

def get_template_loader(repo):
    """Return a template loader for the given repository."""
    try:
        return _loaders[repo]
    except KeyError:
        pass

    def load_template(filename):
        path, rev = filename.rsplit('@', 1)
        rev = bytes(rev) if rev else None
        fctx = repo[rev][path]

        def uptodate():
            return rev is not None

        return (filename, filename, fctx.data(), uptodate)

    loader = _loaders[repo] = Loader(load_template, auto_reload=True, max_cache_size=100, default_encoding='utf-8', variable_lookup='strict')
    return loader

def execute(path, context):
    """Execute a script in the given context."""
    with open(path, 'r') as (f):
        source = f.read()
    Suite(source, path).execute(context)

def make_context(req, path, **kwargs):
    """Create a rendering context."""
    context = Context(req=req, **kwargs)
    context_module = req.web.config('hgsite', 'context.genshi', '')
    if context_module:
        execute(os.path.join(req.repo.path, context_module), context)
    return context

translate_nop = ('').join(chr(i) for i in range(256))
invalid_control_chars = ('').join(chr(i) for i in range(32) if i not in (9, 10, 13))

@renderer('genshi:html', 'genshi:xhtml', 'genshi:xml', register=has_genshi)
def render_markup_template(req, path, name, config, **kwargs):
    """Render a Genshi markup template."""
    method = name.split(':', 1)[(-1)]
    mimetype = guess_mimetype(config.get('mimetype'), path, 'text/xml')
    encoding = config.get('encoding', 'utf-8')
    loader = get_template_loader(req.repo)
    template = loader.load('%s@%s' % (path, hex_node(req.ctx)), cls=MarkupTemplate)
    context = make_context(req, path, highlight=highlight, **kwargs)
    stream = template.generate(context)
    text = stream.render(method, encoding=encoding)
    text = text.translate(translate_nop, invalid_control_chars)
    return req.send(text, mimetype=mimetype, encoding=encoding, headers=cache_must_revalidate)

@renderer('genshi:text', register=has_genshi)
def render_text_template(req, path, name, config, **kwargs):
    """Render a Genshi text template."""
    method = name.split(':', 1)[(-1)]
    mimetype = guess_mimetype(config.get('mimetype'), path, 'text/plain')
    encoding = config.get('encoding', 'utf-8')
    loader = get_template_loader(req.repo)
    template = loader.load('%s@%s' % (path, hex_node(req.ctx)), cls=NewTextTemplate)
    stream = template.generate(make_context(req, path, **kwargs))
    text = stream.render(method, encoding=encoding)
    return req.send(text, mimetype=mimetype, encoding=encoding, headers=cache_must_revalidate)

@renderer('pygments:css', register=has_pygments, file_must_exist=False)
def render_pygments_css(req, path, name, config, **kwargs):
    """Render a (virtual) CSS file with Pygments styles."""
    style_cls = get_style_by_name(config.get('style', 'trac'))
    container = config.get('container', '')
    formatter = HtmlFormatter(style=style_cls, nobackground=True)
    content = formatter.get_style_defs(c.strip() for c in container.split(','))
    return req.send(content, mimetype='text/css', encoding='utf-8', headers=cache_must_revalidate)

def _group_by_class(tokens):
    """Group Pygments lexer tokens with the same CSS class."""
    cls = None
    text = []
    for ttype, value in tokens:
        c = _get_ttype_class(ttype)
        if c == cls:
            text.append(value)
            continue
        if value:
            yield (
             cls, ('').join(text))
            text = [value]
            cls = c

    if text:
        yield (
         cls, ('').join(text))
    return

def generate_highlight_markup(tokens):
    """Generate a Genshi stream for Pygments markup."""
    pos = (None, -1, -1)
    span = QName('span')
    class_ = QName('class')
    for cls, text_chunk in _group_by_class(tokens):
        if cls:
            yield (
             START, (span, Attrs([(class_, cls)])), pos)
            yield (TEXT, text_chunk, pos)
            yield (END, span, pos)
        else:
            yield (
             TEXT, text_chunk, pos)

    return

def generate_text(text):
    """Generate a Genshi stream with a single text node."""
    yield (TEXT, text, (None, -1, -1))
    return

def highlight(text, lexer, tabsize=0):
    """Syntax-highlight the given text with the given lexer, and return a
    Genshi stream of the result."""
    if has_pygments:
        try:
            lexer = get_lexer_by_name(lexer, stripnl=False, ensurenl=False, tabsize=tabsize)
            tokens = lexer.get_tokens(text)
            return Stream(generate_highlight_markup(tokens))
        except Exception:
            pass

    return Stream(generate_text(text))


#! /usr/bin/env python3

def pairs_difference2(in_array, k):
    if (len(in_array) <= 1):
        return 0

    if (type(k) is not int):
        print('k must be integer')
        return 0
    else:
        lookup = dict()
        for i in in_array:
            lookup[i] = i

        num_pairs = 0
        for j in in_array:
            if (lookup.get(j+k) is not None):
                num_pairs += 1

        return num_pairs

def pairs_difference(in_array, k):
    if (len(in_array) <= 1):
        return 0

    if (type(k) is not int):
        print('k must be integer')
        return 0
    else:
        num_pairs = 0
        s_array = sorted(in_array) #sorts it in place
        anchor = 0
        runner = 1
        while (anchor < len(s_array)-1 and
               runner < len(s_array)) :
            diff = s_array[runner] - s_array[anchor]
            if (diff < k):
                runner += 1
            else:
                if (diff == k):
                    num_pairs += 1
                anchor += 1
                runner = anchor + 1

        return num_pairs

def main():
    s = [1, 7, 5, 9, 2, 12, 3]
    k = 2
    print(s,k)
    print(pairs_difference2(s, k))

    s = [1, 7, 5]
    k = 4
    print(s,k)
    print(pairs_difference2(s, k))

    s = [2]
    k = 3
    print(s,k)
    print(pairs_difference2(s, k))

if __name__ == '__main__':
    main()


#!/usr/bin/env python2
""" Created on Wed Aug 29 16:05:01 2018 @author: jklhj """

import argparse
import cv2
import os
import shutil

parser = argparse.ArgumentParser(
        description='For Caffe ssd image detection (use python2), '
                    'and return the coordinates of the bounding boxes.')

parser.add_argument('--root_caffe_ssd',
                    default='',
                    help='Caffe ssd directory (python2).')

parser.add_argument('--set_gpu',
                    help='set to use GPU.',
                    default=False,
                    action='store_true')

parser.add_argument('--gpu_index',
                    help='the index of GPU.',
                    default=None)

parser.add_argument('--deploy_model',
                    default='',
                    help='the prototxt file of deployment.')

parser.add_argument('--pretrain_model',
                    default='',
                    help='the pretrain model (*.caffemodel) of deployment.')

parser.add_argument('--conf_threshold',
                    default=0.5,
                    help='the confidence threshold in ssd detection, default=0.5 .')

parser.add_argument('--image_file',
                    default='',
                    help='the image file to detect.')

parser.add_argument('--show_img',
                    help='set to show the image with bounding boxes.',
                    default=False,
                    action='store_true')

args = parser.parse_args()

if args.set_gpu and not args.gpu_index: print('Error: Need to set the index of GPU: '
                                                  '--gpu_index')

if not args.root_caffe_ssd: print('Error: Need to set the caffe ssd root: '
                                  '--root_caffe_ssd')
if not args.deploy_model: print('Error: Need to set deploy prototxt file: '
                                '--deploy_model')
if not args.pretrain_model: print('Error: Need to set pretrained model: '
                                  '--pretrain_model')
if not args.image_file: print('Error: Need to set image file to detect: '
                              '--image_file')

img = cv2.imread(args.image_file)
height, width, channels = img.shape

import sys
sys.path.insert(0, args.root_caffe_ssd + '/python/')

import caffe
from caffe.proto import caffe_pb2
from google.protobuf import text_format

if args.set_gpu:
    caffe.set_device(int(args.gpu_index))
    caffe.set_mode_gpu()

def get_modify_output_layer_param(conf_threshold, deploy_model):
    net = caffe_pb2.NetParameter()

    with open(deploy_model, 'r') as f:
        text_format.Merge(f.read(), net)

    layerName = [ l.name for l in net.layer ]
    idx = layerName.index('detection_out')

    output_layer = net.layer[idx]

    # modify output parameter
    output_layer.detection_output_param.confidence_threshold = float(conf_threshold)

    # get output parameter
    LabelMapFile = output_layer.detection_output_param.save_output_param.label_map_file

    shutil.copyfile(deploy_model, deploy_model + '_orig')
    os.remove(deploy_model)

    with open(deploy_model, 'w') as f:
        f.write(str(net))

    return LabelMapFile, conf_threshold

def caffe_ssd_img_detection(deploy_model,
                            pretrain_model,
                            image_file):

    net = caffe.Net(deploy_model,
                    pretrain_model,
                    caffe.TEST)

    transformer = caffe.io.Transformer({'data': net.blobs['data'].data.shape})
    transformer.set_transpose('data', (2, 0, 1))
#    transformer.set_mean('data', np.array([104,117,123])) # mean pixel

    ## the reference model operates on images in [0,255] range instead of [0,1]
    transformer.set_raw_scale('data', 255)
    ## the reference model has channels in BGR order instead of RGB
    transformer.set_channel_swap('data', (2,1,0))

    image = caffe.io.load_image(image_file)

    transformed_image = transformer.preprocess('data', image)

    net.blobs['data'].data[0,...] = transformed_image

    detections = net.forward()['detection_out']

    det_label = detections[0,0,:,1]
    det_conf  = detections[0,0,:,2]
    det_xmin  = detections[0,0,:,3]
    det_ymin  = detections[0,0,:,4]
    det_xmax  = detections[0,0,:,5]
    det_ymax  = detections[0,0,:,6]

    return det_label, det_conf, det_xmin, det_ymin, det_xmax, det_ymax

def show_image(img, xmin, xmax, ymin, ymax, label_names):
    for i in range(len(xmin)):
        cv2.rectangle( img, (xmin[i], ymin[i]), (xmax[i], ymax[i]), (0, 0, 255), 3 )
        font = cv2.FONT_HERSHEY_SIMPLEX
        cv2.putText( img, str(label_names[i]),
                     (xmin[i], ymin[i]), font, 0.7, (255, 255, 255), 1 )
        cv2.putText( img, '{:.2f}'.format(conf[i]),
                     (xmin[i], ymin[i]-20), font, 0.7, (255, 255, 255), 1 )

    cv2.imshow('Image', img)
    cv2.waitKey(0)

if __name__ == '__main__':

    labelmap_file, conf_thres = \
      get_modify_output_layer_param(args.conf_threshold,
                                    args.deploy_model)

    label, conf, xmin, ymin, xmax, ymax = \
      caffe_ssd_img_detection(args.deploy_model,
                              args.pretrain_model,
                              args.image_file)
    label = list(label)
    conf = list(conf)
    xmin = map( int, list(xmin*width) )
    xmax = map( int, list(xmax*width) )
    ymin = map( int, list(ymin*height) )
    ymax = map( int, list(ymax*height) )

    # get label names
    label_names = []
    with open(labelmap_file, 'r') as f:
        labelmap = caffe_pb2.LabelMap()
        text_format.Merge(str(f.read()), labelmap)
        for i in label:
            label_names.append( str(labelmap.item[int(i)].display_name) )

    print('conf threshold: ', conf_thres)
    print('label: ', list(label))
    print('label name:', label_names)
    print('conf: ', list(conf))
    print('xmin: ', map( int, xmin ))
    print('xmax: ', map( int, xmax ))
    print('ymin: ', map( int, ymin ))
    print('ymax: ', map( int, ymax ))
    print('image height, width, channels: ', height, width, channels)

    if args.show_img:
        show_image(img, xmin, xmax, ymin, ymax, label_names)


"Module for decorator to check variable types in function"
def check_type(function):
    "Compares types of variables with types in annotation"
    def wrapped(*args):
        annotations = (function.__annotations__).values()
        if len(args) != len(annotations):
            raise TypeError('Need type annotation for all variables')
        for (variable, type_required) in zip(args, annotations):
            if type(variable) != type_required:
                print(f'Type: {type(variable)} of variable {variable} '
                      f'is not equal to type: {type_required} in annotation')
        return function(*args)
    return wrapped

# Samples:

# @check_type
# def sample1(a, b: str, c: list):
#     c.append(a * b)
#     return c
#
# @check_type
# def sample2(a: str, b: str, c: list):
#     c.append(a * b)
#     return c
#
# @check_type
# def sample3(a: int, b: str, c: list):
#     c.append(a * b)
#     return c

# sample1(3, 'word', [])
# sample2(3, 'word', [])
# sample3(3, 'word', [])


'''tic tac toe for two players by bahubuli'''
def wincheck(board):
	if(board['1']==board['2'] and board['2']==board['3']):
		print('player with turn '+turn+ ' won the match')
		return 1
	if(board['1']==board['5'] and board['5']==board['9']):
		print('player with turn '+turn+ ' won the match')
		return 1

	if(board['1']==board['4'] and board['4']==board['7']):
		print('player with turn '+turn +' won the match')
		return 1
	if(board['3']==board['5'] and board['5']==board['7']):
		print('player with turn '+turn+ ' won the match')
		return 1
	else:
		print('either match is tied or still running')

def isfull(board):
	if '  ' not in board.values():
		return True
	else:
		return False

bord={'1':' 1 ','2':' 2 ','3':' 3 ','4':' 4 ','5':' 5 ','6':' 6 ','7':' 7 ','8':' 8 ','9':' 9 '}

def pb(board):
	print(board['1']+'|'+board['2']+'|'+board['3'])
	print('--+--+--')
	print(board['4']+'|'+board['5']+'|'+board['6'])
	print('--+--+--')
	print(board['7']+'|'+board['8']+'|'+board['9'])

turn='X'

while True:
	print('turn for  '+turn)
	move=input()
	if(int(move)>9):
		print('please enter appropriate place ')
		continue
	if(bord[move]!='X' and bord[move]!='O'):
		bord[move]=turn

	else:
		print('wrong place')
	pb(bord)
	wincheck(bord)
	if turn=='X':
		turn='O'
	else:
		turn='X'


class Node(object):
    def __init__(self, v):
        self.v = v
        self.left = None
        self.right = None
        self.small_count = 0
        self.left_count = 0
        self.dup_count = 1
    def add(self, child):
        # (self.v, self.small_count, self.dup_count).p()
        # (child.v, child.small_count, child.dup_count).p()
        # child.small_count = self.small_count
        if child.v > self.v:
            child.small_count += self.dup_count + self.left_count
            if self.right:
                self.right.add(child)
            else:
                self.right = child
        elif child.v < self.v:
            self.left_count += 1
            if self.left:
                self.left.add(child)
            else:
                self.left = child
        else:
            child.small_count += self.left_count
            self.dup_count += 1

class Solution(object):
    def countSmaller(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        n = len(nums)
        counts = []
        for i in range(n):
            count = 0
            for j in range(i+1, n):
                if nums[j] < nums[i]:
                    count += 1
            counts += count,
        return counts

    def countSmaller(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        n = len(nums)
        if n == 0: return []
        if n == 1: return [0]
        root = Node(nums[n-1])
        counts = [0] * n
        for i in range(n-2, -1, -1):
            cur = Node(nums[i])
            root.add(cur)
            counts[i] = cur.small_count
        return counts

class Solution(object):
    ## merge sort
    def countSmaller(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        if len(nums) == 0: return []
        res = [0] * len(nums)
        num_pos_arr = [(v,i) for i,v in enumerate(nums)]
        def merge_sort(left, right):
            # (left, right).p()
            new = []
            i, j = 0, 0
            while i < len(left) and j < len(right):
                if left[i] <= right[j]:
                    res[left[i][1]] += j
                    # res[left[i][1]].p()
                    new += left[i],
                    i += 1
                else:
                    new += right[j],
                    j += 1
            if i == len(left):
                new += right[j:]
            else:
                for k in range(i, len(left)):
                    res[left[k][1]] += j
                new += left[i:]
            return new
        def inner(l):
            n = len(l)
            if n == 1:
                return l
            elif n == 2:
                if l[0][0] > l[1][0]:
                    res[l[0][1]] += 1
                    # res[l[0][1]].p()
                    l[0],l[1] = l[1],l[0]
                return l
            left_l = inner(l[:n/2])
            right_l = inner(l[n/2:])
            return merge_sort(left_l, right_l)
        inner(num_pos_arr)
        return res

if __name__ == '__main__':
    from minitest import *

    with test(Solution):

        # Solution().countSmaller([30,100,51,51,21,100,41]).must_equal([1,4,2,2,0,1,0])
        # Solution().countSmaller([2,0,1]).must_equal([2,0,0])
        # Solution().countSmaller([99,8,21,65,100,41]).must_equal([4,0,0,1,1,0])
        # Solution().countSmaller([5,2,6,1]).must_equal([2,1,1,0])
        # Solution().countSmaller([5,2,2,6,1]).must_equal([3,1,1,1,0])
        # nums = [83,51,98,69,81,32,78,28,94,13,2,97,3,76,99,51,9,21,84,66,65,36,100,41]
        # results = [17,9,19,12,14,6,12,5,12,3,0,10,0,7,8,4,0,0,4,3,2,0,1,0]
        # Solution().countSmaller(nums).must_equal(results)
        nums = [26,78,27,100,33,67,90,23,66,5,38,7,35,23,52,22,83,51,98,69,81,32,78,28,94,13,2,97,3,76,99,51,9,21,84,66,65,36,100,41]
        results = [10,27,10,35,12,22,28,8,19,2,12,2,9,6,12,5,17,9,19,12,14,6,12,5,12,3,0,10,0,7,8,4,0,0,4,3,2,0,1,0]
        Solution().countSmaller(nums).must_equal(results)


#!/usr/bin/python
import grequests
from bs4 import BeautifulSoup
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlite_decl import Base, RawDataUrl, RawDataArticle
import zip
import os

dataPath = '../data'
databasePath = '%s/datacollection.db' % (dataPath)
engine = create_engine('sqlite:///%s' % databasePath)
Base.metadata.bind = engine
DBSession = sessionmaker(bind=engine)
session = DBSession()

def store_url(url, content):
    global session
    raw_data_url = session.query(RawDataUrl).filter(RawDataUrl.url == url).first
    if raw_data_url is None:
        raw_data_url = RawDataUrl(id = RawDataUrl.getMaxId(session) + 1, url=url)
        session.add(raw_data_url)
        session.commit()

    zipped = zip.zipped(content, 'article.html')
    raw_data_article = RawDataArticle(id = RawDataArticle.getMaxId(session) + 1, content = zipped, rawDataUrl = None)
    session.add(raw_data_article)
    session.commit()

def get_urls_from_response(r):
    if r is None:
        return []
    print(r.url)
    soup = BeautifulSoup(r.text, 'html.parser')
    store_url(r.url, str(soup))
    urls = [link.get('href') for link in soup.find_all('a')]
    soup.decompose()
    return urls

def print_url(args):
    print (args['url'])

def exception_handler(r,e):
        print('failed: ',r.url,'\n')
        #changing the url just for doing sth
        r.url = 'http://httpbin.org/status/200'
        res = r.send().response
        return res

def chunks(l, n):
    n = max(1, n)
    return (l[i:i+n] for i in xrange(0, len(l), n))

def recursive_urls(urls):
    """
    Given a list of starting urls, recursively finds all descendant urls
    recursively
    """
    global base_url
    if len(urls) == 0:
        return
    print (urls)
    rs = [grequests.get(url) for url in urls]
    responses = grequests.map(rs, size=100)
    url_lists = [get_urls_from_response(response) for response in responses]
    urls = sum(url_lists, [])  # flatten list of lists into a list
    urls = [url for url in urls if url is not None and url.startswith(base_url)]
    urls = list(set(urls)) # remove double entries
    for chunked_urls in chunks(urls, 100):
    	recursive_urls(chunked_urls)

def iterative_loader():
    global loadedUrls, identifiedUrls, base_url
    urls = identifiedUrls[:100]
    identifiedUrls = identifiedUrls[100:]
    rs = [grequests.get(url) for url in urls]
    responses = grequests.map(rs, size=100)
    loadedUrls = list(sum([loadedUrls, urls], []))
    url_lists = [get_urls_from_response(response) for response in responses]
    responded_urls = list(set(sum(url_lists, [])))
    responded_urls = [url for url in responded_urls if url is not None and url.startswith(base_url)]
    responded_urls = [url for url in responded_urls if not url in loadedUrls]
    identifiedUrls = list(sum([identifiedUrls, responded_urls],[]))

    print ("----------------------------------------------------")
    print ("%s identified Urls, %s loaded urls" % (len(identifiedUrls), len(loadedUrls)))
    print ("----------------------------------------------------")

base_url = 'https://www.krone.at'
loadedUrls = []
identifiedUrls = [base_url]

iterative_loader()
while (len(identifiedUrls) > 0):
    iterative_loader()

#recursive_urls([base_url])