import numpy as np
import chainer
import chainer.functions as F
from chainer import initializers
import chainer.links as L

from ada_loss.chainer_impl.functions.ada_loss_branch import AdaLossBranch
from ada_loss.chainer_impl.ada_loss import AdaLossChainer
from ada_loss.chainer_impl.functions.ada_loss_cast import ada_loss_cast
from ada_loss.chainer_impl.links.ada_loss_convolution_2d import AdaLossConvolution2D

def post_loc(x):
    """ Post loc convolution """
    y = F.transpose(x, (0, 2, 3, 1))
    y = F.reshape(y, (y.shape[0], -1, 4))
    # y = F.cast(y, 'float32')
    return y

def post_conf(mb_conf, n_class):
    """ """
    mb_conf = F.transpose(mb_conf, (0, 2, 3, 1))
    mb_conf = F.reshape(mb_conf, (mb_conf.shape[0], -1, n_class))
    # mb_conf = F.cast(mb_conf, 'float32')
    return mb_conf

class Multibox(chainer.Chain):
    """Multibox head of Single Shot Multibox Detector.

    This is a head part of Single Shot Multibox Detector [#]_.
    This link computes :obj:`mb_locs` and :obj:`mb_confs` from feature maps.
    :obj:`mb_locs` contains information of the coordinates of bounding boxes
    and :obj:`mb_confs` contains confidence scores of each classes.

    .. [#] Wei Liu, Dragomir Anguelov, Dumitru Erhan,
       Christian Szegedy, Scott Reed, Cheng-Yang Fu, Alexander C. Berg.
       SSD: Single Shot MultiBox Detector. ECCV 2016.

    Args:
        n_class (int): The number of classes possibly including the background.
        aspect_ratios (iterable of tuple or int): The aspect ratios of
            default bounding boxes for each feature map.
        initialW: An initializer used in
            :meth:`chainer.links.Convolution2d.__init__`.
            The default value is :class:`chainer.initializers.LeCunUniform`.
        initial_bias: An initializer used in
            :meth:`chainer.links.Convolution2d.__init__`.
            The default value is :class:`chainer.initializers.Zero`.

    """

    def __init__(self, n_class, aspect_ratios, initialW=None, initial_bias=None):
        super(Multibox, self).__init__()

        self.n_class = n_class
        self.aspect_ratios = aspect_ratios

        if initialW is None:
            initialW = initializers.LeCunUniform()
        if initial_bias is None:
            initial_bias = initializers.Zero()
        init = {"initialW": initialW, "initial_bias": initial_bias}

        with self.init_scope():
            # with chainer.using_config('dtype', 'float32'):
            for i, ar in enumerate(aspect_ratios):
                n = (len(ar) + 1) * 2
                loc_name = "loc_{}".format(i)
                conf_name = "conf_{}".format(i)

                setattr(self, loc_name, L.Convolution2D(n * 4, 3, pad=1, **init))
                setattr(
                    self, conf_name, L.Convolution2D(n * self.n_class, 3, pad=1, **init)
                )

            self.concat_locs = lambda xs: F.concat(xs, axis=1)
            self.concat_confs = lambda xs: F.concat(xs, axis=1)
            self.post_loc = lambda x: post_loc(x)
            self.post_conf = lambda x: post_conf(x, self.n_class)

        self.tc_locs = [None] * len(aspect_ratios)
        self.tc_confs = [None] * len(aspect_ratios)

    def forward(self, xs):
        """Compute loc and conf from feature maps

        This method computes :obj:`mb_locs` and :obj:`mb_confs`
        from given feature maps.

        Args:
            xs (iterable of chainer.Variable): An iterable of feature maps.
                The number of feature maps must be same as the number of
                :obj:`aspect_ratios`.

        Returns:
            tuple of chainer.Variable:
            This method returns two :obj:`chainer.Variable`: :obj:`mb_locs` and
            :obj:`mb_confs`.

            * **mb_locs**: A variable of float arrays of shape \
                :math:`(B, K, 4)`, \
                where :math:`B` is the number of samples in the batch and \
                :math:`K` is the number of default bounding boxes.
            * **mb_confs**: A variable of float arrays of shape \
                :math:`(B, K, n\_fg\_class + 1)`.

        """

        mb_locs = []
        mb_confs = []

        dtype = chainer.global_config.dtype

        for i, x in enumerate(xs):
            # TODO: can we don't refer to AdaLossBranch here? Maybe turn it to a
            # general forward function?
            x1, x2 = AdaLossBranch().apply((x,))
            loc = getattr(self, "loc_{}".format(i))
            mb_loc = loc(x1)
            mb_loc = self.post_loc(mb_loc)

            conf = getattr(self, "conf_{}".format(i))
            mb_conf = conf(x2)
            mb_conf = self.post_conf(mb_conf)

            if dtype != np.float32:
                if not isinstance(loc, AdaLossConvolution2D):
                    mb_loc = F.cast(mb_loc, "float32")
                    mb_conf = F.cast(mb_conf, "float32")
                else:
                    if self.tc_locs[i] is None:
                        self.tc_locs[i] = AdaLossChainer(**loc.ada_loss_cfg)
                    if self.tc_confs[i] is None:
                        self.tc_confs[i] = AdaLossChainer(**loc.ada_loss_cfg)
                    mb_loc = ada_loss_cast(mb_loc, "float32", self.tc_locs[i])
                    mb_conf = ada_loss_cast(
                        mb_conf, "float32", self.tc_confs[i], lognormal=True
                    )

            mb_locs.append(mb_loc)
            mb_confs.append(mb_conf)

        mb_locs = self.concat_locs(mb_locs)
        mb_confs = self.concat_confs(mb_confs)

        return mb_locs, mb_confs


import re

# the words to use, sorted by parts of speech, subdivided where words of the same type need different formalizations
vocabulary = {
    'P': (
        'with',
        'in',
        'on',
        'to',
        'without',
        'from',
    ),
    'N': (
        'boy',
        'student',
        'girl',
        'class',
        'book',
        'teacher',
    ),
    'PropN': (
        'john',
        'mary',
    ),
    'Vi': (
        'walks',
        'passed',
    ),
    'Vt': (
        'sees',
        'teaches',
    ),
    'Vpro': (
        'think',
    ),
    'Adj': (
        'eager',
        'smart',
    ),
    'Adv': (
        'eagerly',
        'well',
    ),
    'Det': {
        'existential': (
            'a',
            'an',
            'the',
            'some'),
        'universal': (
            'every',
            'any',
        )
    },
    'Conj': (
        'and',
        'or',
        'but',
    ),
    'Role': (
        'agent',
        'patient'
    ),
    'Event': (
        'ev_exists',
    )
}

# a function that takes string representations of functions and combines them
def combine_function_strings(f1, f2):
    var_to_swap = f1[8]  # find what symbol to substitute, formulas have form <lambda s : rest>
    full_function = f1[11:-1].replace(f'_{var_to_swap}_', f2)  # remove brackets and substitute variables, marked _v_
    # print('full', full_function)
    while True:
        # find cases for simplification. does not catch cases where function contains unresolved functions,
        # or argument contains parentheses
        stuff_to_simplify = re.search(r'<[^<>]*>\([^()]*\)', full_function)
        if stuff_to_simplify:
            stuff_to_simplify = stuff_to_simplify[0]  # retrieve the actual string
            # print('to simplify', stuff_to_simplify)
            function_part = re.search(r'<[^<>]*>\(', stuff_to_simplify)[0][:-1]
            # print('fun', function_part)
            argument_part = stuff_to_simplify.replace(function_part, '')[1:-1]  # cut the parentheses
            # print('arg', argument_part)
            replacement = combine_function_strings(
                function_part,
                argument_part
            )
            full_function = full_function.replace(stuff_to_simplify, replacement)
        else:
            break  # exit once no simplifications can be made
    # print('simplified', full_function)
    return full_function

# this class creates an object storing both the representation of an element, and its typing information
class Formalization:
    def __init__(self, formula, type_hint, type_=None, formula_string=''):
        self.formula = formula
        self.type = type_hint
        self.t = type_
        self.string = formula_string
        if type(type_hint) == tuple:
            self.selected = type_hint[0]
            self.returned = type_hint[1]
        else:
            self.selected = None

    # take another formalization object and try to compose them into a new object
    def application(self, argument):
        if argument.type == self.selected:
            resulting_formula = self.formula(argument.formula)
            resulting_string = combine_function_strings(self.string, argument.string)
            return Formalization(
                formula=resulting_formula,
                type_hint=self.returned,
                formula_string=resulting_string
            )
        elif self.type == argument.selected:
            resulting_formula = argument.formula(self.formula)
            resulting_string = combine_function_strings(argument.string, self.string)
            return Formalization(
                formula=resulting_formula,
                type_hint=argument.returned,
                formula_string=resulting_string
            )
        # case where there are two predicates, expected in event semantics
        elif (self.type == ('e', 't')) and (argument.type == ('e', 't')):
            resulting_formula = lambda x: f'{argument.formula(x)} ^ {self.formula(x)}'
            resulting_string = f'<lambda x: {argument.string}(_x_) ^ {self.string}(_x_)>'
            return Formalization(
                formula=resulting_formula,
                type_hint=('e', 't'),
                formula_string=resulting_string
            )
        else:
            print('type mismatch')

    def intensional_application(self, argument):
        if argument.type == self.returned[0]:  # that is, it matches what is selected by the extension
            resulting_formula = lambda w: self.formula(w)(argument.formula)
            resulting_string = combine_function_strings(combine_function_strings(self.string, '_w_'), argument.string)
            resulting_string = '<lambda w: ' + resulting_string + '>'
            return Formalization(
                formula=resulting_formula,
                type_hint=('s', self.returned[1]),
                formula_string=resulting_string
            )
        elif argument.returned[0] == self.type:
            resulting_formula = lambda w: argument.formula(w)(self.formula)
            resulting_string = combine_function_strings(combine_function_strings(argument.string, '_w_'), self.string)
            resulting_string = '<lambda w: ' + resulting_string + '>'
            return Formalization(
                formula=resulting_formula,
                type_hint=('s', argument.returned[1]),
                formula_string=resulting_string
            )
        else:
            print('type mismatch')

    # create an object where a given trace string is replaced by a variable
    def remove_traces(self, trace):
        split_formula = self.formula.split(trace)
        new_formula = lambda x: f'{x}'.join(split_formula)
        split_string = self.string.split(trace)
        new_string = '<lambda x:' + 'x'.join(split_string) + '>'
        return Formalization(
            formula=new_formula,
            type_hint=('e', self.type),
            formula_string=new_string
        )

# this dictionary contains functions to generate lexical entries for different parts of speech.
formalizations = {
    'PropN': lambda name: Formalization(
        name,
        'e',
        'PropN',
        name
    ),
    'N': lambda noun: Formalization(
        lambda x: f'{noun.upper()}({x})',
        ('e', 't'),
        'N',
        f'<lambda x: {noun.upper()}(_x_)>'
    ),
    'Vi': lambda verb: Formalization(
        lambda x: f'{verb.upper()}({x})',
        ('e', 't'),
        'Vi',
        f'<lambda x: {verb.upper()}(_x_)>'
    ),
    'Vt': lambda verb: Formalization(
        lambda y: lambda x: f'{verb.upper()}({x}, {y})',
        ('e', ('e', 't')),
        'Vt',
        f'<lambda y: <lambda x: {verb.upper()}(_x_, _y_)>>'
    ),
    'Vpro': lambda verb: Formalization(
        lambda P: lambda x: f'{verb.upper()}({x}, {P})',
        ('t', ('e', 't')),
        'Vpro',
        f'<lambda P: <lambda x: {verb.upper()}(_x_, _P_)'
    ),
    'Adj': lambda adjective: Formalization(
        lambda P: lambda x: f'{adjective.upper()}({x}) ^ {P(x)}',
        (('e', 't'), ('e', 't')),
        'Adj',
        f'<lambda P: <lambda x: {adjective.upper()}(_x_) ^ _P_(_x_)>>'
    ),
    'Adv': lambda adverb: Formalization(
        lambda P: lambda x: f'{adverb.upper()}({P(x)})',
        (('e', 't'), ('e', 't')),
        'Adv',
        f'<lambda P: <lambda x: {adverb.upper()}(_P_(_x_))>>'
    ),
    'P': lambda preposition: Formalization(
        lambda x: lambda y: f'{preposition.upper()}({x}, {y})',
        ('e', ('e', 't')),
        'P',
        f'<lambda y: <lambda x: {preposition.upper()}(_x_, _y_)>>'
    ),
    # 'existential': lambda _: Formalization(
    #     lambda P: lambda Q: f'Exists x[{P("x")} ^ {Q("x")}]',
    #     (('e', 't'), (('e', 't'), 't')),
    #     'existential',
    #     '<lambda P: <lambda Q: Exists x[_P_(x) ^ _Q_(x)]>>'
    # ),
    # 'universal': lambda _: Formalization(
    #     lambda P: lambda Q: f'All x[{P("x")} -> {Q("x")}]',
    #     (('e', 't'), (('e', 't'), 't')),
    #     'universal',
    #     '<lambda P: <lambda Q: All x[_P_(x) -> _Q_(x)]>>'
    # ),
    # alternative entry for quantifiers where they can use variables represented by other things than x
    'existential': lambda _: Formalization(
        lambda v: lambda P: lambda Q: f'Exists {v}[{P(v)} ^ {Q(v)}]',
        ('v', (('e', 't'), (('e', 't'), 't'))),
        'existential',
        '<lambda v : <lambda P: <lambda Q: Exists _v_[_P_(_v_) ^ _Q_(_v_)]>>>'
    ),
    'universal': lambda _: Formalization(
        lambda v: lambda P: lambda Q: f'All {v}[{P(v)} -> {Q(v)}]',
        ('v', (('e', 't'), (('e', 't'), 't'))),
        'universal',
        '<lambda v : <lambda P: <lambda Q: All _v_[_P_(_v_) -> _Q_(_v_)]>>>'
    ),
    'Var': lambda name: Formalization(
        name,
        'v',
        'Var',
        name,
    ),
}

formalizations_events = formalizations.copy()
formalizations_events.update({
    'Vi': lambda verb: Formalization(
        lambda e: f'{verb.upper()}({e})',
        ('e', 't'),
        'Vi',
        f'<lambda e: {verb.upper()}(_e_)>'
    ),
    'Vt': lambda verb: Formalization(
        lambda e: f'{verb.upper()}({e})',
        ('e', 't'),
        'Vt',
        f'<lambda e: {verb.upper()}(_e_)>'
    ),
    'Adv': lambda adverb: Formalization(
        lambda e: f'{adverb.upper()}({e})',
        ('e', 't'),
        'Adv',
        f'<lambda e: {adverb.upper()}(_e_)>'
    ),
    'Role': lambda role: Formalization(
        lambda x: lambda e: f'{role.upper()}({x}, {e})',
        ('e', ('e', 't')),
        'Role',
        f'<lambda x: <lambda e: {role.upper()}(_x_, _e_)>>'
    ),
    'Event': lambda _: Formalization(
        lambda P: f'Exists e[{P("e")}]',
        (('e', 't'), 't'),
        'Event',
        f'<lambda P: Exists e[_P_(e)]>'
    )
})

intensional_formalizations = {
    'PropN': lambda name: Formalization(
        lambda w: name,
        ('s', 'e'),
        'PropN',
        f'<lambda w: {name}>'
    ),
    'N': lambda noun: Formalization(
        lambda w: lambda x: f'{noun.upper()}({w})({x(w)})',
        ('s', (('s', 'e'), 't')),
        'N',
        f'<lambda w: <lambda x: {noun.upper()}(_w_)(_x_(_w_))>>'
    ),
    'Vi': lambda verb: Formalization(
        lambda w: lambda x: f'{verb.upper()}({w})({x(w)})',
        ('s', (('s', 'e'), 't')),
        'N',
        f'<lambda w: <lambda x: {verb.upper()}(_w_)(_x_(_w_))>>'
    ),
    'Vt': lambda verb: Formalization(
        lambda w: lambda y: lambda x: f'{verb.upper()}({w})({x(w)}, {y(w)})',
        ('s', (('s', 'e'), (('s', 'e'), 't'))),
        'Vt',
        f'<lambda w: <lambda y: <lambda x: {verb.upper()}(_w_)(_x_(_w_), _y_(_w_))>>>'
    ),
    'Adj': lambda adjective: Formalization(
        lambda w: lambda P: lambda x: f'{adjective.upper()}({w})({x(w)}) ^ {P(w)(x(w))}',
        ('s', ((('s', 'e'), 't'), (('s', 'e'), 't'))),
        'Adj',
        f'<lambda w: <lambda P: <lambda x: {adjective.upper()}(_w_)(_x_(_w_)) ^ _P_(_w_)(_x_(_w_))>>>'
    ),
    'Adv': lambda adverb: Formalization(
        lambda w: lambda P: lambda x: f'{adverb.upper()}({w})({P(w)(x(w))})',
        ('s', ((('s', 'e'), 't'), (('s', 'e'), 't'))),
        'Adv',
        f'<lambda P: <lambda x: {adverb.upper()}(_w_)(_P_(_w_)(_x_(_w_)))>>'
    ),
    'P': lambda preposition: Formalization(
        lambda w: lambda y: lambda x: f'{preposition.upper()}({w})({x(w)}, {y(w)})',
        ('s', (('s', 'e'), (('s', 'e'), 't'))),
        'P',
        f'<lambda w: <lambda y: <lambda x: {preposition.upper()}(_w_)(_x_(_w_), _y_(_w_))>>>'
    ),
    # Predicate intension functions will attempt to call their argument, so quantifiers look like this now
    'existential': lambda _: Formalization(
        lambda w: lambda P: lambda Q: f'Exists x[{P(w)(lambda _: "x")} ^ {Q(w)(lambda _: "x")}]',
        ('s', (('s', (('s', 'e'), 't')), (('s', (('s', 'e'), 't')), 't'))),
        'existential',
        '<lambda w: <lambda P: <lambda Q: Exists x[_P_(_w_)(x) ^ _Q_(_w_)(x)]>>>'
    ),
    'universal': lambda _: Formalization(
        lambda w: lambda P: lambda Q: f'All x[{P(w)(lambda _: "x")} -> {Q(w)(lambda _: "x")}]',
        ('s', (('s', (('s', 'e'), 't')), (('s', (('s', 'e'), 't')), 't'))),
        'universal',
        '<lambda w: <lambda P: <lambda Q: All x[_P_(_w_)(x) -> _Q_(_w_)(x)]>>>'
    )
}

# takes a vocabulary and a dictionary of translation methods,
# then returns a lexicon storing word: Formalization pairs sorted by parts of speech
def generate_lexicon(vocab, translations):
    lexicon = {}
    for part_of_speech, entries in vocab.items():
        if part_of_speech in translations.keys():
            lexicon.update({word: translations[part_of_speech](word) for word in entries})
        elif type(entries) == dict:
            for subtype, words in entries.items():
                lexicon.update({word: translations[subtype](word) for word in words})
        else:
            lexicon.update({part_of_speech: {word: Formalization(word, 'e') for word in entries}})
    return lexicon

# generate entries for terminal symbol rules for use in grammar based on a lexicon as created by generate_lexicon
def vocabulary_to_terminals(vocab):
    terminal_rules = ''
    for part_of_speech in vocab.keys():
        if type(vocab[part_of_speech]) == dict:
            words = ()
            for sublist in vocab[part_of_speech].values():
                words += tuple(word for word in sublist)
        else:
            words = vocab[part_of_speech]
        terminals_string = " | ".join(["'" + word + "'" for word in words])
        terminal_rules += (part_of_speech + ' -> ' + terminals_string + '\n\t')
    return terminal_rules

extensional_lexicon = generate_lexicon(vocabulary, formalizations)
intensional_lexicon = generate_lexicon(vocabulary, intensional_formalizations)
event_lexicon = generate_lexicon(vocabulary, formalizations_events)

extensional_grammar = f"""
    S -> DP VP
    DP -> Det NP | PropN
    NP -> N  | Adj NP | NP PP
    VP -> Vi | Vt  | Vbar DP | Vbar DP PP | Adv VP | VP Adv | VP Conj VP | V AdvP
    Vbar -> Vi | Vt
    AdvP -> Adv P
    PP -> P DP

    {vocabulary_to_terminals(vocabulary)}
"""

event_grammar = f"""
    EP -> Event VP
    ThetaP -> Role DP
    DP -> Det NP | NP | DP Conj DP
    NP -> N | PropN | Adj NP | NP PP
    VP -> ThetaP VP | Vi | Vt | Vbar ThetaP | Vbar ThetaP PP | AdvP VP | VP Adv | VP Conj VP | V AdvP
    Vbar -> Vi | Vt
    AdvP -> Adv P
    PP -> P DP

    {vocabulary_to_terminals(vocabulary)}
"""
# # for testing purposes
# print(event_lexicon)
# print(extensional_grammar)

# result = extensional_lexicon['Det']['every'].application(
#     extensional_lexicon['N']['student']
# ).application(
#     extensional_lexicon['Vi']['passed']
# )
# print(result.string)


list=input()
def bubble(nums):
    for i in range(len(nums) - 1):
        for j in range(len(nums) - i - 1):
            if nums[j] > nums[j + 1]:
                nums[j], nums[j + 1] = nums[j + 1], nums[j]
    return nums

for i in range(len(list)):
    temp = []
    length=len(list)-i
    for j in range(length):
        temp.append(list[j+i][j])
    temp=bubble(temp)
    for j in range(length):
        list[j+i][j]=temp[j]

for i in range(len(list[0])):
    a=len(list[0])-len(list)
    if i<=a:
        length=len(list)
    else:
        length = len(list[0]) - i
    temp=[]
    for j in range(length):
        temp.append(list[j][j+i])
    temp=bubble(temp)
    for j in range(length):
        list[j][j+i]=temp[j]

print (list)


from flask import Flask, jsonify, request, make_response
from flask_migrate import Migrate
from flask_sqlalchemy import SQLAlchemy
from flask_restful import Api, Resource

from models import Restaurant, Pizza, RestaurantPizza, db

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///app.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['JSONIFY_PRETTYPRINT_REGULAR'] = True
app.json.compact = False

migrate = Migrate(app, db, render_as_batch=True)
db.init_app(app)

api = Api(app)

# "landing" page
class Home(Resource):
    def get(self):
        response_dict = {
            "Home page": "Welcome to the Restauraunt page",
        }
        response = make_response(
            jsonify(response_dict),
            200,
        )
        return response

api.add_resource(Home, '/')

class Restaurants(Resource):
    # GET for restaurants
    def get(self):
        response_dict_list = [n.to_dict() for n in Restaurant.query.all()]
        response = make_response(
            jsonify(response_dict_list),
            200,
        )
        return response

    # POST for restaurants
    def post(self):
        new_restaurant = Restaurant(
            name=request.form['name'],
            address=request.form['address'],
        )

        db.session.add(new_restaurant)
        db.session.commit()

        response_dict= new_restaurant.to_dict()

        response = make_response(
            jsonify(response_dict),
            201,
        )
        return response

api.add_resource(Restaurants, '/restaurants')

class RestaurantById(Resource):
    # GET for restaurantbyID
    def get(self, id):
        restaurant = Restaurant.query.filter_by(id=id).first()
        if restaurant:
            response = make_response(
                jsonify(restaurant.to_dict()),
                200,
            )
            return response
        else:
            response = jsonify({"message": "Not Found"})
            return response, 404

    # DELETE for restaurantbyID
    def delete(self, id):
        restaurant = Restaurant.query.get(id)

        if restaurant:
            Restaurant.query.filter_by(id=id).delete

            db.session.delete(restaurant)
            db.session.commit()

            response = jsonify({"message": "Restaurant successfully deleted"})
            return response, 200
        else:
            response = jsonify({"message": "Not Found"})
            return response, 404

api.add_resource(RestaurantById, '/restaurants/<int:id>')

class Pizzas(Resource):
    # GET for Pizzas
    def get(self):
        response_dict_list = [n.to_dict() for n in Pizza.query.all()]

        response = make_response(
            jsonify(response_dict_list),
            200,
        )
        return response

api.add_resource(Pizzas, '/pizzas')

class RestaurantPizzas(Resource):

    def get(self):
        response_dict_list = [n.to_dict() for n in RestaurantPizza.query.all()]
        response = make_response(
            jsonify(response_dict_list),
            200,
        )
        return response

    def post(self):
        data = request.get_json()

        price=data.get('price')
        pizza_id=data.get('pizza_id')
        restaurant_id=data.get('restaurant_id')

        if pizza_id and restaurant_id:
            new_restaurant_pizza = RestaurantPizza(
                price=price,
                pizza_id=pizza_id,
                restaurant_id=restaurant_id
            )

            db.session.add(new_restaurant_pizza)
            db.session.commit()

            pizza = Pizza.query.get(pizza_id)
            if pizza:
                response = make_response(
                    {"id": pizza.id,
                    "ingredients" : pizza.ingredients,
                    "name" : pizza.name},
                    201
                )
                return response

            else:
                response = jsonify({"message": "Not Found"})
                return response, 404

api.add_resource(RestaurantPizzas, '/restaurant_pizzas')

if __name__ == "__main__":
    app.run(debug=True, port=5555)


from helpers import address_helper as ah, folium_helper as fh, streamlit_helper as sh
from streamlit_folium import folium_static, st_folium
import streamlit as st

sh.SetInitialStreamlitStates()

def validate_button_clicked():
    given_address = st.session_state.address
    google_lat, google_long, st.session_state.address_json_google = ah.GetLocationInfo(given_address, "Google")
    yandex_lat, yandex_long, st.session_state.address_json_yandex = ah.GetLocationInfo(given_address, "Yandex")

    st.session_state.google_map = fh.CreateMap([google_lat, google_long])
    st.session_state.yandex_map = fh.CreateMap([yandex_lat, yandex_long])

    st.session_state.google_map_lat_long = f"Koordinatlar: {[google_lat, google_long]}"
    st.session_state.yandex_map_lat_long = f"Koordinatlar: {[yandex_lat, yandex_long]}"

st.title("Address Validator")

st.text_area("Address", key="address")

st.button("Validate", on_click=validate_button_clicked)

c1, c2 = st.columns(2)

with c1:
    st.subheader("Google")
    st_folium(fig=st.session_state.google_map, key="gmap", height=400)
    st.markdown(st.session_state.google_map_lat_long)
    st.write(st.session_state.address_json_google)
with c2:
    st.subheader("Yandex")
    st_folium(fig=st.session_state.yandex_map, key="ymap", height=400)
    st.markdown(st.session_state.yandex_map_lat_long)
    st.write(st.session_state.address_json_yandex)


import pyomo.environ as aml
import pyomo.dae as dae
import pyomo.network as pyn
from pyomo.common.collections import ComponentSet
from pyomo.core.expr.visitor import identify_variables
from pyomo.util.calc_var_value import calculate_variable_from_constraint

from idaes.core import (FlowsheetBlock, MaterialBalanceType, EnergyBalanceType,
        MomentumBalanceType)
from idaes.core.util.model_statistics import (degrees_of_freedom,
        activated_equalities_generator, unfixed_variables_generator)
from idaes.core.util.initialization import initialize_by_time_element
from idaes.core.util.exceptions import ConfigurationError
from idaes.apps.caprese import nmpc
from idaes.apps.caprese.nmpc import *
from idaes.apps.caprese.util import *
from idaes.apps.caprese.common.config import (
        VariableCategory,
        ElementInitializationInputOption,
        ControlInitOption,
        )
from idaes.apps.caprese.tests.test_model import (
        make_model,
        make_small_model,
        initialize_t0,
        copy_values_forward,
        )
import idaes.logger as idaeslog
import random
import pytest

__author__ = "Robert Parker"

# See if ipopt is available and set up solver
solver_available = SolverFactory('ipopt').available()
if solver_available:
    solver = SolverFactory('ipopt')
#    solver.options = {'tol': 1e-8,
#                      'mu_init': 1e-8,
#                      'bound_push': 1e-8,
#                      'halt_on_ampl_error': 'yes'}
# Want to run with default options.
else:
    solver = None

class TestNMPCSim(object):
    def make_nmpc(self, sample_time=0.5, horizon=1, nfe=2):
        plant = make_model(horizon=horizon, nfe=nfe)
        plant_time = plant.time
        plant_inputs = [plant.flow_in[plant_time.first()]]
        controller = make_model(horizon=horizon, nfe=nfe)
        controller_time = controller.time
        nmpc = NMPCSim(
                plant_model=plant,
                plant_time_set=plant_time,
                controller_model=controller,
                controller_time_set=controller_time,
                inputs_at_t0=plant_inputs,
                sample_time=sample_time,
                )
        return nmpc

    @pytest.mark.unit
    def test_constructor(self):
        """
        Categorization is tested rigorously in the test_nmpc_constructor
        files. This test is very basic by comparison
        """
        nmpc = self.make_nmpc()
        assert not nmpc.controller_solved
        assert nmpc.current_plant_time == 0
        assert hasattr(nmpc.controller, nmpc.namespace_name)
        assert hasattr(nmpc.plant, nmpc.namespace_name)
        controller_namespace = getattr(nmpc.controller, nmpc.namespace_name)
        plant_namespace = getattr(nmpc.plant, nmpc.namespace_name)

        locator_name = 'var_locator'
        category_name = 'category_dict'
        assert hasattr(controller_namespace, locator_name)
        assert hasattr(plant_namespace, locator_name)
        assert hasattr(controller_namespace, category_name)
        assert hasattr(plant_namespace, category_name)

    @pytest.mark.unit
    def test_add_namespace_to(self):
        nmpc = self.make_nmpc()
        model = make_small_model()
        nmpc.add_namespace_to(model, model.time)
        assert hasattr(model, nmpc.namespace_name)

    @pytest.mark.unit
    def test_validate_sample_time(self):
        nmpc = self.make_nmpc()
        model = make_small_model()
        sample_time = 0.5
        nmpc.add_namespace_to(model, model.time)
        nmpc.validate_sample_time(sample_time, model)
        namespace = getattr(model, nmpc.namespace_name)
        assert hasattr(namespace, 'sample_points')
        assert hasattr(namespace, 'fe_per_sample')

        sample_point_set = set(namespace.sample_points)
        # NOTE: My implementation has wavered between whether or not
        # time.first() is a sample point. I now assert, hopefully for
        # good, that it is.
        for p in [0.0, 0.5, 1]:
            assert p in sample_point_set

    @pytest.mark.unit
    def test_validate_slices(self):
        nmpc = self.make_nmpc()
        plant_namespace = getattr(nmpc.plant, nmpc.namespace_name)
        controller_namespace = getattr(nmpc.controller, nmpc.namespace_name)
        src_slices = [
                plant_namespace.diff_vars[0],
                plant_namespace.alg_vars[0],
                ]
        src_names = [_slice[0].name for _slice in src_slices]
        tgt_names = [
                nmpc.controller.conc[0,'A'].name,
                nmpc.controller.flow_out[0].name,
                ]
        # This will be violated if component construction order (and
        # therefore categorization) is changed.
        assert src_names == tgt_names
        tgt_slices = nmpc.validate_slices(
                nmpc.controller,
                nmpc.plant,
                nmpc.plant_time,
                src_slices)
        tgt_slice_names = [_slice[0].name for _slice in tgt_slices]
        assert tgt_names == tgt_slice_names

    @pytest.mark.unit
    def test_validate_fixedness(self):
        nmpc = self.make_nmpc()
        nmpc.validate_fixedness(nmpc.plant, nmpc.controller)
        nmpc.plant.conc[0,'A'].unfix()
        with pytest.raises(AssertionError):
            nmpc.validate_fixedness(nmpc.plant)
        nmpc.plant.conc[0,'A'].fix()
        t1 = nmpc.plant_time.get_finite_elements()[1]
        nmpc.plant.conc_in[t1, 'A'].unfix()
        with pytest.raises(AssertionError):
            nmpc.validate_fixedness(nmpc.plant)

    @pytest.mark.unit
    def test_transfer_current_plant_state_to_controller(self):
        nmpc = self.make_nmpc()
        ts = nmpc.plant_time.first() + nmpc.sample_time
        nmpc.plant.conc[ts,'A'].set_value(4)
        nmpc.plant.conc[ts,'B'].set_value(5)
        nmpc.transfer_current_plant_state_to_controller(ts,
                add_plant_noise=False)
        t0 = nmpc.controller_time.first()
        assert nmpc.controller.conc[t0,'A'].value == 4
        assert nmpc.controller.conc[t0,'B'].value == 5

        random.seed(123)
        nmpc.transfer_current_plant_state_to_controller(ts,
                add_plant_noise=True,
                noise_weights=[1,1])
        assert nmpc.controller.conc[t0,'A'].value != 4
        assert nmpc.controller.conc[t0,'B'].value != 5

    @pytest.mark.unit
    def test_inject_control_inputs_into_plant(self):
        nmpc = self.make_nmpc()
        n_samples = 2
        sample_inputs = {1: 3, 2: 6}
        plant_sample_points = [nmpc.plant_time.first() + i*nmpc.sample_time
                for i in range(n_samples+1)]
        plant_sample = {i+1: [t for t in nmpc.plant_time
            if t > plant_sample_points[i] and t <= plant_sample_points[i+1]]
            for i in range(n_samples)}
        tc = nmpc.controller_time.first() + nmpc.sample_time

        for i in range(n_samples):
            nmpc.controller.flow_in[tc].set_value(sample_inputs[i+1])
            nmpc.inject_control_inputs_into_plant(plant_sample_points[i])
            for t in plant_sample[i+1]:
                assert nmpc.plant.flow_in[t] == sample_inputs[i+1]
            nmpc.inject_control_inputs_into_plant(plant_sample_points[i],
                    add_input_noise=True,
                    noise_weights=[1])
            for t in plant_sample[i+1]:
                assert nmpc.plant.flow_in[t] != sample_inputs[i+1]

    @pytest.mark.unit
    def test_has_consistent_initial_conditions(self):
        nmpc = self.make_nmpc()
        with pytest.raises(ValueError):
            # Model has not been properly initialized
            nmpc.has_consistent_initial_conditions(nmpc.plant)

        t0 = nmpc.plant_time.first()
        nmpc.plant.rate[t0,:].set_value(0.0)
        nmpc.plant.flow_out[t0].set_value(nmpc.plant.flow_in[t0].value)
        for j in nmpc.plant.components:
            calculate_variable_from_constraint(
                    nmpc.plant.dcdt[t0,j],
                    nmpc.plant.material_balance[t0,j],
                    )
        assert nmpc.has_consistent_initial_conditions(nmpc.plant)

        nmpc.plant.flow_out[t0].set_value(0.0)
        assert not nmpc.has_consistent_initial_conditions(nmpc.plant)

    @pytest.mark.unit
    def test_solve_consistent_initial_conditions(self):
        # solve, assert has_consistent..., assert same dof
        nmpc = self.make_nmpc()
        dof_prior = degrees_of_freedom(nmpc.plant)

        # Just going to assume this model needs no additional
        # initialization before solving for initial conditions.
        nmpc.solve_consistent_initial_conditions(nmpc.plant)
        assert nmpc.has_consistent_initial_conditions(nmpc.plant)
        dof_post = degrees_of_freedom(nmpc.plant)
        assert dof_prior == dof_post

        nmpc.controller.flow_in.setlb(0.0)
        nmpc.controller.flow_out.setlb(0.0)
        nmpc.controller.flow_in.setub(10.0)
        nmpc.controller.flow_out.setub(10.0)
        nmpc.solve_consistent_initial_conditions(nmpc.controller,
                strip_bounds=False)
        assert nmpc.has_consistent_initial_conditions(nmpc.controller)

    @pytest.mark.unit
    def test_calculate_full_state_setpoint(self):
        # come up with setpoint, solve, check data structures,
        # make sure values of setpoint make sense.
        nmpc = self.make_nmpc()
        namespace = getattr(nmpc.controller, nmpc.namespace_name)
        t0 = nmpc.controller_time.first()
        setpoint = [
                (nmpc.controller.flow_in[t0], 3.0),
                ]
        # Note: without this initialization, the setpoint arrives at a
        # local optimum with inlet flow ~= 0.
        nmpc.controller.flow_in[:].set_value(3.0)
        initialize_t0(nmpc.controller)
        nmpc.calculate_full_state_setpoint(setpoint, outlvl=idaeslog.DEBUG)
        categories = [VariableCategory.DIFFERENTIAL, VariableCategory.ALGEBRAIC]
        for categ in categories:
            group = namespace.category_dict[categ]
            for i, var in enumerate(group):
                assert group.setpoint[i] is not None

        assert namespace.diff_vars.setpoint[0] == pytest.approx(3.75)
        assert namespace.diff_vars.setpoint[1] == pytest.approx(1.25)
        assert namespace.alg_vars.setpoint[0] == pytest.approx(3.0)
        assert namespace.alg_vars.setpoint[1] == pytest.approx(-3.75)
        assert namespace.alg_vars.setpoint[2] == pytest.approx(3.75)
        assert namespace.input_vars.setpoint[0] == pytest.approx(3.0)

    @pytest.mark.unit
    def test_solve_setpoint(self):
        # create objective function on model
        # get dof
        # call solve_setpoint
        # compare dof
        # compare values
        nmpc = self.make_nmpc()
        time = nmpc.controller_time
        t0 = time.first()
        namespace = getattr(nmpc.controller, nmpc.namespace_name)
        mod = nmpc.controller
        mod.objective = Objective(expr=
                (mod.flow_in[t0] - 3.0)**2 + (mod.conc[t0,'A'] - 5)**2)
        nmpc.controller.flow_in[:].set_value(3.0)
        initialize_t0(nmpc.controller)

        dof_prior = degrees_of_freedom(mod)
        nmpc.solve_setpoint(require_steady=False, outlvl=idaeslog.DEBUG)
        dof_post = degrees_of_freedom(mod)

        assert dof_prior == dof_post
        assert namespace.diff_vars[0][t0].value == pytest.approx(5.0, abs=1e-3)
        assert namespace.diff_vars[1][t0].value == pytest.approx(7.11, abs=1e-3)
        assert namespace.alg_vars[0][t0].value == pytest.approx(3.0, abs=1e-3)
        assert namespace.alg_vars[1][t0].value == pytest.approx(-5.0, abs=1e-3)
        assert namespace.alg_vars[2][t0].value == pytest.approx(5.0, abs=1e-3)
        assert namespace.input_vars[0][t0].value == pytest.approx(3.0, abs=1e-3)

    @pytest.mark.unit
    def test_add_setpoint_to_controller(self):
        # This test just creates an objective then makes sure it has the
        # correct variables. More detailed tests will be performed for
        # construct_objective_weights and add_objective_function.
        nmpc = self.make_nmpc()
        time = nmpc.controller_time
        t0 = time.first()
        namespace = getattr(nmpc.controller, nmpc.namespace_name)
        setpoint = [
                (nmpc.controller.flow_in[t0], 3.0),
                ]
        # Note: without this initialization, the setpoint arrives at a
        # local optimum with inlet flow ~= 0.
        nmpc.controller.flow_in[:].set_value(3.0)
        initialize_t0(nmpc.controller)
        nmpc.calculate_full_state_setpoint(setpoint, outlvl=idaeslog.DEBUG)
        categories = [VariableCategory.DIFFERENTIAL]
        nmpc.add_setpoint_to_controller(objective_state_categories=categories)
        assert hasattr(namespace, 'tracking_objective')
        obj_variables = ComponentSet(
                identify_variables(namespace.tracking_objective.expr))

        n_samples = len(namespace.sample_points) - 1
        assert len(obj_variables) == (len(namespace.diff_vars) +
                len(namespace.input_vars))*n_samples
        for var in namespace.diff_vars.varlist + namespace.input_vars.varlist:
            for ts in namespace.sample_points:
                if ts == t0:
                    continue
                assert var[ts] in obj_variables

    @pytest.mark.unit
    def test_set_reference_values_from_initial(self):
        nmpc = self.make_nmpc()
        time = nmpc.plant_time
        t0 = time.first()
        namespace = getattr(nmpc.plant, nmpc.namespace_name)
        diff_vars = namespace.diff_vars
        nmpc.set_reference_values_from_initial(diff_vars)
        for i, var in enumerate(diff_vars):
            assert var[t0].value == diff_vars.reference[i]

    @pytest.mark.unit
    def test_construct_objective_weights(self):
        """
        Populates setpoint values,

        """
        nmpc = self.make_nmpc()
        time = nmpc.controller_time
        t0 = time.first()
        namespace = getattr(nmpc.controller, nmpc.namespace_name)
        setpoint = [
                (nmpc.controller.flow_in[t0], 3.0),
                ]
        # Note: without this initialization, the setpoint arrives at a
        # local optimum with inlet flow ~= 0.
        nmpc.controller.flow_in[:].set_value(3.0)
        initialize_t0(nmpc.controller)
        nmpc.calculate_full_state_setpoint(setpoint, outlvl=idaeslog.DEBUG)

        reference = namespace.diff_vars.reference
        setpoint = namespace.diff_vars.setpoint
        n_diff_vars = len(namespace.diff_vars)
        predicted_diff_weights = [
                1./abs(reference[i] - setpoint[i]) for i in range(n_diff_vars)
                ]
        tol = 1e-5
        nmpc.construct_objective_weights(
                nmpc.controller,
                categories=[
                    VariableCategory.DIFFERENTIAL,
                    VariableCategory.INPUT,
                    ],
                objective_weight_tolerance=tol,
                )
        for pred, act in zip(predicted_diff_weights,
                namespace.diff_vars.weights):
            assert pred == act
        assert namespace.input_vars.weights[0] == 1/tol

        override = [
                (nmpc.controller.rate[t0,'A'], 2),
                (nmpc.controller.rate[t0,'B'], 2),
                (nmpc.controller.flow_out[t0], 2),
                ]
        nmpc.construct_objective_weights(
                nmpc.controller,
                categories=[
                    VariableCategory.ALGEBRAIC,
                    ],
                objective_weight_override=override,
                )
        for w in namespace.alg_vars.weights:
            assert w == 2

    @pytest.mark.unit
    def test_add_objective_function(self):
        # populate setpoints,
        # construct weights (with override everywhere)
        # add objective function
        # compare objective function to prediction
        # for diff+error, diff+action, diff+alg+action setpoints
        nmpc = self.make_nmpc()
        time = nmpc.controller_time
        t0 = time.first()
        namespace = getattr(nmpc.controller, nmpc.namespace_name)
        setpoint = [
                (nmpc.controller.flow_in[t0], 3.0),
                ]
        # Note: without this initialization, the setpoint arrives at a
        # local optimum with inlet flow ~= 0.
        nmpc.controller.flow_in[:].set_value(3.0)
        initialize_t0(nmpc.controller)
        copy_values_forward(nmpc.controller)
        nmpc.calculate_full_state_setpoint(setpoint, outlvl=idaeslog.DEBUG)
        override = [
                (nmpc.controller.conc[t0,'A'], 1),
                (nmpc.controller.conc[t0,'B'], 1),
                (nmpc.controller.rate[t0,'A'], 1),
                (nmpc.controller.rate[t0,'B'], 1),
                (nmpc.controller.flow_out[t0], 1),
                (nmpc.controller.flow_in[t0], 1),
                ]
        nmpc.construct_objective_weights(
                nmpc.controller,
                objective_weight_override=override,
                )
        pred_obj = {i: 0. for i in range(1, 4)}
        sample_points = namespace.sample_points[1:]
        setpoint = namespace.diff_vars.setpoint
        for i, v in enumerate(namespace.diff_vars):
            for t in sample_points:
                pred_obj[1] += (v[t] - setpoint[i])**2
                pred_obj[2] += (v[t] - setpoint[i])**2
                pred_obj[3] += (v[t] - setpoint[i])**2
        setpoint = namespace.alg_vars.setpoint
        for i, v in enumerate(namespace.alg_vars):
            for t in sample_points:
                pred_obj[3] += (v[t] - setpoint[i])**2
        setpoint = namespace.input_vars.setpoint
        for i, v in enumerate(namespace.input_vars):
            for t in sample_points:
                t_prev = t - nmpc.sample_time
                pred_obj[1] += (v[t] - setpoint[i])**2
                pred_obj[2] += (v[t] - v[t_prev])**2
                pred_obj[3] += (v[t] - v[t_prev])**2

        nmpc.add_objective_function(
                nmpc.controller,
                control_penalty_type=ControlPenaltyType.ERROR,
                objective_state_categories=[
                    VariableCategory.DIFFERENTIAL,
                    ]
                )
        assert aml.value(namespace.objective.expr == pred_obj[1])
        namespace.del_component(namespace.objective)

        nmpc.add_objective_function(
                nmpc.controller,
                control_penalty_type=ControlPenaltyType.ACTION,
                objective_state_categories=[
                    VariableCategory.DIFFERENTIAL,
                    ]
                )
        assert aml.value(namespace.objective.expr == pred_obj[2])
        namespace.del_component(namespace.objective)

        nmpc.add_objective_function(
                nmpc.controller,
                control_penalty_type=ControlPenaltyType.ACTION,
                objective_state_categories=[
                    VariableCategory.DIFFERENTIAL,
                    VariableCategory.ALGEBRAIC,
                    ]
                )
        assert aml.value(namespace.objective.expr == pred_obj[3])
        namespace.del_component(namespace.objective)

    @pytest.mark.unit
    def test_set_bounds_from_initial(self):
        # change bounds on some VarGroup
        # copy forward in time
        # check at all t > t0
        nmpc = self.make_nmpc()
        namespace = getattr(nmpc.controller, nmpc.namespace_name)
        time = nmpc.controller_time
        t0 = time.first()
        for var in namespace.input_vars:
            var[t0].domain = aml.NonNegativeReals
            var[t0].setub(10.)
        for var in namespace.diff_vars:
            var[t0].domain = aml.NonNegativeReals
            var[t0].setub(100.)
        namespace.diff_vars.varlist[0].setlb(1.)
        namespace.diff_vars.varlist[1].setlb(-1.)

        for var in namespace.scalar_vars:
            var.setlb(0.1)
            var.setub(11.)
        nmpc.set_bounds_from_initial(namespace.input_vars)
        nmpc.set_bounds_from_initial(namespace.diff_vars)
        nmpc.set_bounds_from_initial(namespace.scalar_vars)
        # ^ Won't actually do anything for scalar vars...
        for t in time:
            if t == t0:
                continue
            for var in namespace.input_vars:
                assert var[t].ub == var[t0].ub
                assert var[t].lb == 0.0
            for var in namespace.diff_vars:
                assert var[t].ub == var[t0].ub
            assert namespace.diff_vars.varlist[0][t].lb == 1.0
            assert namespace.diff_vars.varlist[1][t].lb == 0.0

    @pytest.mark.unit
    def test_constrain_control_inputs_piecewise_constant(self):
        # construct nmpc
        # constrain_control_inputs
        # assert hasattr pwc_constraint_list, pwc_constraint
        # for each, assert has correct variables
        nmpc = self.make_nmpc()
        namespace = getattr(nmpc.controller, nmpc.namespace_name)
        time = nmpc.controller_time
        t0 = time.first()
        sample_points = namespace.sample_points
        sample_point_set = set(sample_points)
        nmpc.constrain_control_inputs_piecewise_constant()
        assert hasattr(namespace, 'pwc_constraint')
        assert hasattr(namespace, 'pwc_constraint_list')
        for var, con in zip(namespace.input_vars,
                namespace.pwc_constraint_list):
            for t in time:
                if t in sample_point_set:
                    continue
                t_next = time.next(t)
                incident_vars = ComponentSet(
                        identify_variables(con[t].expr))
                assert var[t] in incident_vars
                assert var[t_next] in incident_vars

    @pytest.mark.unit
    def test_initialize_control_problem(self):
        # Each initialization strategy should be tested in more detail
        # in other functions.
        # This function should test that each strategy can be passed to
        # the user-facing function, and that the values left in the
        # controller model are somewhat reasonable
        nmpc = self.make_nmpc()
        time = nmpc.controller_time
        t0 = time.first()
        namespace = getattr(nmpc.controller, nmpc.namespace_name)
        setpoint = [
                (nmpc.controller.flow_in[t0], 3.0),
                ]
        # Note: without this initialization, the setpoint arrives at a
        # local optimum with inlet flow ~= 0.
        nmpc.controller.flow_in[:].set_value(3.0)
        initialize_t0(nmpc.controller)
        copy_values_forward(nmpc.controller)
        nmpc.calculate_full_state_setpoint(setpoint, outlvl=idaeslog.DEBUG)
        override = [
                (nmpc.controller.conc[t0,'A'], 1),
                (nmpc.controller.conc[t0,'B'], 1),
                (nmpc.controller.rate[t0,'A'], 1),
                (nmpc.controller.rate[t0,'B'], 1),
                (nmpc.controller.flow_out[t0], 1),
                (nmpc.controller.flow_in[t0], 1),
                ]
        nmpc.add_setpoint_to_controller(objective_weight_override=override)
        nmpc.constrain_control_inputs_piecewise_constant()

        nmpc.initialize_control_problem(
                control_init_option=ControlInitOption.FROM_INITIAL_CONDITIONS)
        nmpc.initialize_control_problem(
                control_init_option=ControlInitOption.BY_TIME_ELEMENT)
        with pytest.raises(RuntimeError):
            nmpc.initialize_control_problem(
                    control_init_option=ControlInitOption.FROM_PREVIOUS)

    @pytest.mark.unit
    def test_initialize_by_solving_elements(self):
        # Make nmpc
        # add setpoint to controller
        # add pwc_constraints
        # call initialize_by_solving_elements
        # assert that values are as expected.
        nmpc = self.make_nmpc()
        time = nmpc.controller_time
        t0 = time.first()
        tl = time.last()
        controller = nmpc.controller
        namespace = getattr(controller, nmpc.namespace_name)
        setpoint = [
                (nmpc.controller.flow_in[t0], 3.0),
                ]
        # Note: without this initialization, the setpoint arrives at a
        # local optimum with inlet flow ~= 0.
        nmpc.controller.flow_in[:].set_value(3.0)
        initialize_t0(nmpc.controller)
        copy_values_forward(nmpc.controller)
        nmpc.calculate_full_state_setpoint(setpoint, outlvl=idaeslog.DEBUG)
        override = [
                (nmpc.controller.conc[t0,'A'], 1),
                (nmpc.controller.conc[t0,'B'], 1),
                (nmpc.controller.rate[t0,'A'], 1),
                (nmpc.controller.rate[t0,'B'], 1),
                (nmpc.controller.flow_out[t0], 1),
                (nmpc.controller.flow_in[t0], 1),
                ]
        nmpc.add_setpoint_to_controller(objective_weight_override=override)
        nmpc.constrain_control_inputs_piecewise_constant()
        nmpc.controller.flow_in[:].set_value(2.0)
        nmpc.initialize_by_solving_elements(
                controller,
                time,
                input_type=ElementInitializationInputOption.INITIAL,
                )
        input_vars = namespace.input_vars
        diff_vars = namespace.diff_vars
        deriv_vars = namespace.deriv_vars
        assert input_vars[0][tl].value == 2.0
        assert diff_vars[0][tl].value == pytest.approx(3.185595567867036)
        assert diff_vars[1][tl].value == pytest.approx(1.1532474073395755)
        assert deriv_vars[0][tl].value == pytest.approx(0.44321329639889284)
        assert deriv_vars[1][tl].value == pytest.approx(0.8791007531878847)

        nmpc.initialize_by_solving_elements(
                controller,
                time,
                input_type=ElementInitializationInputOption.SET_POINT,
                )
        for t in time:
            if t != t0:
                assert input_vars[0][t] == 3.0
        assert diff_vars[0][tl].value == pytest.approx(3.7037037037037037)
        assert diff_vars[1][tl].value == pytest.approx(1.0746896480968502)
        assert deriv_vars[0][tl].value == pytest.approx(0.1851851851851849)
        assert deriv_vars[1][tl].value == pytest.approx(0.47963475941315314)

    @pytest.mark.unit
    def test_initialize_from_previous_sample(self):
        nmpc = self.make_nmpc()
        time = nmpc.controller_time
        t0 = time.first()
        tl = time.last()
        controller = nmpc.controller
        namespace = getattr(controller, nmpc.namespace_name)
        sample_points = namespace.sample_points
        t1 = sample_points[1]
        setpoint = [
                (nmpc.controller.flow_in[t0], 3.0),
                ]
        # Note: without this initialization, the setpoint arrives at a
        # local optimum with inlet flow ~= 0.
        # One way to deal with this pitfall is to add bounds to inlet flow.
        nmpc.controller.flow_in[:].set_value(3.0)
        initialize_t0(nmpc.controller)
        copy_values_forward(nmpc.controller)
        nmpc.calculate_full_state_setpoint(setpoint, outlvl=idaeslog.DEBUG)
        override = [
                (nmpc.controller.conc[t0,'A'], 1),
                (nmpc.controller.conc[t0,'B'], 1),
                (nmpc.controller.rate[t0,'A'], 1),
                (nmpc.controller.rate[t0,'B'], 1),
                (nmpc.controller.flow_out[t0], 1),
                (nmpc.controller.flow_in[t0], 1),
                ]
        nmpc.add_setpoint_to_controller(objective_weight_override=override)
        nmpc.constrain_control_inputs_piecewise_constant()
        nmpc.solve_control_problem()

        diff_vars = namespace.diff_vars
        input_vars = namespace.input_vars
        sample_time = nmpc.sample_time
        n_samples = namespace.samples_per_horizon
        cat_dict = namespace.category_dict
        categories = [
                VariableCategory.DIFFERENTIAL,
                VariableCategory.INPUT,
                ]
        expected = {categ: {s: [{t-sample_time:
            cat_dict[categ][i][t].value for t in time
            if sample_points[s] < t and t <= sample_points[s+1]}
            for i in range(len(cat_dict[categ]))]
            for s in range(1, n_samples)}
            for categ in categories}
        for categ in categories:
            expected[categ][n_samples] = [{t: cat_dict[categ].setpoint[i]
                for t in time if sample_points[n_samples-1] < t
                and t <= sample_points[n_samples]}
                for i in range(len(cat_dict[categ]))]

        nmpc.initialize_from_previous_sample(nmpc.controller)

        for s in range(1, n_samples):
            interval = [t for t in time
                    if sample_points[s-1] < t and t <= sample_points[s]]
            for categ in categories:
                for i, var in enumerate(cat_dict[categ]):
                    for t in interval:
                        assert var[t].value == expected[categ][s][i][t]

    @pytest.mark.unit
    def test_initialize_from_initial_conditions(self):
        # make nmpc
        # add setpoint to controller
        # call initialize
        # assert that values are same as at t0
        nmpc = self.make_nmpc()
        controller = nmpc.controller
        time = nmpc.controller_time
        t0 = time.first()
        namespace = getattr(controller, nmpc.namespace_name)
        sample_points = namespace.sample_points
        n_samples = namespace.samples_per_horizon
        samples = {i: [t for t in time
            if sample_points[i-1] < t and t <= sample_points[i]]
            for i in range(1, n_samples)}
        sample_val_dict = {
                1: 2.5,
                2: 1.5,
                }
        for i in samples:
            for t in samples[i]:
                nmpc.controller.flow_in[t].set_value(sample_val_dict[i])
        initialize_t0(nmpc.controller)
        nmpc.initialize_from_initial_conditions(nmpc.controller)
        categories = [
                VariableCategory.DIFFERENTIAL,
                VariableCategory.ALGEBRAIC,
                VariableCategory.DERIVATIVE,
                ]
        cat_dict = namespace.category_dict
        for categ in categories:
            for var in cat_dict[categ]:
                for t in time:
                    assert var[t].value == var[t0].value
        # Assert inputs were not changed
        for i in samples:
            for t in samples[i]:
                var = nmpc.controller.flow_in[t]
                assert var.value == sample_val_dict[i]

    @pytest.mark.unit
    def test_solve_control_problem(self):
        # make nmpc
        # add setpoint
        # initialize, from ICs probably
        # solve control problem
        # assert values are as expected.
        # Could probably even do this without initialization
        nmpc = self.make_nmpc()
        time = nmpc.controller_time
        t0 = time.first()
        tl = time.last()
        controller = nmpc.controller
        namespace = getattr(controller, nmpc.namespace_name)
        t1 = namespace.sample_points[1]
        setpoint = [
                (nmpc.controller.flow_in[t0], 3.0),
                ]
        # Note: without this initialization, the setpoint arrives at a
        # local optimum with inlet flow ~= 0.
        # One way to deal with this pitfall is to add bounds to inlet flow.
        nmpc.controller.flow_in[:].set_value(3.0)
        initialize_t0(nmpc.controller)
        copy_values_forward(nmpc.controller)
        nmpc.calculate_full_state_setpoint(setpoint, outlvl=idaeslog.DEBUG)
        override = [
                (nmpc.controller.conc[t0,'A'], 1),
                (nmpc.controller.conc[t0,'B'], 1),
                (nmpc.controller.rate[t0,'A'], 1),
                (nmpc.controller.rate[t0,'B'], 1),
                (nmpc.controller.flow_out[t0], 1),
                (nmpc.controller.flow_in[t0], 1),
                ]
        nmpc.add_setpoint_to_controller(objective_weight_override=override)
        nmpc.constrain_control_inputs_piecewise_constant()
        nmpc.solve_control_problem()
        input_vars = namespace.input_vars
        diff_vars = namespace.diff_vars
        assert input_vars[0][t1].value == pytest.approx(3.192261151432352)
        assert input_vars[0][tl].value == pytest.approx(2.9818775607191648)
        assert diff_vars[0][tl].value == pytest.approx(3.7101450012850137)
        assert diff_vars[1][tl].value == pytest.approx(1.0898406680173942)
        assert nmpc.controller_solved

    @pytest.mark.unit
    def test_simulate_plant(self):
        # populate plant with some random inputs
        # simulate
        # assert values are as expected
        # assert 0 dof
        nmpc = self.make_nmpc()
        time = nmpc.plant_time
        namespace = getattr(nmpc.plant, nmpc.namespace_name)
        sample_points = namespace.sample_points
        t1 = sample_points[1]
        n_samples = namespace.samples_per_horizon
        samples = {i: [t for t in time
            if sample_points[i-1] < t and t <= sample_points[i]]
            for i in range(1, n_samples)}
        for t in samples[1]:
            nmpc.plant.flow_in[t].set_value(2.5)
        nmpc.simulate_plant(t_start=nmpc.plant_time.first())
        assert degrees_of_freedom(nmpc.plant) == 0
        input_vars = namespace.input_vars
        diff_vars = namespace.diff_vars
        assert input_vars[0][t1].value == 2.5
        assert diff_vars[0][t1].value == pytest.approx(3.0155642023346307)
        assert diff_vars[1][t1].value == pytest.approx(0.5914009717947231)

    @pytest.mark.unit
    def test_calculate_error_between_states(self):
        # make nmpc
        # artificially change values
        # calculate error.
        nmpc = self.make_nmpc()
        initialize_t0(nmpc.controller)
        copy_values_forward(nmpc.controller)
        initialize_t0(nmpc.controller)
        copy_values_forward(nmpc.controller)

        nmpc.controller.conc[1, 'A'].set_value(5)
        nmpc.controller.conc[1, 'B'].set_value(5)
        nmpc.plant.conc[1, 'A'].set_value(3)
        nmpc.plant.conc[1, 'B'].set_value(3)
        Q_matrix = [1,1]
        error = nmpc.calculate_error_between_states(
                nmpc.controller,
                nmpc.plant,
                1,
                1,
                Q_matrix=Q_matrix,
                )
        assert error == 1*2**2 + 1*2**2


import pandas as pd
import numpy as np
import os
from typing import Tuple, Dict

from buld.utils import format_col_date
from data.features import ProviderDateFormat
from data.features.features import Features

class StaticDataProvider():
    _current_index = 0

    def __init__(self
                 , df       : pd.DataFrame = None
                 , csv_data_path    : str  = None
                 , do_prepare_data: bool = True
                 #, columns_map:Dict = None
                 , features_to_add ='none'
                 , **kwargs):

        self.kwargs = kwargs

        if df is not None:
            self.df = df

        elif csv_data_path is not None:
            if not os.path.isfile(csv_data_path):
                raise ValueError(
                    f'Error:  csv_data_path={csv_data_path} of StaticDataProvider, file could not be found.')
            self.df = pd.read_csv(csv_data_path)
            #features_to_add = 'none' # none(12) all(288)
            fetures = Features()
            self.df  = fetures.add_features(features_to_add, self.df)

            #formatted = reduce_mem_usage        (formatted)
            #self.print_is_stationary(self.df)
            #print(f'prepared_data={self.df}\ndescribe=\n{self.df.describe()}')
            #self.plot_stats()

        else:
            raise ValueError(
                'Error: StaticDataProvider requires either a "data_frame" or "csv_data_path argument".')

        if do_prepare_data:
            #self.columns = self.df.columns
            #self.df = self.data_prepare(self.df)
            self.df = format_col_date(self.df)
            #self.df = self._sort_by_date      (self.df )
            if isinstance(self.df,  pd.DataFrame):
                d = csv_data_path.replace('.csv', '_with_features.csv')
                self.df.to_csv(d, index=False )
                self.logger.info(f'saved file {d}')

        print(f'(n_samples, n_features) = {self.df.shape}')

        self.columns = self.df.columns

    @staticmethod
    def from_prepared(df: pd.DataFrame, date_format: ProviderDateFormat, **kwargs):
        return StaticDataProvider(date_format=date_format, df=df, csv_data_path=None, do_prepare_data=False, **kwargs)

    def split_data_train_test(self, train_split_percentage: float = 0.8) :
        len_train = int(train_split_percentage * len(self.df))

        train_df = self.df[:len_train].copy()
        test_df  = self.df[len_train:].copy()

        train_provider = StaticDataProvider.from_prepared(df=train_df, date_format=self.date_format, **self.kwargs)
        test_provider  = StaticDataProvider.from_prepared(df=test_df , date_format=self.date_format, **self.kwargs)

        return train_provider, test_provider

    def get_all_historical_obs(self) -> pd.DataFrame:
        return self.df

    def has_next_obs(self) -> bool:
        return self._current_index < len(self.df)

    def reset_obs_index(self) -> int:
        self._current_index = 0

    def next_obs(self) -> pd.DataFrame:
        frame = self.df[self.columns].values[self._current_index]
        frame = pd.DataFrame([frame], columns=self.columns)

        self._current_index += 1

        return frame


import numpy as np
import utils
import os

################################################################################
#
# BaseMask class --> If you have a custom mask, you should inherit from BaseMask
#
################################################################################
class BaseMask(object):
    """BaseMask - Basic functionality to read a mask and filter points. """

    name = ''
    """ Mask name. """

    path = ''
    """ Mask path. """

    data = None
    """ Numpy array containing the mask data. """

    # ------------------------------------------------------------------------ #
    def __init__(self, name = '', path = ''):
        """ Initialize mask structure, and if given a name/path, load data. """

        data = self.load(name, path)

    # ------------------------------------------------------------------------ #
    def load(self, name = None, path = None):
        """ load data from mask, and update name/path if necessary.

            Usage: Mask = BaseMask()
                   Mask.load(name, path)

            Input:
                name - Mask name
                path - Mask path

            Output:
                -NONE- but self.data is updated with the mask data
        """

        if name is not None:
            self.name = name

        if path is not None:
            self.path = path

        # BaseMask assumes we're reading masks from an image type
        file = os.path.join(self.path, self.name)
        if os.path.exists(file):
            self.data = np.asarray(Image.open(file))

    # ------------------------------------------------------------------------ #
    def filter(self, pts2D):
        """ Filter image points based on loaded mask.

        Usage: Mask = BaseMask('mask.png')
               FilteredPts = Mask.filter(pts)

        Input:
            pts - 2-by-N numpy array of 2D points

        Output:
            FilteredPts - 2-by-N numpy array of 2D points. Those that agree
            with the mask (i.e., those points [x, y] s.t. mask[x,y] = True)
            remain the same, while invalid points are zeroed.
        """

        # Find points that are not zero in image space
        idxPts = utils.find( np.logical_and(pts2D[0, :] > 0, pts2D[1,:] > 0) )

        # Get rounded and flattened (1D) pixel indexes for our 2D points
        idxPtsFlat = utils.ravel_index(pts2D[::-1, idxPts].astype(int), \
                                       self.data.shape)

        # Find invalid 2D points by comparing them to the mask
        idxInvalidPts = utils.find( self.data.flat[idxPtsFlat] == 0 )

        # Set invalid points to zero
        pts2D[:, idxPts[idxInvalidPts]] = 0

        return pts2D

################################################################################
#
# MatMask class --> Custom read mask from matlab .mat file
#
################################################################################
class MatMask(BaseMask):
    """MatMask - Read mask from Matlab and filter points. """

    # ------------------------------------------------------------------------ #
    def load(self, name = None, path = None):
        """ load data from mask, and update name/path if necessary. """

        if name is not None:
            self.name = name

        if path is not None:
            self.path = path

        # BaseMask assumes we're reading masks from an image type
        file = os.path.join(self.path, self.name)
        if os.path.exists(file):
            self.data = utils.load(file, 'mask', Matlab_compatible = True)

################################################################################
#
# ImgMask class
#
################################################################################

# ImgMask is the same as BaseClass so far...
ImgMask = BaseMask

def MaskFromType(type):
    """ Mask selector from mask type. Returns most suitable MaskReader class for
    your needs given the image type.

    Usage: MaskReader = MaskFromType(type)

    Input:
        type - mask file extension. Accepted types are 'jpg', 'png', 'bmp' and
               'mat'.
    Output:
        MaskReader - Mask reader class associated with your mask type.
        Currently, it is either ImgMask or MatMask.
    """

    # in case we enter something that is not a type, keep the last three chars
    type = type[-3:]

    if type in ['jpg', 'png', 'bmp']:
        return ImgMask

    elif type in ['mat']:
        return MatMask


import time
import csv

def response_text(openai_resp):
    return openai_resp['choices'][0]['message']['content']

from gptcache import cache
from gptcache.adapter import openai
from gptcache.adapter import qwen
from gptcache.embedding.qianwenEmbedding import QianWenEmbedding
from gptcache.manager import CacheBase, VectorBase, get_data_manager
from gptcache.similarity_evaluation.distance import SearchDistanceEvaluation
import os

os.environ["OPENAI_API_KEY"] = ""
print("Cache loading.....")

qianWen = QianWenEmbedding()
# rocksdb、sqlite、mysql 可选
data_manager = get_data_manager(CacheBase("sqlite"), VectorBase("faiss", dimension=qianWen.dimension))
cache.init(
    embedding_func=qianWen.to_embeddings,  # 千问的embedding
    data_manager=data_manager,
    similarity_evaluation=SearchDistanceEvaluation(),
)
cache.set_openai_key()

# 该函数用于加载csv数据集进行测试
def getQuestions():
    data_list = []
    csv_file_path = 'train.csv'

    # Open the CSV file in read mode
    with open(csv_file_path, 'r', encoding='utf-8', newline='') as csvfile:
        # Create a CSV reader object
        reader = csv.reader(csvfile)
        # Skip the header row (first row)
        next(reader)
        # Iterate over each row and store the values of the second and third column in the list
        for row in reader:
            column2_data, column3_data, is_duplicate = row[3], row[4], int(row[5])
            data_list.append((column2_data, column3_data, is_duplicate))
    print(data_list)
    return data_list

# questions = getQuestions()
# print(questions)
questions = [
    "你知道上海吗?",
    "你知道上海吗?",
]

start_time = time.time()
for question in questions:
    response = qwen.ChatCompletion.create(
        model='qwen-plus-internal-v1',
        messages=[
            {
                'role': 'user',
                'content': question
            }
        ],
    )
    print(f'Question: {question}')
    print("Time consuming: {:.2f}s".format(time.time() - start_time))
    print(f'Answer: {(response)}\n')

# countLine=0
# q1Hit=0
# q2Hit=0
# q1q2markHit=0
# q1q2markHitActuallt=0
# for question in questions:
#     countLine=countLine+1
#     for i in range(2):
#         print(i)
#         if i==0:
#             print()
#             print()
#             print()
#             start_time = time.time()
#             response = qwen.ChatCompletion.create(
#                 model='gpt-3.5-turbo',
#                 messages=[
#                     {
#                         'role': 'user',
#                         'content': question[i]
#                     }
#                 ],
#             )
#             print(f'Question: {question}')
#             print("Time consuming: {:.2f}s".format(time.time() - start_time))
#             if isinstance(response, dict):
#                 q1Hit=q1Hit+1
#             print(f'Answer: {(response)}\n')
#             print()
#             print()
#             print()
#         else:
#             print()
#             print()
#             print()
#             start_time = time.time()
#             response = qwen.ChatCompletion.create(
#                 model='gpt-3.5-turbo',
#                 messages=[
#                     {
#                         'role': 'user',
#                         'content': question[i]
#                     }
#                 ],
#             )
#             print(f'Question: {question}')
#             print("Time consuming: {:.2f}s".format(time.time() - start_time))
#             if question[2] == 1:
#                 q1q2markHitActuallt = q1q2markHitActuallt + 1
#             if isinstance(response, dict):
#                 q2Hit=q2Hit+1
#                 if question[2]==1:
#                     q1q2markHit=q1q2markHit+1
#             print(f'Answer: {(response)}\n')
#             print()
#             print()
#             print()
#     if countLine>=1000:
#         break
# print("countLine:",countLine)
# print("q1Hit:",q1Hit)
# print("q2Hit:",q2Hit)
# print("q1q2markHit:",q1q2markHit)
# print("q1q2markHitActuallt:",q1q2markHitActuallt)


# # import datetime
from plyer import notification

import pync
import time
import os
from pync import Notifier
import datetime

operatingsystem = input(
    "PRESS W if you are using Windows and U if your using Apple, linux or Unix based operating system\n\n")

today = datetime.datetime.now().strftime("%H")
minutes = datetime.datetime.now().strftime("%M")
seconds = datetime.datetime.now().strftime("%S")
Year = datetime.datetime.now().strftime("%y")

print("The current time is "+f"{int(today)}" +
      ":"+minutes + ":"+seconds + "\n")
# print(Year)
water = input("Enter the when to remind you to drink water after every:\n")
print(f"You will be reminded after {water} hours to drink water\n")
waterr = str(int(water) + int(today))

# print(int(waterr))
# if(today == waterr):
#     print("omsairam")
d = ''
if(int(waterr) == 25) or (int(waterr) > 25):
    d = int(waterr) - 24
    waterr == d

# print(waterr)

if(int(waterr) == int(today)):

    if(operatingsystem == "U"):
        if __name__ == "__main__":
            pync.notify('It is so important to stay hydrated during our day, not only to replenish the water that we lose throughout the day, but drinking more water can aid in weight loss, manage diabetes, essential in pregnancy and also keeps your teeth, skin and gums healthy.',
                        title=f"Time to drink water its already {today}:{minutes}:{seconds} ",
                        activate='com.apple.Safari',
                        subtitle="Sip before every meal.",
                        open='http://github.com/',
                        execute='say "ok but do not forget to drink water"',

                        icon='pngfuel.com-19.png',
                        timeout=1
                        )
    elif(operatingsystem == "W"):
        if __name__ == "__main__":
            notification.notify(
                title=f"Time to drink water its already {today}:{minutes}:{seconds} ",
                message='It is so important to stay hydrated during our day, not only to replenish the water that we lose throughout the day, but drinking more water can aid in weight loss, manage diabetes, essential in pregnancy and also keeps your teeth, skin and gums healthy.',
                app_icon='pngfuel.com-19.png',
                timeout=3
            )

elif(int(waterr) > int(today)):
    time.sleep(int(waterr)*60*60)
    if(operatingsystem == "U"):
        if __name__ == "__main__":
            pync.notify('It is so important to stay hydrated during our day, not only to replenish the water that we lose throughout the day, but drinking more water can aid in weight loss, manage diabetes, essential in pregnancy and also keeps your teeth, skin and gums healthy.',
                        title=f"Time to drink water its already {today}:{minutes}:{seconds} ",
                        activate='com.apple.Safari',
                        subtitle="Sip before every meal.",
                        open='http://github.com/',
                        execute='say "ok but do not forget to drink water"',

                        icon='pngfuel.com-19.png',
                        timeout=1
                        )

    elif(operatingsystem == "W"):
        time.sleep(int(water)*60*60)
        if __name__ == "__main__":
            notification.notify(
                title=f"Time to drink water its already {today}:{minutes}:{seconds} ",
                message='It is so important to stay hydrated during our day, not only to replenish the water that we lose throughout the day, but drinking more water can aid in weight loss, manage diabetes, essential in pregnancy and also keeps your teeth, skin and gums healthy.',
                app_icon='pngfuel.com-19.png',
                timeout=3
            )

            # Random notes :)

    # if __name__ == "__main__":
    #     pync.notify('Hello World',
    #                 title="Omsai",
    #                 subtitle="hello this is developer king pro",

    #                 icon='pngfuel.com-19.png',
    #                 )

# pync.notify('Hello World', title='Python')
# pync.notify('Hello World', group=os.getpid())
# pync.notify('Hello World', activate='com.apple.Safari')
# pync.notify('Hello World', open='http://github.com/')
# pync.notify('Hello World', execute='say "OMG"')

'''
Notifier.remove(os.getpid())

Notifier.list(os.getpid())
'''
# d = input("enter the number\n")
# # print(type
# #       (d))
# numm = int(d)
# # print(type(numm))
# one = (numm * (numm + 1))
# print(one/2)
# a = str(0)
# print(a)

# # today = datetime.datetime.now().strftime("%d-%m-%y")
# # Year = datetime.datetime.now().strftime("%y")
# # print(today)
# # print(Year)

# # if __name__ == "__main__":
# #     notification.notify(
# #         title="Time to Have ",
# #         message="its better to have  than to seleep",
# #         app_icon="/Users/tarushj.reddy/Desktop/Water/pngfuel.com-19.png",
# #         timeout=3
# #     )

# '''this is an example system '''
# # import os

# # def notify(title, text):
# #     os.system("""
# #             osascript -e 'display notification "{Thsis jcsdojcosd}" with title "{}" sound name
# #             {}'""".format(text, title))

# # notify("Title", "Heres an alert")


def draw_circle(event,x,y,flags,param):
    global n
    architectural_points = param[0]
    if event == cv.EVENT_LBUTTONDOWN:
        cv.circle(param[1],(x,y),5,(255,0,0),-1)
        architectural_points[n] = (x,y)
        n += 1
cv.namedWindow('Image', cv.WINDOW_AUTOSIZE)
param = [architectural_points, architectural_image]
cv.setMouseCallback('Image',draw_circle, param)
while(1):
    cv.imshow('Image', architectural_image)
    if n == number_of_points:
        break
    if cv.waitKey(20) & 0xFF == 27:
        break
flag_points = np.array([[0, 0], [flag_image.shape[1], 0], [flag_image.shape[1], flag_image.shape[0]], [0, flag_image.shape[0]]], dtype=np.float32)
homography_matrix, _ = cv.findHomography(flag_points, architectural_points)
flag_warped = cv.warpPerspective(flag_image, homography_matrix, (architectural_image.shape[1], architectural_image.shape[0]))
blended_image = cv.addWeighted(architectural_image, 1, flag_warped, 0.7, 0)


#! /usr/bin/env python

'''
Issue Extension for Python-Markdown
==================================

Replace #1234 with link to issue 1234.

Usage
-----

    >>> import markdown
    >>> src = 'Please see issue #1234.'
    >>> html = markdown.markdown(src, ['tracker.mdx.mdx_issue'])
    >>> print(html)

Please see issue #1234.

    >>> html = markdown.markdown(src, ['tracker.mdx.mdx_issue'], {'tracker.mdx.mdx_issue': {'absolute_url': True}})
    >>> print(html)

Please see issue #1234.

Dependencies
------------

* [Markdown 2.0+](http://www.freewisdom.org/projects/python-markdown/)
'''

import markdown
from markdown.inlinepatterns import SubstituteTagPattern
from markdown.inlinepatterns import Pattern
from markdown.util import etree

from django.urls import reverse
from django.conf import settings

ISSUE_RE = r'#([0-9]+)'

class IssuePattern(Pattern):

    def __init__(self, project_name, absolute_url=False):
        super(IssuePattern, self).__init__(ISSUE_RE)
        self.project_name = project_name
        self.absolute_url = absolute_url

    def handleMatch(self, m):
        el = etree.Element('a')
        issue_id = m.group(2)
        url = reverse('show-issue', args=[self.project_name, issue_id])
        if self.absolute_url:
            url = settings.BASE_URL + url
        el.set('href', url)
        el.text = '#{issue_id}'.format(issue_id=issue_id)
        return el

class IssueExtension(markdown.extensions.Extension):

    def __init__(self, **kwargs):
        self.config = {
            'project_name': ['project', 'Project name'],
            'absolute_url': [False, 'Use absolute URL'],
        }
        super(IssueExtension, self).__init__(**kwargs)

    def extendMarkdown(self, md, md_globals):
        pattern = IssuePattern(self.getConfig('project_name'), self.getConfig('absolute_url'))
        md.inlinePatterns.add('issue', pattern, '<not_strong')

def makeExtension(**configs):
    return IssueExtension(configs=configs)


from django import forms

from ...account.models import User

class CustomerForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        self.user = kwargs.pop('user', None)
        super().__init__(*args, **kwargs)
        # disable 'is_active' checkbox if user edits his own account
        if self.user == self.instance:
            self.fields['is_active'].disabled = True

    class Meta:
        model = User
        fields = ['email', 'is_active']


import sys
input = sys.stdin.readline

#최대이익
# dp
N = int(input())
lst = [list(map(int,input().split())) for i in range(N)]
dp = [0]*(N+1)

# d[i] = i일이 끝났을 때 얻는 가치
for i in range(N):
    T = lst[i][0]
    P = lst[i][1]
    # 7일까지라 N+1
    for j in range(i+T,N+1):
        if dp[j] < dp[i]+P:
            dp[j] = dp[i]+P

print(dp[N])


from django.shortcuts import render, HttpResponse
from chats.audio.audioEncryption import audioEncrypt
from login.models import chatUsers
from django.http import HttpResponseRedirect
from chats.audio.keyGeneration import keyGeneration
from chats.models import KeyRoom
from chats.models import Chats
from kellanb_cryptography import aes
import json

# Create your views here.

def index(request, userId):
    if request.session.has_key("user") == False:
        return HttpResponseRedirect("/")
    context = {}
    context["User"] = chatUsers.objects.exclude(id=int(userId))
    context["Id"] = userId
    # return HttpResponse("This is Response")
    return render(request, "chats/chat.html", context)

def audio(request):
    if request.method == "POST":
        if request.FILES.get("myAudio", False):
            group_id = request.POST.get("id")
            handleUploadFile(request.FILES["myAudio"])
            keyObject = KeyRoom.objects.filter(groupId=group_id)
            if keyObject.exists:

                path = audioEncrypt(
                    keyObject[0].key)
            else:
                Key = keyGeneration()
                KeyRoom.objects.create(groupId=group_id, key=Key)
                path = audioEncrypt(Key)
            return HttpResponse(path)
        return HttpResponse("NO FILE FOUND")

def handleUploadFile(f):
    with open("chats/audio/" + f.name, "wb+") as destination:
        for chunk in f.chunks():
            destination.write(chunk)

def chats(request, groupId):
    chats = Chats.objects.filter(groupId=groupId)
    if chats.exists:
        data = list(chats.values())
        keyObject = KeyRoom.objects.filter(groupId=groupId)[0].key
        for i in range(len(data)):
            if data[i]['Audio'] == None:
                data[i]['EncryptedText'] = aes.decrypt_aes(
                    data[i]['EncryptedText'], keyObject)
        return HttpResponse(json.dumps(data))


from django.urls import path, include
from . import views
from rest_framework import routers

router = routers.DefaultRouter()
router.register('customer', views.CustomerView)
router.register('person', views.person)

urlpatterns = [

  path('class/', include(router.urls)),

  # Api for .Customer model using function INDIVIDUALLY
  path('customer_listind/', views.Customer_list_seprately),
  path('customer_add/', views.add),
  path('customer_update/<int:id>/', views.update),
  path('customer_delete/<int:id>/', views.delete),

# Api for .Customer model using function COMBINED
  path('customer/', views.Customer_list),
  path('customer/<int:id>/', views.update_delete),

  # Api for Crud.Person model using function COMBINED
  path('person_list/', views.person_list_function),
  path('person_list/<int:id>/', views.person_update_delete),

  ]


import pytest
from flask_sqlalchemy import SQLAlchemy

@pytest.fixture
def uses_sql_database(_db: SQLAlchemy) -> None:
    _db.session.commit()
    _db.drop_all()
    _db.create_all()

@pytest.fixture
def minimal_patient() -> dict:
    return {
        "accessibility_considerations": [],
        "allowed_to_text": True,
        "dh_products": [
            {
                "opened_date": "2019-04-29",
                "product_name": "GDM",
            }
        ],
        "dob": "1992-04-23",
        "email_address": "",
        "ethnicity": "185988007",
        "first_name": "Diane",
        "highest_education_level": "426769009",
        "hospital_number": "147777799",
        "last_name": "Smith",
        "locations": ["location_uuid_1"],
        "other_notes": "",
        "personal_addresses": [
            {
                "address_line_1": "School House Stony Bridge Park",
                "address_line_2": "",
                "address_line_3": "",
                "address_line_4": "",
                "lived_from": "2013-12-31",
                "locality": "Oxford",
                "postcode": "OX5 3NA",
                "region": "Oxfordshire",
            }
        ],
        "phone_number": "07123456789",
        "record": {},
        "sex": "248152002",
        "height_in_mm": 1666,
        "weight_in_g": 68800,
    }


class Node:
    def __init__(self, data=None):
        self.data = data
        self.left = None
        self.right = None

def insert(self,d):
    if self.data == d:
        return
    elif d < self.data:
        if self.left:
            return insert(self.left,d)
        else:
            self.left = Node(d)
    else:
        if self.right:
            return insert(self.right,d)
        else:
            self.right = Node(d)

lst = [12, 7, 16, 5, 8, 14 ]
root = None
if lst is not None:
    root = Node(lst[0])
    for i in range(1, len(lst)):
        insert(root,lst[i])

print()


# CH4 Implementation 115p <2> 왕실의 나이트

if __name__=='__main__':

    move = input('나이트의 좌표(열, 행):')

    y = ord(move[0])-96
    x = int(move[1])

    print('x: {}, y: {}'.format(x, y))

    cases = [(2, 1), (2, -1), (-2, 1), (-2, -1), (1, 2), (1, -2), (-1, 2), (-1, -2)]

    count = 0
    for case in cases:
        temp_x, temp_y = x+case[0], y+case[1]

        if temp_x <= 8 and temp_x >=1 and temp_y <=8 and temp_y >=1:
            print(case, temp_x, temp_y)
            count+=1

    print('count: {}'.format(count))


def sumColumn(m, columnIndex):
    matrix = []
    numberOfRows = 3
    numberOfColumns = 4
    for row in range(numberOfRows):
        matrix.append([])
        for column in range(numberOfColumns):
            element = input("Enter 3-by-4 matrix row for row 0 :")
            # matrix[row].append(element)
            items = element.split()
            row = [eval(x) for x in items]
        print(matrix)
        return matrix


import cv2
import torch
import numpy as np
import pandas as pd
from torch.utils.data import Sampler, BatchSampler

# https://www.kaggle.com/gaborfodor/greyscale-mobilenet-lb-0-892
BASE_SIZE = 256
def list2drawing(raw_strokes, size=256, lw=6, time_color=False):
    img = np.zeros((BASE_SIZE, BASE_SIZE), np.uint8)
    for t, stroke in enumerate(raw_strokes):
        for i in range(len(stroke[0]) - 1):
            color = 255 - min(t, 10) * 13 if time_color else 255
            _ = cv2.line(img, (stroke[0][i], stroke[1][i]),
                         (stroke[0][i + 1], stroke[1][i + 1]), color, lw)
    if size != BASE_SIZE:
        return cv2.resize(img, (size, size), interpolation=cv2.INTER_LINEAR)
    else:
        return img

def drawing2tensor(drawing):
    rgb = cv2.cvtColor(drawing,cv2.COLOR_GRAY2RGB)
    rgb = rgb.transpose(2,0,1).astype(np.float32)
    return torch.from_numpy(rgb)

def channels2tensor(ch1, ch2, ch3):
    rgb = np.stack((ch1, ch2, ch3)).astype(np.float32)
    return torch.from_numpy(rgb)

# https://www.tensorflow.org/tutorials/sequences/recurrent_quickdraw
def drawing2seq(inkarray):
    stroke_lengths = [len(stroke[0]) for stroke in inkarray]
    total_points = sum(stroke_lengths)
    np_ink = np.zeros((total_points, 3), dtype=np.float32)
    current_t = 0
    if not inkarray:
        print("Empty inkarray")
        return None, None
    for stroke in inkarray:
        if len(stroke[0]) != len(stroke[1]):
            print("Inconsistent number of x and y coordinates.")
            return None, None
        for i in [0, 1]:
            np_ink[current_t:(current_t + len(stroke[0])), i] = stroke[i]
        current_t += len(stroke[0])
        np_ink[current_t - 1, 2] = 1    # stroke_end
    # Preprocessing.
    # 1. Size normalization.
    lower = np.min(np_ink[:, 0:2], axis=0)
    upper = np.max(np_ink[:, 0:2], axis=0)
    scale = upper - lower
    scale[scale == 0] = 1
    np_ink[:, 0:2] = (np_ink[:, 0:2] - lower) / scale
    # 2. Compute deltas.
    np_ink[1:, 0:2] -= np_ink[0:-1, 0:2]
    np_ink = np_ink[1:, :]
    return np_ink

# https://github.com/benhamner/Metrics/blob/master/Python/ml_metrics/average_precision.py
def apk(actual, predicted, k=10):
    if len(predicted)>k:
        predicted = predicted[:k]

    score = 0.0
    num_hits = 0.0

    for i,p in enumerate(predicted):
        if p in actual and p not in predicted[:i]:
            num_hits += 1.0
            score += num_hits / (i+1.0)

    if not actual:
        return 0.0

    return score / min(len(actual), k)

def mapk(actual, predicted, k=10):
    return np.mean([apk(a,p,k) for a,p in zip(actual, predicted)])

def map3(preds, targs):
    predicted_idxs = preds.sort(descending=True)[1]
    top_3 = predicted_idxs[:, :3]
    res = mapk([[t] for t in targs.cpu().numpy()], top_3.cpu().numpy(), 3)
    return torch.tensor(res)

def top_3_preds(preds): return np.argsort(preds.numpy())[:, ::-1][:, :3]

def top_3_pred_labels(preds, classes):
    top_3 = top_3_preds(preds)
    labels = []
    for i in range(top_3.shape[0]):
        labels.append(' '.join([classes[idx] for idx in top_3[i]]))
    return labels

def chunks(l, n):
    """Yield successive n-sized chunks from l."""
    for i in range(0, len(l), n):
        yield l[i:i + n]

class RandomSamplerWithEpochSize(Sampler):
    """Yields epochs of specified sizes. Iterates over all examples in a data_source in random
    order. Ensures (nearly) all examples have been trained on before beginning the next iteration
    over the data_source - drops the last epoch that would likely be smaller than epoch_size.
    """
    def __init__(self, data_source, epoch_size):
        self.n = len(data_source)
        self.epoch_size = epoch_size
        self._epochs = []
    def __iter__(self):
        return iter(self.next_epoch)
    @property
    def next_epoch(self):
        if len(self._epochs) == 0: self.generate_epochs()
        return self._epochs.pop()
    def generate_epochs(self):
        idxs = [i for i in range(self.n)]
        np.random.shuffle(idxs)
        self._epochs = list(chunks(idxs, self.epoch_size))[:-1]
    def __len__(self):
        return self.epoch_size

def create_submission(test_preds, test_dl, name, classes):
    key_ids = [path.stem for path in test_dl.dataset.x.items]
    labels = top_3_pred_labels(test_preds, classes)
    sub = pd.DataFrame({'key_id': key_ids, 'word': labels})
    sub.to_csv(f'subs/{name}.csv.gz', index=False, compression='gzip')