import time
from weapons import dagger  # Function for choosing a weapon.
from weapons import stick  # Function for choosing a weapon.
from weapons import axe  # Function for choosing a weapon.
import sys

weapon1 = ""
weapon2 = ""
weapon3 = ""

def intro():

    play = "Y"

    while play == "Y" not in "N":  # Loop for restarting the game.
        print("You wake up in a dark room...")
        time.sleep(2)
        print("A stranger appears before you...")
        time.sleep(1)
        player = input("Stranger: What is your name?: ")
        time.sleep(1)
        print("Stranger: Hello there", player + "!")
        time.sleep(1)
        print("Stranger: The world you once knew is no more...")
        time.sleep(2)
        print("Stranger: The living dead now walks the surface of the earth...")
        time.sleep(2)
        print("Stranger: If you want to survive out there, you will need one of these...")
        print("")
        time.sleep(2)
        print("The stranger gives you an option to choose from three different weapons:\n"
              "A: A dagger.\n"
              "B: A stick.\n"
              "C: An axe.")
        chooseweapon = input("Please choose a weapon: ")

        weapon1 = dagger()
        weapon2 = stick()
        weapon3 = axe()

        while chooseweapon != "A" and chooseweapon != "B" and chooseweapon != "C":  # Input validation
            chooseweapon = input("Please choose a weapon: ")

        if chooseweapon == "A":
            print("You have been given a " + weapon1 + ".")
        elif chooseweapon == "B":
            print("You have been given a " + weapon2 + ".")
        elif chooseweapon == "C":
            print("You have been given an " + weapon3 + ".")

        time.sleep(2)
        print("Stranger: Great! Now you are set...")
        time.sleep(2)
        print("Stranger: The dead ones are about to overrun this place, we must escape! ")
        time.sleep(2)
        print("You have two choices to exit this building.")
        print("Do you want to:")
        print("A: Exit through the window.")
        print("B: Climb to the rooftop.")
        choice = input("Enter your choice: ")

        while choice != "A" and choice != "B" and choice != "C":  # Another input validation
            choice = input("You can't go there. Please try a valid exit: ")

        # Choice A
        if choice == "A" and chooseweapon == "A":
            print("You find three zombies outside the window, you manage to take down two of them but the third one\n"
                  "bit your neck.")
            time.sleep(1)
            print("You died, " + player + ".")
            play = input("Do you wish to restart? Y/N: ")
            while play != "Y" and play != "N":
                play = input("Invalid choice, please type Y or N: ")
            while play == "N":
                time.sleep(1)
                print("Okay, Goodbye " + player + "!")
                time.sleep(3)
                sys.exit()
        elif choice == "A" and chooseweapon == "B":
            print("You find three zombies outside the window, your stick is completely useless and you quickly\n"
                  " get overwhelmed.")
            print("You died, " + player + ".")
            play = input("Do you wish to restart? Y/N: ")
            while play != "Y" and play != "N":
                play = input("Invalid choice, please type Y or N: ")
            while play == "N":
                time.sleep(1)
                print("Okay, Goodbye " + player + "!")
                time.sleep(3)
                sys.exit()
        elif choice == "A" and chooseweapon == "C":
            print("You find three zombies outside the window and manage to take all of them down\n"
                  " with your axe.")
            time.sleep(2)
            print("You got out of the building, now the real journey begins.")
            print("To be continued...")
            play = input("Do you wish to restart? Y/N: ")
            while play != "Y" and play != "N":
                play = input("Invalid choice, please type Y or N: ")
            while play == "N":
                time.sleep(1)
                print("Okay, Goodbye " + player + "!")
                time.sleep(3)
                sys.exit()

        # Choice B
        elif choice == "B" and chooseweapon == "A":
            print("You climb the ladder and arrive on the rooftop.")
            print("You get spotted by a military helicopter and quickly conceal your dagger.")
            print("They let you aboard.")
            print("To be continued...")
            play = input("Do you wish to restart? Y/N: ")
            while play != "Y" and play != "N":
                play = input("Invalid choice, please type Y or N: ")
            while play == "N":
                time.sleep(1)
                print("Okay, Goodbye " + player + "!")
                time.sleep(3)
                sys.exit()
        elif choice == "B" and chooseweapon == "B":
            print("You climb the ladder and arrive on the rooftop.")
            print("You get spotted by a military helicopter.")
            print("They see you as a threat and start shooting at you.")
            print("You died, " + player + ".")
            play = input("Do you wish to restart? Y/N: ")
            while play != "Y" and play != "N":
                play = input("Invalid choice, please type Y or N: ")
            while play == "N":
                time.sleep(1)
                print("Okay, Goodbye " + player + "!")
                time.sleep(3)
                sys.exit()
        elif choice == "B" and chooseweapon == "C":
            print("You climb the ladder and arrive on the rooftop.")
            print("You get spotted by a military helicopter.")
            print("They see you as a threat and start shooting at you.")
            print("You died, " + player + ".")
            play = input("Do you wish to restart? Y/N: ")
            while play != "Y" and play != "N":
                play = input("Invalid choice, please type Y or N: ")
            while play == "N":
                time.sleep(1)
                print("Okay, Goodbye " + player + "!")
                time.sleep(3)
                sys.exit()
intro()


import json

from PySide import QtGui, QtCore

from .modes_base import GridViewMouseModeBase, mouse_mode_filtered

class SelectItemsMode(GridViewMouseModeBase):
    def __init__(self, *args, **kargs):
        super().__init__(*args, **kargs)

        self._undo_group_scene = None
        self._drag_start_pos = None

    def mouse_enter(self):
        super().mouse_enter()
        self.setDragMode(QtGui.QGraphicsView.RubberBandDrag)
        self.scene().setSelectionAllowed(True)
        self.scene().set_active(False)

    def mouse_leave(self):
        super().mouse_leave()

        self.setDragMode(QtGui.QGraphicsView.NoDrag)
        self.scene().setSelectionAllowed(False)
        self.scene().set_active(True)

        if self._undo_group_scene is not None:
            self._undo_group_scene.endUndoRedoGroup()
            self._undo_group_scene = None

    def _mask_drag_mode(self, func, mouse_event):
        """
        disables rubber band mode when the left mouse button is not pressed,
        then calls func(mouse_event)
        """
        drag_mode = self.dragMode()
        try:
            if drag_mode is QtGui.QGraphicsView.RubberBandDrag and \
                    not mouse_event.button() & QtCore.Qt.LeftButton:
                # disable rubber band drag
                self.setDragMode(QtGui.QGraphicsView.NoDrag)
            return func(mouse_event)
        finally:
            # restore old drag mode
            self.setDragMode(drag_mode)

    @mouse_mode_filtered
    def mousePressEvent(self, event):
        # call parent with masked drag mode
        self._mask_drag_mode(super().mousePressEvent, event)

        if event.button() == QtCore.Qt.LeftButton:
            self._undo_group_scene = self.scene()
            self._undo_group_scene.beginUndoGroup()

            self._drag_start_pos = event.pos()

    @mouse_mode_filtered
    def mouseMoveEvent(self, event):
        # TODO: merge code with the one in library_view

        is_draged = False

        if event.buttons() & QtCore.Qt.LeftButton and \
                (event.pos() - self._drag_start_pos).manhattanLength() >= \
                QtGui.QApplication.startDragDistance() and False:

            # get selected items & start drag&drop
            gpos = self.mapToScene(self._drag_start_pos)
            # TODO: create method instead of accessing _selection_item
            gpos_items = self.scene().items(gpos)
            sel_items = self.scene().selectedItems()
            if len(sel_items) > 0 and \
                    self.scene()._selection_item in gpos_items:

                drag_pos = self.mapToScene(self._drag_start_pos)
                data = {'drag_pos': drag_pos.toTuple(),
                        'items': [item.metadata() for item in sel_items]}

                mimeData = QtCore.QMimeData()
                mimeData.setData('application/x-components',
                                 json.dumps(data))

                drag = QtGui.QDrag(self)
                drag.setMimeData(mimeData)

                # set items temporary
                for item in sel_items:
                    item.set_temporary(True)

                drop_action = drag.exec_(QtCore.Qt.CopyAction |
                                         QtCore.Qt.MoveAction)

                if drop_action == QtCore.Qt.MoveAction:
                    # delete all items
                    for item in sel_items:
                        self.scene().removeItem(item)
                    is_draged = True
                elif drop_action == QtCore.Qt.CopyAction:
                    # unset temporary
                    for item in sel_items:
                        item.set_temporary(False)
                    is_draged = True

                if is_draged:
                    # TODO: refactor
                    self._undo_group_scene.endUndoGroup()
                    self._undo_group_scene = None
                    self._drag_start_pos = None

        if not is_draged:
            super().mouseMoveEvent(event)

    @mouse_mode_filtered
    def mouseDoubleClickEvent(self, event):
        self.mousePressEvent(event)

    @mouse_mode_filtered
    def mouseReleaseEvent(self, event):
        super().mouseReleaseEvent(event)

        if event.button() == QtCore.Qt.LeftButton and \
                self._undo_group_scene is not None:
            self._undo_group_scene.endUndoGroup()
            self._undo_group_scene = None


# -*- coding: utf-8 -*-
import os
import re
import datetime
from bson import ObjectId
import models
import globals
from schematics.serialize import (to_python, to_json, make_safe_python,
                                  make_safe_json, blacklist, whitelist)
from models.extensions import validate, validate_partial, doc_remove_empty_keys, nextEId
from models.logit import logit
from models.typ import Typ
from models._cs import _cs
from utils.nextid import nextId
from utils.slugify import slugify

def preSave(doc, usr):
    response   = {}

    modelClass = getattr(models, doc['_c'])
    # collNam    = modelClass.meta['collection']
    # collNamTmp = collNam + '_tmp'
    # collTmp    = db[collNamTmp]
    # coll       = db[collNam]

    # validate
    errors     = validate_partial(modelClass, doc)

    if errors:
        response['errors'] = errors['errors']
        response['total_errors'] = errors['count']
        return {'response': response, 'status': 400}

    # init model instance
    model      = modelClass(**doc)

    # if there is a vNam class property
    if hasattr(model, 'vNam') and 'dNam' in model._fields:
        model.dNam = model.vNam
        if hasattr(model, 'vNamS') and 'dNamS' in model._fields:
            model.dNamS = model.vNamS

        doc        = doc_remove_empty_keys(to_python(model, allow_none=True))

    # logit update
    doc = logit(usr, doc)
    response['doc'] = doc
    return {'response': response, 'status': 200}
def initDocListTypes(doc, usr):
    '''When posting a doc with listType attributes/fields, they must be initialized with provided data and validated and saved back to the doc for further handling, ie, validation, etc.'''
    attrNams = doc.keys()
    # loop through all doc keys
    for attrNam in attrNams:
        attrVal = doc[attrNam]

        # is it a list
        if type(attrVal) == list:
            attrValList = attrVal

            # loop through all the elements in the list
            for attrValListOffset in range(0, len(attrValList)):
                attrValListItem = attrValList[attrValListOffset]
                attr_c          = attrValListItem['_c']
                modelClass      = _cs[attr_c]['modelClass']

                # init a class model for this item
                model           = modelClass()

                # set model attribute values
                for k,v in attrValListItem.iteritems(): setattr(model, k, v)

                # generate a next eId
                resp       = nextEId(doc, attrNam)
                doc        = resp['doc']
                model.eId  = resp['eId']

                # generate dNam
                if hasattr(model, 'vNam') and 'dNam' in model._fields and not model.dNam:
                    model.dNam = model.vNam

                # generate dNamS
                if 'dNamS' in model._fields and hasattr(model, 'vNamS') and not model.dNamS:
                    model.dNamS = model.vNamS

                # remove all empty fields
                attrValListItemClean   = doc_remove_empty_keys(to_python(model, allow_none=True))

                # validate
                errors = validate(modelClass, attrValListItemClean)

                # TODO: handle and test errors
                if errors:
                    total_errors += errors['count']
                    post_errors.append(errors)
                    continue

                # logit update
                attrValListItemClean = logit(usr, attrValListItemClean, method='post')
                # save cleaned listType item back to doc
                doc[attrNam][attrValListOffset] = attrValListItemClean

    # now all listType items are clean, validated, and logged
    return doc

class Generic(object):

    def __init__(self, g):
        #: Doc comment for instance attribute db
        self.usr = g['usr']
        self.db  = g['db']
        self.es  = g['es']

    def post_attr(self, doc, attrNam, attr_c, attrVal, useTmpDoc = True):
        '''
            doc     = base doc to post/add attrVal to (in the attrNam field)
                Must contain _c, and _id
            usr     = user object
            coll    = collection
            attr_c  = model class
            _id     = doc id
            attrNam = attribute/fieldname
            attrVal = value to post/add
            '''

        db           = self.db

        errors       = {}
        doc_info     = {}
        response     = {}
        status       = 200
        post_errors  = []
        total_errors = 0

        doc_id         = doc['_id']
        usrOID       = self.usr['OID']
        where        = {'_id': doc_id}
        doc_c          = doc['_c']
        docModel       = _cs[doc_c]['modelClass']()
        collNam      = docModel.meta['collection']
        coll         = db[collNam + '_tmp'] if useTmpDoc else db[collNam]

        attrModel    = _cs[attr_c]['modelClass']()

        for k,v in attrVal.iteritems(): setattr(attrModel, k, v)

        # set the next element id eId
        resp       = nextEId(doc, attrNam)

        doc        = resp['doc']

        attrModel.eId  = resp['eId']

        if hasattr(attrModel, 'vNam') and 'dNam' in attrModel._fields and not attrModel.dNam:
            attrModel.dNam = attrModel.vNam

        # set dNamS if used:
        # if dNamS is empty, set to value of slug
        if hasattr(attrModel, 'vNam') and 'dNamS' in attrModel._fields and not attrModel.dNamS:
            attrModel.dNamS = attrModel.vNamS

        attrValClean   = doc_remove_empty_keys(to_python(attrModel, allow_none=True))
        attrErrors = validate(_cs[attr_c]['modelClass'], attrValClean)
        if attrErrors:
            response['total_invalid'] = 1
            response['errors']        = attrErrors
            response['total_errors']  = 1
            return {'response': response, 'status': 400}

        # logit update
        attrValClean = logit(self.usr, attrValClean, method='post')

        resp = coll.update(where,
                {"$push": { attrNam: attrValClean}, "$set": {'eIds': doc['eIds']}}
            )

        response['update_response'] = resp

        return {'response': response, 'status': 200}

    def post(self, **kwargs):
        '''Insert a doc
            newDocTmp: Initialize a temp (tmp) doc if no OID and no data.
            cloneDocTmp: Clone to a temp doc if OID and no isTmp flag set.
            upsertDocTmp: Update or Insert temp doc to base collection if OID and isTmp is set.
            insertDoc: Insert a new doc if no OID and there are more attributes than _c.
            '''
        db           = self.db

        response     = {}
        docs         = []
        status       = 200

        usrOID       = self.usr['OID']
        docs_to_post = kwargs['docs']

        post_errors  = []
        total_errors = 0

        for doc in docs_to_post:
            errors      = {}
            doc_info    = {}

            # required attribute
            _c          = doc['_c']

            # shortcut
            doc_keys   = doc.keys()

            modelClass = getattr(models, _c)
            _id        = doc['_id'] if '_id' in doc_keys else None
            where      = {'_id': ObjectId(_id)} if _id else None
            attrNam    = doc['attrNam'] if 'attrNam' in doc_keys else None
            attr_c     = doc['attr_c'] if attrNam else None
            attrVal    = doc['attrVal'] if attrNam else None
            collNam    = modelClass.meta['collection']
            collTmp    = db[collNam + '_tmp']
            coll       = db[collNam]

            # if _ id is passed,  it directs that a temp doc be initialized and inserted into the appropriate Tmp (temp) collection.
            # if an _id IS passed, it directs that the doc passed in be validated and inserted in the base collection and the temp doc in the temp collection be deleted.

            # if attrNam, posting a new value to a listtype attribute/field
            if attrNam:
                for elem in attrVal:
                    modelClass = getattr(models.embed, attr_c)
                    model      = modelClass()
                    for k,v in elem.iteritems(): setattr(model, k, v)

                    resp       = nextEId(doc, attrNam)
                    doc        = resp['doc']
                    # model.eIds = doc['eIds']
                    model.eId  = resp['eId']

                    if hasattr(model, 'vNam') and 'dNam' in model._fields and not model.dNam:
                        model.dNam = model.vNam

                    # generate a slug if slug is empty
                    if 'slug' in model._fields and 'dNam' in model._fields and not model.slug:
                        model.slug = slugify(model.dNam, coll)

                    # set dNamS if used:
                    # if dNamS is empty, set to value of slug
                    if 'dNamS' in model._fields and not model.dNamS:
                        if hasattr(model, 'vNamS'):
                            model.dNamS = model.vNamS
                        else:
                            model.dNamS = model.slug

                    embedDoc   = doc_remove_empty_keys(to_python(model, allow_none=True))
                    doc_errors = validate(modelClass, embedDoc)

                    if doc_errors:
                        total_errors += doc_errors['count']
                        post_errors.append(doc_errors)
                        continue

                    embedDoc['_c'] = attr_c

                    # logit update
                    embedDoc = logit(self.usr, embedDoc, method='post')

                    collTmp.update(where,
                            {"$push": { attrNam: embedDoc}, "$set": {'eIds': doc['eIds']}}
                        )

                    doc_info['doc']   = embedDoc
                    docs.append(doc_info)

                # http://docs.mongodb.org/manual/applications/update/
                # { $set: { 'emails.$.eId': 2 }

                response['total_inserted'] = len(docs)

                if post_errors:
                    response['total_invalid'] = len(post_errors)
                    response['errors']        = post_errors
                    response['total_errors']  = total_errors
                    status                    = 400
                else:
                    response['total_invalid'] = 0

                response['docs'] = docs

                return {'response': response, 'status': status}

            # Initialize a temp (tmp) doc if no OID and no data.
            elif not '_id' in doc_keys and len(doc_keys) == 1:
                newDocTmp = True
                useTmpDoc = True

            # Clone to a temp doc if OID and no isTmp flag set.
            elif '_id' in doc_keys and not 'isTmp' in doc_keys and len(doc_keys) > 2:
                cloneDocTmp  = True
                useTmpDoc    = True

                # find source doc
                # set locked = True
                doc_cloned = coll.find_and_modify(
                    query = {'_id':_id},
                    update = {"$set": {'locked': True}},
                    new = True
                )
                # set cloned doc in tmp collection isTmp = True
                doc_cloned['isTmp'] = True

                # don't need locked set in tmp doc
                del doc_cloned['locked']

                # clone/save doc to tmp collection

                # TODO properly handle exception
                try:
                    collTmp.insert(doc_cloned)
                except:
                    pass

                doc_info['doc']   = doc_cloned

                # TODO
                # should return a link to object according to good practice
                #doc_info['link'] = get_document_link(class_name, id)

                docs.append(doc_info)

                continue

            # Update temp doc to base collection if OID and isTmp is set.
            elif '_id' in doc_keys and 'isTmp' in doc_keys and doc['isTmp']:
                upsertDocTmp  = True
                useTmpDoc     = False

                tmp_doc = collTmp.find_one({'_id': _id})

                # unset isTmp
                _id = tmp_doc['_id']
                tmp_doc['locked'] = False
                del tmp_doc['_id']
                del tmp_doc['isTmp']

                # logit update
                tmp_doc = logit(self.usr, tmp_doc)

                # update original/source doc
                doc = coll.update({'_id': _id}, {"$set": tmp_doc}, upsert=True, safe=True)

                # remove tmp doc
                collTmp.remove({'_id': _id})

                # though not necessary, to be consistant, return full doc
                doc = coll.find_one({'_id': _id})

                doc_info['doc']   = doc
                docs.append(doc_info)

                continue

            # Insert a new doc if no OID and there are more attributes than _c.
            elif not '_id' in doc_keys and len(doc_keys) > 2:
                insertDoc  = True
                useTmpDoc  = False

            # need to cruz through all doc keys to handle arrays/listtype fields.
            # they need to be initialized according to the appropriate model and validated, etc.
            doc = initDocListTypes(doc, self.usr)

            # init model instance
            model       = modelClass(**doc)

            # set isTemp
            model.isTmp = useTmpDoc and 'isTmp' in model._fields

            # try to generate dNam
            # if there is a vNam class property
            # if already has a value, use it
            if hasattr(model, 'vNam') and not useTmpDoc and 'dNam' in model._fields and not model.dNam:
                model.dNam = model.vNam

            # assign dId
            if 'dId' in model._fields and not model.dId:
                response = nextId(coll)
                if response['status'] == 200:
                    model.dId = response['nextId']
                else:
                    # handle error condition
                    pass

            # generate a slug if:
            # not a temp doc and slug is empty
            if 'slug' in model._fields and not useTmpDoc and not model.slug:
                model.slug = slugify(model.dNam, coll)

            # set dNamS if used:
            # not a temp doc and dNamS is empty, set to value of slug
            if 'dNamS' in model._fields and not useTmpDoc and not model.dNamS:
                model.dNamS = model.slug

            # do not validate if using temp doc
            if not useTmpDoc:
                doc_errors = validate(modelClass, doc)

                if doc_errors:
                    total_errors += doc_errors['count']
                    post_errors.append(doc_errors)
                    continue

            # modelClass stuffed in all available fields
            # let's remove all empty fields to keep mongo clean.
            doc             = to_python(model, allow_none=True)

            # do not log if using temp doc
            #log date time user involved with this event
            if not useTmpDoc:
                doc = logit(self.usr, doc, 'post')

            doc['_c'] = _c
            doc_clean = doc_remove_empty_keys(doc)

            # posting an existing temp doc to base collection
            if _id:
                doc_clean['_id'] = str(_id)
                id = str(coll.insert(doc_clean))
                # TODO properly handle exception
                try:
                    collTmp.remove({'_id': _id})
                except:
                    pass

            # posting initialized temp doc
            else:
                # TODO properly handle exception
                try:
                    coll.insert(doc_clean)
                except:
                    pass

            doc_info['doc']   = doc_clean

            # TODO
            # should return a link to object according to good practice
            #doc_info['link'] = get_document_link(class_name, id)

            docs.append(doc_info)

        response['total_inserted'] = len(docs)

        if post_errors:
            response['total_invalid'] = len(post_errors)
            response['errors']        = post_errors
            response['total_errors']  = total_errors
            status                    = 400
        else:
            response['total_invalid'] = 0

        response['docs'] = docs

        return {'response': response, 'status': status}

    def put(self, **kwargs):
        """Update a doc"""
        db = self.db
        # TODO: accomodate where clause to put changes to more than one doc.

        usrOID     = self.usr['OID']
        data       = kwargs['data']
        _c         = data['_c']
        modelClass = getattr(models, _c)
        #attrNam    = doc['attrNam'] if 'attrNam' in doc_keys else None
        #attr_c     = doc['attr_c'] if attrNam else None
        #attrEid    = doc['attrEid'] if attrNam else None
        #attrVal    = doc['attrVal'] if attrNam else None
        collNam    = modelClass.meta['collection']
        collNamTmp = collNam + '_tmp'
        collTmp    = db[collNamTmp]
        coll       = db[collNam]

        response   = {}
        docs       = []
        status     = 200

        where      = data['where']
        patch      = data['patch']
        eId        = data['eId'] if 'eId' in data else None

        if eId and len(patch.keys()) > 1:
            # TODO Handle error
            pass

        # if element eId was passed, expect to put/patch change to one element in a ListType attribute/field
        if eId and len(patch) == 1:
            elem    = patch.popitem()
            attrNam = elem[0]

            # enhance to support putting/updating multiple list elements
            attrVal = elem[1][0]

            resp    = preSave(attrVal, self.usr)
            if not resp['status'] == 200:
                return {'response': resp, 'status': 400}

            attrVal = resp['response']['doc']
            # http://docs.mongodb.org/manual/applications/update/
            # patch update in tmp collection
            attrEl = attrNam + '.$'
            doc = collTmp.find_and_modify(
                query = where,
                update = { "$set": { attrEl: attrVal }},
                new = True
            )
            response['collection'] = collNamTmp
            response['total_invalid'] = 0
            response['id'] = id.__str__()

            # remove this, not needed
            response['doc'] = doc

            return {'response': response, 'status': 200}
        else:
            # validate patch
            # init modelClass for this doc
            patch_errors = validate_partial(modelClass, patch)
            if patch_errors:
                response['errors'] = patch_errors['errors']
                response['total_errors'] = patch_errors['count']
                status = 400

                return prep_response(response, status = status)

            # logit update
            patch = logit(self.usr, patch)

            # patch update in tmp collection
            doc = collTmp.find_and_modify(
                query = where,
                update = {"$set": patch},
                new = True
            )

        # init model instance
        model      = modelClass(**doc)

        # if there is a vNam class property
        if hasattr(model, 'vNam') and 'dNam' in model._fields:
            doc        = collTmp.find_one(where)
            _id        = doc['_id']

            model.dNam = model.vNam
            if hasattr(model, 'vNamS') and 'dNamS' in model._fields:
                model.dNamS = model.vNamS

            doc        = doc_remove_empty_keys(to_python(model, allow_none=True))
            collTmp.update(where, doc)
            # gotta put the _id back
            doc['_id'] = _id

        response['collection'] = collNamTmp
        response['total_invalid'] = 0
        response['id'] = id.__str__()

        # remove this, not needed
        response['doc'] = doc

        return {'response': response, 'status': status}

    def get(self, **kwargs):
        """Docstring for get method:"""
        db = self.db
        class_name = kwargs['class_name']
        modelClass = getattr(models, class_name)
        collNam = modelClass.meta['collection']
        coll = db[collNam]

        response = {}
        docs = []
        status = 200

        # if an id was passed, try to return only that one
        if 'id' in kwargs:
            id = kwargs['id']
            doc = coll.find_one({"_id": ObjectId(id)})
            response['doc'] = doc
            return {'response': response, 'status': status}

        if 'where' in kwargs:
            where = kwargs['where']
        else:
            where = {}

        # this allows us to filter results on the type of contact involved
        # contacts return all
        # persons return contacts that are persons, etc.
        where['_c'] = class_name

        fields = kwargs['fields'] if 'fields' in kwargs else None
        sort_raw = kwargs['sort'] if 'sort' in kwargs else None

        # mongo wants sorts like: [("fld1", <order>), ("fld2", <order>)]
        sorts = []
        if sort_raw:
            flds = sort_raw
            for fld in flds:
                sorts = [(k, int(v)) for k, v in fld.iteritems()]

        skip = int(kwargs['skip']) if 'skip' in kwargs else 0
        limit = int(kwargs['limit']) if 'limit' in kwargs else 0
        skip_limit = skip > -1 and limit

        if sorts:
            cursor = coll.find(spec = where, fields = fields, skip = skip, limit = limit).sort(sorts)
        else:
            cursor = coll.find(spec = where, fields = fields, skip = skip, limit = limit)
        for doc in cursor:
            docs.append(doc)

        # handle any virtual fields
        if 'vflds' in kwargs:
            vflds = kwargs['vflds']
            for i, doc in enumerate(docs):
                initialed_model = modelClass(**doc)
                for vfld in vflds:
                    docs[i][vfld] = getattr(initialed_model, vfld)

        response['docs'] = docs

        return {'response': response, 'status': status}


# Input : n
# Input : n elements of an array (array is sorted) all the elements are different
# Input : Sum we are looking for
# Output: Number of pairs of elements which add up to inputed sum
# complexity: start with O(n^2) -> optimize it to O(nlogn)
def binary_search1(arr, x):
    low = 0
    high = len(arr) - 1
    mid = 0

    while low <= high:

        mid = (high + low) // 2

        # If x is greater, ignore left half
        if arr[mid] < x:
            low = mid + 1

        # If x is smaller, ignore right half
        elif arr[mid] > x:
            high = mid - 1

        # means x is present at mid
        else:
            return mid

    # If we reach here, then the element was not present
    return -1

n = int(input("Enter the number of elements in an array: "))
array = []
for i in range (n):
    array.append(int(input("Element of an array :")))

sum = int(input("Enter the sum you are looking for: "))

numberOfPairs = int(0)

signals = [0]*n

for i in range(n):
    signals[i] = 1
    valOfBinarySearch = int(binary_search1(array, sum - array[i]))
    if signals[int(valOfBinarySearch)] == 0:
        if valOfBinarySearch != -1:
            numberOfPairs = numberOfPairs + 1
            signals[valOfBinarySearch] = 1

print("Number of pairs adding to {0:d} is : {1:d}".format(sum, numberOfPairs))


""" Tests for the spatial module. """

import numpy as np
import pytest
import rasterio as rio
from shapely.geometry import Polygon, Point, LineString
import earthpy.spatial as es

def test_crop_image_with_gdf(basic_image_tif, basic_geometry_gdf):
    """Cropping with a GeoDataFrame works when all_touched=True.

    Cropping basic_image_tif file with the basic geometry fixture returns
    all of the cells that have the value 1 in the basic_image_tif fixture

    These fixtures are described in conftest.py
    """
    with rio.open(basic_image_tif) as src:
        img, meta = es.crop_image(src, basic_geometry_gdf, all_touched=True)
    assert np.sum(img) == 9

def test_crop_image_with_gdf_touch_false(basic_image_tif, basic_geometry_gdf):
    """Cropping with a GeoDataFrame works when all_touched=False."""
    with rio.open(basic_image_tif) as src:
        img, meta = es.crop_image(src, basic_geometry_gdf, all_touched=False)
    assert np.sum(img) == 4

def test_crop_image_with_geometry(basic_image_tif, basic_geometry):
    """Cropping with a geometry works with all_touched=True."""
    with rio.open(basic_image_tif) as src:
        img, meta = es.crop_image(src, [basic_geometry], all_touched=True)
    assert np.sum(img) == 9

def test_crop_image_with_geojson_touch_false(basic_image_tif, basic_geometry):
    """Cropping with GeoJSON works when all_touched=False."""
    geojson = basic_geometry.__geo_interface__
    with rio.open(basic_image_tif) as src:
        img, meta = es.crop_image(src, [geojson], all_touched=False)
    assert np.sum(img) == 4

def test_crop_image_when_poly_bounds_image_extent(basic_image_tif):
    """When an image is fully contained in a larger polygon, dont crop."""
    big_polygon = Polygon([(-1, -1), (11, -1), (11, 11), (-1, 11), (-1, -1)])
    with rio.open(basic_image_tif) as src:
        img, meta = es.crop_image(src, [big_polygon])
        src_array = src.read()
    assert np.array_equal(img, src_array)

def test_crop_image_with_one_point_raises_error(basic_image_tif):
    """Cropping an image with one point should raise an error."""
    point = Point([(1, 1)])
    with rio.open(basic_image_tif) as src:
        with pytest.raises(ValueError, match="Input shapes do not overlap "):
            es.crop_image(src, [point])

def test_crop_image_with_1d_extent_raises_error(basic_image_tif):
    """Cropping with a horizontal or vertical line raises an error."""
    line = LineString([(1, 1), (2, 1), (3, 1)])
    with rio.open(basic_image_tif) as src:
        with pytest.raises(ValueError, match="Input shapes do not overlap "):
            es.crop_image(src, [line])

def test_crop_image_fails_two_rasters(basic_image_tif, basic_geometry):
    """crop_image should raise an error if provided two rasters."""
    with rio.open(basic_image_tif) as src:
        with pytest.raises(TypeError):
            es.crop_image(src, src)

def test_crop_image_swapped_args(basic_image_tif, basic_geometry):
    """If users provide a polygon instead of raster raise an error."""
    with pytest.raises(AttributeError):
        es.crop_image(basic_geometry, basic_image_tif)
    with pytest.raises(AttributeError):
        es.crop_image(basic_geometry, basic_geometry)

def test_crop_image_fails_empty_list(basic_image_tif, basic_geometry):
    """If users provide empty list as arg, crop_image fails."""
    with pytest.raises(AttributeError):
        es.crop_image(list(), basic_geometry)
    with rio.open(basic_image_tif) as src:
        with pytest.raises(ValueError):
            es.crop_image(src, list())


from datetime import datetime

from pandas import date_range, to_datetime, DatetimeIndex
from pandas import to_numeric, DateOffset
from prophet import Prophet

# from pandas import read_excel

"""
Pedro Tobarra 20210318:
Modificación del notebook '20210318_script_final_prophet_temporal_series_celda unica.ipynb' para meter el código
en una función de python que luego pueda ser implementada en un fichero '.py' para su integración con el backend
del PFM
"""

def forecast_3_months(transactions_df, balance_df):
    # CAMBIO: nos quedamos con el saldo de la cuenta bancaria el ultimo dia
    balance_last_day_real = to_numeric(balance_df.loc[[0], ['BALANCE']].squeeze(), downcast='float')

    transactions_df = transactions_df.iloc[:, 0:2]

    # CAMBIO: renombramos columnas dataframe
    transactions_df.rename(columns={"Fecha transacción": "TRANSACTION_DATE", "Importe": "AMOUNT"}, inplace=True)

    # AGREGAMOS LAS TRANSACCIONES POR DIA
    transactions_df = transactions_df.groupby(transactions_df.TRANSACTION_DATE).sum()
    transactions_df.reset_index(level=0, inplace=True)
    range_of_dates = date_range(start=transactions_df.TRANSACTION_DATE.min(),
                                end=transactions_df.TRANSACTION_DATE.max())

    # rellenamos los dias sin transacciones con el valor 0.0
    transactions_df = \
        transactions_df.set_index('TRANSACTION_DATE').reindex(range_of_dates).fillna(0.0).rename_axis(
            'TRANSACTION_DATE').reset_index()
    transactions_df = transactions_df.set_index(transactions_df.iloc[:, 0])
    transactions_df = transactions_df.drop(['TRANSACTION_DATE'], axis=1)

    # CONSTRUIMOS EL DATAFRAME DEL BALANCE DE LA CUENTA
    balance_df = transactions_df.copy()
    balance_df.reset_index(level=0, inplace=True)
    balance_df["DATE"] = balance_df["TRANSACTION_DATE"]
    balance_df["BALANCE"] = 0

    for i in range(balance_df.index[0], balance_df.index[-1]):
        balance_df.loc[i + 1, 'BALANCE'] = balance_df.loc[i, 'BALANCE'] + \
                                           balance_df.loc[i, 'AMOUNT']

    balance_df = balance_df.drop(['TRANSACTION_DATE', 'AMOUNT'], axis=1)
    balance_df = balance_df.set_index(balance_df.iloc[:, 0])
    balance_df = balance_df.drop(['DATE'], axis=1)
    balance_last_day_fake = to_numeric(balance_df.iloc[-1:].squeeze(), downcast='float')
    bias = balance_last_day_real - balance_last_day_fake
    balance_df['BALANCE'] = balance_df['BALANCE'] + bias

    # PREPARAMOS UN DATAFRAME prophet_df PARA ENTRENAR UN MODELO
    prophet_df = balance_df.copy()
    prophet_df.reset_index(level=0, inplace=True)

    # prepare expected column names
    prophet_df.columns = ['ds', 'y']
    prophet_df['ds'] = to_datetime(prophet_df['ds'])

    # define the model
    model = Prophet()
    # fit the model
    model.fit(prophet_df)

    # HACEMOS UNA PREDICCIÓN A 90 DIAS
    # Make an Out-of-Sample Forecast
    future_out_sample_df = prophet_df.copy()
    future_out_sample_df = future_out_sample_df.drop(['y'], axis=1)
    future_out_sample_df = future_out_sample_df[-90:]
    future_out_sample_df.reset_index(level=0, inplace=True)
    future_out_sample_df = future_out_sample_df.drop(['index'], axis=1)
    future_out_sample_df.iloc[0, 0] = future_out_sample_df.iloc[-1, 0] + DateOffset(1)

    for i in range(1, len(future_out_sample_df)):
        future_out_sample_df.iloc[i, 0] = future_out_sample_df.iloc[i - 1, 0] + DateOffset(1)

    # use the model to make a forecast
    forecast_df = model.predict(future_out_sample_df)
    forecast_per_day_df = forecast_df.loc[:, ['ds', 'yhat']]
    forecast_per_day_df.columns = ['DATE', 'BALANCE']

    # HACEMOS UN DATAFRAME CON LA PREDICCIÓN DEL BALANCE MEDIO SEMANAL DE LA CUENTA A 90 DIAS
    forecast_per_week_df = forecast_per_day_df.copy()

    # Using a lambda function on apply.() to separate the year, month, day components
    forecast_per_week_df['DATE'].apply(lambda lambda_df: datetime(year=lambda_df.year,
                                                                  month=lambda_df.month,
                                                                  day=lambda_df.day))

    # Set the date as the index

    # convert the column (if it's a string) to datetime type
    datetime_ser = to_datetime(forecast_per_week_df['DATE'])

    # create datetime index passing the datetime series
    datetime_index = DatetimeIndex(datetime_ser.values)
    forecast_per_week_df = forecast_per_week_df.set_index(datetime_index)

    # we don't need the column DATE anymore
    forecast_per_week_df.drop('DATE', axis=1, inplace=True)

    # Using resample() method to aggregate by weeks and add mean() to take the average
    forecast_per_week_df = forecast_per_week_df['BALANCE'].resample('W').mean()

    return forecast_per_week_df

"""
# LOAD DATA USING READ_EXCEL
transacciones_orig_df = read_excel('./scripts_jupyter/Cuenta_124075.xlsx', sheet_name='_select_TRANSACTION_DATE_cast_a')

forecast_per_week_final_df = forecast_3_months(transacciones_orig_df)

print()
print(forecast_per_week_final_df)
print()
"""


import os
import sys
import logging
from ctypes import *

sys.path.append("\\\\VBOXSVR\\setup\\lib\\")

import cuckoo.defines
from cuckoo.paths import CUCKOO_DLL_PATH
from cuckoo.inject import cuckoo_inject

def cuckoo_resumethread(h_thread = -1):
    """
    Resumes the thread of a process created in suspended mode.
    @param h_thread: handle to the thread to resume
    """
    log = logging.getLogger("Monitor.ResumeThread")

    cuckoo.defines.KERNEL32.Sleep(2000)
    # If the resume fails we need to abort the analysis, as there won't be
    # any activity monitored.
    if not cuckoo.defines.KERNEL32.ResumeThread(h_thread):
        log.error("Unable to resume thread with handle \"0x%08x\" (GLE=%d)."
                  % (h_thread, cuckoo.defines.KERNEL32.GetLastError()))
        return False
    else:
        log.info("Resumed thread with handle \"0x%08x\"." % h_thread)

    return True

def cuckoo_monitor(pid = -1, h_thread = -1, suspended = False, dll_path = None):
    """
    Invokes injection and resume of the specified process.
    @param pid: PID of the process to monitor
    @param h_thread: handle of the thread of the process to monitor
    @param suspended: boolean value enabling or disabling the resume of the
                      specified process from suspended mode
    @param dll_path: path to the DLL to inject, if none is specified it will use
                     the default DLL
    """
    log = logging.getLogger("Monitor.Monitor")

    # The package run function should return the process id, if it's valid
    # I can inject it with Cuckoo's DLL or specified custom DLL.
    if pid > -1:
        if not dll_path or dll_path == CUCKOO_DLL_PATH:
            dll_path = CUCKOO_DLL_PATH
            log.info("Using default Cuckoo DLL \"%s\"." % dll_path)
        else:
            log.info("Using custom DLL \"%s\"." % dll_path)

        if not cuckoo_inject(pid, dll_path):
            log.error("Unable to inject process with ID \"%d\" with DLL " \
                      "\"%s\" (GLE=%s)."
                      % (pid, dll_path, cuckoo.defines.KERNEL32.GetLastError()))
            return False
        else:
            log.info("Original process with PID \"%d\" successfully injected."
                     % pid)

    # Resume the process in case it was created in suspended mode.
    if suspended and h_thread > -1:
        if not cuckoo_resumethread(h_thread):
            return False

    return True


def camel_case(phrase:str) -> str:
    camel = False
    result = ""
    for x in phrase:
        if x.isalpha():
            result += x.lower() if not camel else x.upper()
            camel = False
        else:
            camel = True
    return result


# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def reorderList(self, head: Optional[ListNode]) -> None:
        """
        Do not return anything, modify head in-place instead.
        Time: O(n)
        Space: O(1)
        """

        # find middle point separating two halves
        slow, fast = head, head.next
        while fast is not None and fast.next is not None:
            slow = slow.next
            fast = fast.next.next

        # reverse second halve
        second = slow.next
        prev = slow.next = None
        while second is not None:
            temp = second.next
            second.next = prev
            prev = second
            second = temp

        # merge two halves
        first, second = head, prev
        while second is not None:
            temp1, temp2 = first.next, second.next
            first.next = second
            second.next = temp1
            first, second = temp1, temp2


def calc_perc ( idx, length ):

    perc = (idx + 1) / length * 100
    return perc

def get_equilibrium_pc ( lst ):

    lst.sort ( reverse = True )

    for idx in range ( len(lst) ):
        if ( sum(lst[0:idx+1]) >= sum(lst[idx+1:]) ):
            perc = calc_perc ( idx, len(lst) )
            if perc > 50:
                perc = 50 - ( perc - 50 )

            perc = "{:.1f}".format(perc)
            return perc


from requests import get, utils
from decimal import Decimal
from datetime import datetime

response = get('http://www.cbr.ru/scripts/XML_daily.asp')
content = response.content.decode(encoding=utils.get_encoding_from_headers(response.headers))

def currency_rates(code, cool_vision=False, site=content):
    date_site_2 = site[site.find('Date="') + len('Date="'):site.find('" name="Foreign')]
    date_site = datetime.strptime(date_site_2, '%d.%m.%Y').date()
    for s in site.split('<CharCode>'):
        if code.upper() == s[0:3]:
            nominal = s[s.rfind('<Nominal>') + len('<Nominal>'):s.find('</Nominal>')]
            name = s[s.rfind('<Name>') + len('<Name>'):s.find('</Name>')]
            value = Decimal(s[s.rfind('<Value>') + len('<Value>'):s.find('</Value>')].replace(',', '.')).quantize(Decimal('1.00'))
            if cool_vision is False:
                return f'{value} {date_site}'
            else:
                return f'Получите {nominal} {name} за {value} руб на {date_site}'


import sys
import json
import logging
from pandas.core.algorithms import mode
import torch
import torch.nn as nn
import torch.nn.init as init
import torch.optim as optim
import torch.nn.functional as F
import torch.backends.cudnn as cudnn
import torchvision
import torchvision.transforms as transforms
import os
import time
import math
import argparse
import numpy as np
import scipy.sparse as sp
import pandas as pd
import matplotlib.pyplot as plt

from PIL import Image
from models import *
from pathlib import Path
from datetime import datetime as dt
from os.path import abspath, dirname, join
from torch.utils.data import Dataset, DataLoader

class DPLTrainingSet(Dataset):
    def __init__(self, root_dir, csv_file, transform=None, target_transform=None):
        self.root_dir = root_dir
        self.labels = pd.read_csv(csv_file)

        self.transform = transform

        self.target_transform = target_transform

    def __len__(self):
        return self.labels.shape[0]

    def __getitem__(self, index):
        img_name = os.path.join(self.root_dir,
                                self.labels.iloc[index, 0])
        image = Image.open(img_name)

        label = self.labels.iloc[index, 1:].astype(int).to_numpy()
        label = list(label)[0].tolist()

        if self.transform:
            image = self.transform(image)
        if self.target_transform:
            label = self.target_transform(label)

        return image, label

def load_data(args):

    transform_train = transforms.Compose([
        transforms.RandomCrop(32, padding=4),
        transforms.RandomHorizontalFlip(),
        transforms.ToTensor(),
        transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)),
    ])

    transform_test = transforms.Compose([
        transforms.ToTensor(),
        transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)),
    ])

    if args.dataset == "CIFAR10":
        ori_trainset = torchvision.datasets.CIFAR10(
            root=args.data_dir, train=True, download=True, transform=transform_train)
        trainset = DPLTrainingSet(root_dir=args.data_dir+"/"+args.dataset+"/", csv_file="labels.csv", transform=transform_train)
        testset = torchvision.datasets.CIFAR10(
            root=args.data_dir, train=False, download=True, transform=transform_test)
    elif args.dataset == "CIFAR100":
        ori_trainset = torchvision.datasets.CIFAR100(
            root=args.data_dir, train=True, download=True, transform=transform_train)
        trainset = DPLTrainingSet(root_dir=args.data_dir+"/"+args.dataset+"/", csv_file="labels.csv", transform=transform_train)
        testset = torchvision.datasets.CIFAR100(
            root=args.data_dir, train=False, download=True, transform=transform_test)
    else:
        print('the dataset name you have entered is not supported yet')
        sys.exit()

    trainloader = torch.utils.data.DataLoader(
        trainset, batch_size=args.batch_size, shuffle=True, num_workers=4)
    testloader = torch.utils.data.DataLoader(
        testset, batch_size=args.batch_size, shuffle=False, num_workers=4)
    ori_trainloader = torch.utils.data.DataLoader(
        ori_trainset, batch_size=args.batch_size, shuffle=False, num_workers=4)

    return trainloader, testloader, ori_trainloader

def load_net(args):
    """ return given network
    """
    if args.net == 'vgg16':
        net = VGG('VGG16')
    elif args.net == 'densenet121':
        net = DenseNet121()
    elif args.net == 'resnet18':
        net = ResNet18()
    elif args.net == 'preactresnet18':
        net = PreActResNet18()
    elif args.net == 'googlenet':
        net = GoogLeNet()
    elif args.net == 'mobilenet':
        net = MobileNet()
    elif args.net == 'mobilenetv2':
        net = MobileNetV2()
    elif args.net == 'efficientnet':
        net = EfficientNetB0()
    elif args.net == 'dla':
        net = SimpleDLA()

    else:
        print('the network name you have entered is not supported yet')
        sys.exit()

    if args.gpu: #use_gpu
        net = net.cuda()

    return net

def load_checkpoint(net, ckpt_path):
    print('==> Resuming from checkpoint..')
    assert os.path.isdir('checkpoint'), 'Error: no checkpoint directory found!'
    checkpoint = torch.load(ckpt_path)
    net.load_state_dict(checkpoint['net'])
    best_acc = checkpoint['acc']
    start_epoch = checkpoint['epoch']

    return net, best_acc, start_epoch

def save_json(json_obj, json_path, append_if_exists=False,
              overwrite_if_exists=False, unique_fn_if_exists=True):
    """Saves a json file

    Arguments:
        json_obj: json, json object
        json_path: Path, path including the file name where the json object
            should be saved to
        append_if_exists: bool, append to the existing json file with the same
            name if it exists (keep the json structure intact)
        overwrite_if_exists: bool, xor with append, overwrites any existing
            target file
        unique_fn_if_exsists: bool, appends the current date and time to the
            file name if the target file exists already.
    """
    if isinstance(json_path, str):
        json_path = Path(json_path)

    if overwrite_if_exists:
        append_if_exists = False
        unique_fn_if_exists = False

    if unique_fn_if_exists:
        overwrite_if_exists = False
        append_if_exists = False
        if json_path.exists():
            time = dt.now().strftime("%Y-%m-%d-%H-%M-%S")
            json_path = json_path.parents[0] / f'{str(json_path.stem)}_{time}'\
                                               f'{str(json_path.suffix)}'

    if overwrite_if_exists:
        append_if_exists = False
        with open(json_path, 'w+') as fout:
            json.dump(json_obj, fout, indent=2)
        return

    if append_if_exists:
        if json_path.exists():
            with open(json_path, 'r') as fin:
                read_file = json.load(fin)
            read_file.update(json_obj)
            with open(json_path, 'w+') as fout:
                json.dump(read_file, fout, indent=2)
            return

    with open(json_path, 'w+') as fout:
        json.dump(json_obj, fout, indent=2)

def display_progress(text, current_step, last_step, enabled=True,
                     fix_zero_start=True):
    """Draws a progress indicator on the screen with the text preceeding the
    progress

    Arguments:
        test: str, text displayed to describe the task being executed
        current_step: int, current step of the iteration
        last_step: int, last possible step of the iteration
        enabled: bool, if false this function will not execute. This is
            for running silently without stdout output.
        fix_zero_start: bool, if true adds 1 to each current step so that the
            display starts at 1 instead of 0, which it would for most loops
            otherwise.
    """
    if not enabled:
        return

    # Fix display for most loops which start with 0, otherwise looks weird
    if fix_zero_start:
        current_step = current_step + 1

    term_line_len = 80
    final_chars = [':', ';', ' ', '.', ',']
    if text[-1:] not in final_chars:
        text = text + ' '
    if len(text) < term_line_len:
        bar_len = term_line_len - (len(text)
                                   + len(str(current_step))
                                   + len(str(last_step))
                                   + len("  / "))
    else:
        bar_len = 30
    filled_len = int(round(bar_len * current_step / float(last_step)))
    bar = '=' * filled_len + '.' * (bar_len - filled_len)

    bar = f"{text}[{bar:s}] {current_step:d} / {last_step:d}"
    if current_step < last_step-1:
        # Erase to end of line and print
        sys.stdout.write("\033[K" + bar + "\r")
    else:
        sys.stdout.write(bar + "\n")

    sys.stdout.flush()

def write_csv(args, info):
    data = pd.DataFrame(info)
    data.to_csv(args.data_dir+"/"+args.dataset+"/labels.csv", mode='a', header=True, index=None)

def init_logging(filename=None):
    """Initialises log/stdout output

    Arguments:
        filename: str, a filename can be set to output the log ormation to
            a file instead of stdout"""
    log_lvl = logging.INFO
    log_format = '%(asctime)s: %(message)s'
    if filename:
        logging.basicConfig(handlers=[logging.FileHandler(filename),
                                      logging.StreamHandler(sys.stdout)],
                            level=log_lvl,
                            format=log_format)
    else:
        logging.basicConfig(stream=sys.stdout, level=log_lvl,
                            format=log_format)

def get_default_config():
    """Returns a default config file"""
    config = {
        'outdir': 'outdir',
        'seed': 42,
        'gpu': 0,
        'dataset': 'CIFAR10',
        'num_classes': 10,
        'test_sample_num': 1,
        'test_start_index': 0,
        'recursion_depth': 1,
        'r_averaging': 1,
        'scale': None,
        'damp': None,
        'calc_method': 'img_wise',
        'log_filename': None,
    }

    return config

FILE_DIR = dirname(abspath(__file__))
DATA_DIR = join(FILE_DIR, "data")

MACOSKO_COLORS = {
    "airplane": "#9fc5e8",
    "automobile": "#93c47d",
    "bird": "#76a5af",
    "cat": "#ffd966",
    "deer": "#6fa8dc",
    "dog": "#8e7cc3",
    "frog": "#c27ba0",
    "horse": "#a61c00",
    "ship": "#cc0000",
    "truck": "#e69138",
}
ZEISEL_COLORS = {
    "Astroependymal cells": "#d7abd4",
    "Cerebellum neurons": "#2d74bf",
    "Cholinergic, monoaminergic and peptidergic neurons": "#9e3d1b",
    "Di- and mesencephalon neurons": "#3b1b59",
    "Enteric neurons": "#1b5d2f",
    "Hindbrain neurons": "#51bc4c",
    "Immature neural": "#ffcb9a",
    "Immune cells": "#768281",
    "Neural crest-like glia": "#a0daaa",
    "Oligodendrocytes": "#8c7d2b",
    "Peripheral sensory neurons": "#98cc41",
    "Spinal cord neurons": "#c52d94",
    "Sympathetic neurons": "#11337d",
    "Telencephalon interneurons": "#ff9f2b",
    "Telencephalon projecting neurons": "#fea7c1",
    "Vascular cells": "#3d672d",
}
MOUSE_10X_COLORS = {
    0: "#FFFF00",
    1: "#1CE6FF",
    2: "#FF34FF",
    3: "#FF4A46",
    4: "#008941",
    5: "#006FA6",
    6: "#A30059",
    7: "#FFDBE5",
    8: "#7A4900",
    9: "#0000A6",
    10: "#63FFAC",
    11: "#B79762",
    12: "#004D43",
    13: "#8FB0FF",
    14: "#997D87",
    15: "#5A0007",
    16: "#809693",
    17: "#FEFFE6",
    18: "#1B4400",
    19: "#4FC601",
    20: "#3B5DFF",
    21: "#4A3B53",
    22: "#FF2F80",
    23: "#61615A",
    24: "#BA0900",
    25: "#6B7900",
    26: "#00C2A0",
    27: "#FFAA92",
    28: "#FF90C9",
    29: "#B903AA",
    30: "#D16100",
    31: "#DDEFFF",
    32: "#000035",
    33: "#7B4F4B",
    34: "#A1C299",
    35: "#300018",
    36: "#0AA6D8",
    37: "#013349",
    38: "#00846F",
}

def calculate_cpm(x, axis=1):
    """Calculate counts-per-million on data where the rows are genes.

    Parameters
    ----------
    x : array_like
    axis : int
        Axis accross which to compute CPM. 0 for genes being in rows and 1 for
        genes in columns.

    """
    normalization = np.sum(x, axis=axis)
    # On sparse matrices, the sum will be 2d. We want a 1d array
    normalization = np.squeeze(np.asarray(normalization))
    # Straight up division is not an option since this will form a full dense
    # matrix if `x` is sparse. Divison can be expressed as the dot product with
    # a reciprocal diagonal matrix
    normalization = sp.diags(1 / normalization, offsets=0)
    if axis == 0:
        cpm_counts = np.dot(x, normalization)
    elif axis == 1:
        cpm_counts = np.dot(normalization, x)
    return cpm_counts * 1e6

def log_normalize(data):
    """Perform log transform log(x + 1).

    Parameters
    ----------
    data : array_like

    """
    if sp.issparse(data):
        data = data.copy()
        data.data = np.log2(data.data + 1)
        return data

    return np.log2(data.astype(np.float64) + 1)

def pca(x, n_components=50):
    if sp.issparse(x):
        x = x.toarray()
    U, S, V = np.linalg.svd(x, full_matrices=False)
    U[:, np.sum(V, axis=1) < 0] *= -1
    x_reduced = np.dot(U, np.diag(S))
    x_reduced = x_reduced[:, np.argsort(S)[::-1]][:, :n_components]
    return x_reduced

def select_genes(
    data,
    threshold=0,
    atleast=10,
    yoffset=0.02,
    xoffset=5,
    decay=1,
    n=None,
    plot=True,
    markers=None,
    genes=None,
    figsize=(6, 3.5),
    markeroffsets=None,
    labelsize=10,
    alpha=1,
):
    if sp.issparse(data):
        zeroRate = 1 - np.squeeze(np.array((data > threshold).mean(axis=0)))
        A = data.multiply(data > threshold)
        A.data = np.log2(A.data)
        meanExpr = np.zeros_like(zeroRate) * np.nan
        detected = zeroRate < 1
        meanExpr[detected] = np.squeeze(np.array(A[:, detected].mean(axis=0))) / (
            1 - zeroRate[detected]
        )
    else:
        zeroRate = 1 - np.mean(data > threshold, axis=0)
        meanExpr = np.zeros_like(zeroRate) * np.nan
        detected = zeroRate < 1
        meanExpr[detected] = np.nanmean(
            np.where(data[:, detected] > threshold, np.log2(data[:, detected]), np.nan),
            axis=0,
        )

    lowDetection = np.array(np.sum(data > threshold, axis=0)).squeeze() < atleast
    # lowDetection = (1 - zeroRate) * data.shape[0] < atleast - .00001
    zeroRate[lowDetection] = np.nan
    meanExpr[lowDetection] = np.nan

    if n is not None:
        up = 10
        low = 0
        for t in range(100):
            nonan = ~np.isnan(zeroRate)
            selected = np.zeros_like(zeroRate).astype(bool)
            selected[nonan] = (
                zeroRate[nonan] > np.exp(-decay * (meanExpr[nonan] - xoffset)) + yoffset
            )
            if np.sum(selected) == n:
                break
            elif np.sum(selected) < n:
                up = xoffset
                xoffset = (xoffset + low) / 2
            else:
                low = xoffset
                xoffset = (xoffset + up) / 2
        print("Chosen offset: {:.2f}".format(xoffset))
    else:
        nonan = ~np.isnan(zeroRate)
        selected = np.zeros_like(zeroRate).astype(bool)
        selected[nonan] = (
            zeroRate[nonan] > np.exp(-decay * (meanExpr[nonan] - xoffset)) + yoffset
        )

    if plot:
        import matplotlib.pyplot as plt

        if figsize is not None:
            plt.figure(figsize=figsize)
        plt.ylim([0, 1])
        if threshold > 0:
            plt.xlim([np.log2(threshold), np.ceil(np.nanmax(meanExpr))])
        else:
            plt.xlim([0, np.ceil(np.nanmax(meanExpr))])
        x = np.arange(plt.xlim()[0], plt.xlim()[1] + 0.1, 0.1)
        y = np.exp(-decay * (x - xoffset)) + yoffset
        if decay == 1:
            plt.text(
                0.4,
                0.2,
                "{} genes selected\ny = exp(-x+{:.2f})+{:.2f}".format(
                    np.sum(selected), xoffset, yoffset
                ),
                color="k",
                fontsize=labelsize,
                transform=plt.gca().transAxes,
            )
        else:
            plt.text(
                0.4,
                0.2,
                "{} genes selected\ny = exp(-{:.1f}*(x-{:.2f}))+{:.2f}".format(
                    np.sum(selected), decay, xoffset, yoffset
                ),
                color="k",
                fontsize=labelsize,
                transform=plt.gca().transAxes,
            )

        plt.plot(x, y, linewidth=2)
        xy = np.concatenate(
            (
                np.concatenate((x[:, None], y[:, None]), axis=1),
                np.array([[plt.xlim()[1], 1]]),
            )
        )
        t = plt.matplotlib.patches.Polygon(xy, color="r", alpha=0.2)
        plt.gca().add_patch(t)

        plt.scatter(meanExpr, zeroRate, s=3, alpha=alpha, rasterized=True)
        if threshold == 0:
            plt.xlabel("Mean log2 nonzero expression")
            plt.ylabel("Frequency of zero expression")
        else:
            plt.xlabel("Mean log2 nonzero expression")
            plt.ylabel("Frequency of near-zero expression")
        plt.tight_layout()

        if markers is not None and genes is not None:
            if markeroffsets is None:
                markeroffsets = [(0, 0) for g in markers]
            for num, g in enumerate(markers):
                i = np.where(genes == g)[0]
                plt.scatter(meanExpr[i], zeroRate[i], s=10, color="k")
                dx, dy = markeroffsets[num]
                plt.text(
                    meanExpr[i] + dx + 0.1,
                    zeroRate[i] + dy,
                    g,
                    color="k",
                    fontsize=labelsize,
                )

    return selected

def plot(
    save_dir,
    x,
    y_origin,
    ax=None,
    title=None,
    draw_legend=True,
    draw_centers=False,
    draw_cluster_labels=False,
    colors=None,
    legend_kwargs=None,
    label_order=None,
    **kwargs
):
    import matplotlib

    y = []

    for i in range(y_origin.size):
        if y_origin[i] == 0:
            y.append("airplane")
        elif y_origin[i] == 1:
            y.append("automobile")
        elif y_origin[i] == 2:
            y.append("bird")
        elif y_origin[i] == 3:
            y.append("cat")
        elif y_origin[i] == 4:
            y.append("deer")
        elif y_origin[i] == 5:
            y.append("dog")
        elif y_origin[i] == 6:
            y.append("frog")
        elif y_origin[i] == 7:
            y.append("horse")
        elif y_origin[i] == 8:
            y.append("ship")
        elif y_origin[i] == 9:
            y.append("truck")

    if ax is None:
        _, ax = matplotlib.pyplot.subplots(figsize=(8, 8))

    if title is not None:
        ax.set_title(title)

    plot_params = {"alpha": kwargs.get("alpha", 0.6), "s": kwargs.get("s", 1)}

    # Create main plot
    if label_order is not None:
        assert all(np.isin(np.unique(y), label_order))
        classes = [l for l in label_order if l in np.unique(y)]
    else:
        classes = np.unique(y)
    if colors is None:
        default_colors = matplotlib.rcParams["axes.prop_cycle"]
        colors = {k: v["color"] for k, v in zip(classes, default_colors())}

    print(classes)

    point_colors = list(map(colors.get, y))

    ax.scatter(x[:, 0], x[:, 1], c=point_colors, rasterized=True, **plot_params)

    # Plot mediods
    if draw_centers:
        centers = []
        for yi in classes:
            mask = yi == y
            centers.append(np.median(x[mask, :2], axis=0))
        centers = np.array(centers)

        center_colors = list(map(colors.get, classes))
        print(center_colors)
        ax.scatter(
            centers[:, 0], centers[:, 1], c=center_colors, s=48, alpha=1, edgecolor="k"
        )

        # Draw mediod labels
        if draw_cluster_labels:
            for idx, label in enumerate(classes):
                if idx % 10 == 0:
                    print(idx)
                    ax.text(
                        centers[idx, 0],
                        centers[idx, 1] + 2.2,
                        label,
                        fontsize=kwargs.get("fontsize", 6),
                        horizontalalignment="center",
                    )

    # Hide ticks and axis
    ax.set_xticks([]), ax.set_yticks([]), ax.axis("off")

    if draw_legend:
        legend_handles = [
            matplotlib.lines.Line2D(
                [],
                [],
                marker="s",
                color="w",
                markerfacecolor=colors[yi],
                ms=10,
                alpha=1,
                linewidth=0,
                label=yi,
                markeredgecolor="k",
            )
            for yi in classes
        ]
        legend_kwargs_ = dict(loc="center left", bbox_to_anchor=(1, 0.5), frameon=False, )
        if legend_kwargs is not None:
            legend_kwargs_.update(legend_kwargs)
        ax.legend(handles=legend_handles, **legend_kwargs_)

    matplotlib.pyplot.savefig(os.path.join(save_dir,'99.png'), dpi=500, bbox_inches='tight')

def evaluate_embedding(
    embedding, labels, projection_embedding=None, projection_labels=None, sample=None
):
    """Evaluate the embedding using Moran's I index.

    Parameters
    ----------
    embedding: np.ndarray
        The data embedding.
    labels: np.ndarray
        A 1d numpy array containing the labels of each point.
    projection_embedding: Optional[np.ndarray]
        If this is given, the score will relate to how well the projection fits
        the embedding.
    projection_labels: Optional[np.ndarray]
        A 1d numpy array containing the labels of each projection point.
    sample: Optional[int]
        If this is specified, the score will be computed on a sample of points.

    Returns
    -------
    float
        Moran's I index.

    """
    has_projection = projection_embedding is not None
    if projection_embedding is None:
        projection_embedding = embedding
        if projection_labels is not None:
            raise ValueError(
                "If `projection_embedding` is None then `projection_labels make no sense`"
            )
        projection_labels = labels

    if embedding.shape[0] != labels.shape[0]:
        raise ValueError("The shape of the embedding and labels don't match")

    if projection_embedding.shape[0] != projection_labels.shape[0]:
        raise ValueError("The shape of the reference embedding and labels don't match")

    if sample is not None:
        n_samples = embedding.shape[0]
        sample_indices = np.random.choice(
            n_samples, size=min(sample, n_samples), replace=False
        )
        embedding = embedding[sample_indices]
        labels = labels[sample_indices]

        n_samples = projection_embedding.shape[0]
        sample_indices = np.random.choice(
            n_samples, size=min(sample, n_samples), replace=False
        )
        projection_embedding = projection_embedding[sample_indices]
        projection_labels = projection_labels[sample_indices]

    weights = projection_labels[:, None] == labels
    if not has_projection:
        np.fill_diagonal(weights, 0)

    mu = np.asarray(embedding.mean(axis=0)).ravel()

    numerator = np.sum(weights * ((projection_embedding - mu) @ (embedding - mu).T))
    denominator = np.sum((projection_embedding - mu) ** 2)

    return projection_embedding.shape[0] / np.sum(weights) * numerator / denominator

def get_mean_and_std(dataset):
    '''Compute the mean and std value of dataset.'''
    dataloader = torch.utils.data.DataLoader(dataset, batch_size=1, shuffle=True, num_workers=2)
    mean = torch.zeros(3)
    std = torch.zeros(3)
    print('==> Computing mean and std..')
    for inputs, targets in dataloader:
        for i in range(3):
            mean[i] += inputs[:,i,:,:].mean()
            std[i] += inputs[:,i,:,:].std()
    mean.div_(len(dataset))
    std.div_(len(dataset))
    return mean, std

def init_params(net):
    '''Init layer parameters.'''
    for m in net.modules():
        if isinstance(m, nn.Conv2d):
            init.kaiming_normal(m.weight, mode='fan_out')
            if m.bias:
                init.constant(m.bias, 0)
        elif isinstance(m, nn.BatchNorm2d):
            init.constant(m.weight, 1)
            init.constant(m.bias, 0)
        elif isinstance(m, nn.Linear):
            init.normal(m.weight, std=1e-3)
            if m.bias:
                init.constant(m.bias, 0)

_, term_width = os.popen('stty size', 'r').read().split()
term_width = int(term_width)

TOTAL_BAR_LENGTH = 65.
last_time = time.time()
begin_time = last_time
def progress_bar(current, total, msg=None):
    global last_time, begin_time
    if current == 0:
        begin_time = time.time()  # Reset for new bar.

    cur_len = int(TOTAL_BAR_LENGTH*current/total)
    rest_len = int(TOTAL_BAR_LENGTH - cur_len) - 1

    sys.stdout.write(' [')
    for i in range(cur_len):
        sys.stdout.write('=')
    sys.stdout.write('>')
    for i in range(rest_len):
        sys.stdout.write('.')
    sys.stdout.write(']')

    cur_time = time.time()
    step_time = cur_time - last_time
    last_time = cur_time
    tot_time = cur_time - begin_time

    L = []
    L.append('  Step: %s' % format_time(step_time))
    L.append(' | Tot: %s' % format_time(tot_time))
    if msg:
        L.append(' | ' + msg)

    msg = ''.join(L)
    sys.stdout.write(msg)
    for i in range(term_width-int(TOTAL_BAR_LENGTH)-len(msg)-3):
        sys.stdout.write(' ')

    # Go back to the center of the bar.
    for i in range(term_width-int(TOTAL_BAR_LENGTH/2)+2):
        sys.stdout.write('\b')
    sys.stdout.write(' %d/%d ' % (current+1, total))

    if current < total-1:
        sys.stdout.write('\r')
    else:
        sys.stdout.write('\n')
    sys.stdout.flush()

def format_time(seconds):
    days = int(seconds / 3600/24)
    seconds = seconds - days*3600*24
    hours = int(seconds / 3600)
    seconds = seconds - hours*3600
    minutes = int(seconds / 60)
    seconds = seconds - minutes*60
    secondsf = int(seconds)
    seconds = seconds - secondsf
    millis = int(seconds*1000)

    f = ''
    i = 1
    if days > 0:
        f += str(days) + 'D'
        i += 1
    if hours > 0 and i <= 2:
        f += str(hours) + 'h'
        i += 1
    if minutes > 0 and i <= 2:
        f += str(minutes) + 'm'
        i += 1
    if secondsf > 0 and i <= 2:
        f += str(secondsf) + 's'
        i += 1
    if millis > 0 and i <= 2:
        f += str(millis) + 'ms'
        i += 1
    if f == '':
        f = '0ms'
    return f


def LIS(Lis):
    from bisect import bisect
    seq = []
    for i in Lis:
        pos = bisect(seq,i)
        if len(seq) <= pos:
            seq.append(i)
        else:
            seq[pos]=i
    return len(seq)

N = int(input())
a = list(map(int, input().split()))
print(LIS(a))


# -*- coding: utf-8 -*-
"""
GA implementado para resolver ATSP
@author: Marcelo Gallegos
"""

import numpy as np
import random
import os
import operator
import pandas as pd
import matplotlib.pyplot as plt

mainpath = os.getcwd()
mDistancia = pd.read_csv(mainpath + '\ExampleInstance' + '.txt',delim_whitespace=True, header = None)

class Fitness:
    def __init__(self, circuito):
        self.circuito = circuito
        self.distancia = 0
        self.fitness= 0.0

    def circuitoDistancia(self):
        if self.distancia ==0:
            rutaDistancia = 0
            for i in range(0, len(self.circuito)):
                desdeNodo = self.circuito[i]
                haciaNodo = None
                if i + 1 < len(self.circuito):
                    haciaNodo = self.circuito[i + 1]
                else:
                    haciaNodo = self.circuito[0]
                rutaDistancia += desdeNodo.distancia(haciaNodo)
            self.distancia = rutaDistancia
        return self.distancia

    def circuitoFitness(self):
        if self.fitness == 0:
            self.fitness = 1 / float(self.circuitoDistancia())
        return self.fitness

def crearCircuito(ListaNodo):
    circuito = random.sample(ListaNodo, len(ListaNodo))
    return circuito

def rankearCircuito(poblacion):
    t_fitness = {}
    for i in range(0,len(poblacion)):
        t_fitness[i] = Fitness(poblacion[i]).circuitoFitness()
    return sorted(t_fitness.items(), key = operator.itemgetter(1), reverse = True)

class Nodo:
    def __init__(self, n):
        self.n = n

    def distancia(self, nodo):
        i = self.n
        j = nodo.n
        distancia = mDistancia[i][j]
        return distancia

    def __repr__(self):
        return "Nodo:" + str(self.n+1)

def poblacionInicial(n_Poblacion, ListaNodo):
    poblacion = []

    for i in range(0, n_Poblacion):
        poblacion.append(crearCircuito(ListaNodo))
    return poblacion

def Seleccion(poblacionOrdenada, n_Elite):
    Resultado = []
    df = pd.DataFrame(np.array(poblacionOrdenada), columns=["Index","Fitness"])
    df['cum_sum'] = df.Fitness.cumsum()
    df['cum_perc'] = 100*df.cum_sum/df.Fitness.sum()

    for i in range(0, n_Elite):
        Resultado.append(poblacionOrdenada[i][0])
    for i in range(0, len(poblacionOrdenada) - n_Elite):
        seleccion = 100*random.random()
        for i in range(0, len(poblacionOrdenada)):
            if seleccion <= df.iat[i,3]:
                Resultado.append(poblacionOrdenada[i][0])
                break
    return Resultado

def Cruzamiento(poblacion, Resultado):
    Cruzamiento = []
    for i in range(0, len(Resultado)):
        index = Resultado[i]
        Cruzamiento.append(poblacion[index])
    return Cruzamiento

def Descendencia(Padre_a, Padre_b):
    Hijo = []
    HijoPadre_a = []
    HijoPadre_b = []

    genPadre_a = int(random.random() * len(Padre_a))
    genPadre_b = int(random.random() * len(Padre_b))

    GenInicio = min(genPadre_a, genPadre_b)
    GenTermino = max(genPadre_a, genPadre_b)

    for i in range(GenInicio, GenTermino):
        HijoPadre_a.append(Padre_a[i])
    HijoPadre_b = [item for item in Padre_b if item not in HijoPadre_a]

    Hijo = HijoPadre_a + HijoPadre_b
    return Hijo

def DescendenciaPoblacion(Cruzamiento, n_Elite):
    Hijos = []
    length = len(Cruzamiento) - n_Elite
    pool = random.sample(Cruzamiento, len(Cruzamiento))
    for i in range(0, n_Elite):
        Hijos.append(Cruzamiento[i])

    for i in range(0, length):
        Hijo = Descendencia(pool[i], pool[len(Cruzamiento)-i-1])
        Hijos.append(Hijo)
    return Hijos

def Mutacion(Individuo, p_Mutacion):
    for cruzado1 in range(len(Individuo)):
        if(random.random() < p_Mutacion):
            cruzado2 = int(random.random() * len(Individuo))

            Nodo1 = Individuo[cruzado1]
            Nodo2 = Individuo[cruzado2]

            Individuo[cruzado1] = Nodo2
            Individuo[cruzado2] = Nodo1
    return Individuo

def MutacionPoblacion(poblacion, p_Mutacion):
    PoblacionMutada = []

    for ind in range(0, len(poblacion)):
        IndividuoMutado = Mutacion(poblacion[ind], p_Mutacion)
        PoblacionMutada.append(IndividuoMutado)
    return PoblacionMutada

def GeneracionDescendiente(Cromosoma, n_Elite, p_Mutacion):
    PoblacionOrdenada = rankearCircuito(Cromosoma)
    Resultado = Seleccion(PoblacionOrdenada, n_Elite)
    Cruza = Cruzamiento(Cromosoma, Resultado)
    Hijos = DescendenciaPoblacion(Cruza, n_Elite)
    Descendientes = MutacionPoblacion(Hijos, p_Mutacion)
    return Descendientes

def Algoritmo(poblacion, n_Poblacion, n_Elite, p_Mutacion, generaciones):
    ga_poblacion = poblacionInicial(n_Poblacion, poblacion)
    print("Distancia Inicial: " + str(1 / rankearCircuito(ga_poblacion)[0][1]))

    for i in range(0, generaciones):
        ga_poblacion = GeneracionDescendiente(ga_poblacion, n_Elite, p_Mutacion)

    print("Distancia Final (Solucion): " + str(1 / rankearCircuito(ga_poblacion)[0][1]))
    mejorCircuitoIndex = rankearCircuito(ga_poblacion)[0][0]
    mejorCircuito = ga_poblacion[mejorCircuitoIndex]
    print("Circuito:" + str(mejorCircuito))
    return mejorCircuito

ListaNodo = []

for j in range(0,len(mDistancia)):
    ListaNodo.append(Nodo(n=j))

#Parámetros
poblacion = ListaNodo   #This parameter is automatically defined with "ListaNodo".
n_Poblacion = 200       #Population size to generate / iterate.
n_Elite = 40            #Size of the set of individuals selected under elitist criteria in each generation.
p_Mutacion = 0.001      #Mutation Probability of the offspring of each generation (1% = 0.01)
generaciones = 800      #Number of generations

#Ejecutar
Algoritmo(poblacion, n_Poblacion, n_Elite, p_Mutacion, generaciones)

#Gráfica
def AlgoritmoPlot(poblacion, n_Poblacion, n_Elite, p_Mutacion, generaciones):
    plotPoblacion = poblacionInicial(n_Poblacion, poblacion)
    progreso = []
    progreso.append(1 / rankearCircuito(plotPoblacion)[0][1])

    for k in range(0, generaciones):
        plotPoblacion = GeneracionDescendiente(plotPoblacion, n_Elite, p_Mutacion)
        progreso.append(1 / rankearCircuito(plotPoblacion)[0][1])

    plt.plot(progreso)
    plt.ylabel('Distancia de Circuito')
    plt.xlabel('Generacion')
    #plt.savefig("Grafico.png") #Unblock if you want create a copy of the graph image in the folder
    plt.show()

AlgoritmoPlot(poblacion, n_Poblacion, n_Elite, p_Mutacion, generaciones)


# Função que mostra todas as tabuadas

def tabuada():

    linha = 1
    coluna = 1
    while linha <= 10:
        while coluna <= 10:
            resultado = linha * coluna
            print(str(linha) + " x " + str(coluna) + " = " + str(resultado))
            coluna = coluna + 1
        linha = linha + 1
        print()
        print()
        coluna = 1

if __name__ == "__main__":
    tabuada()


'''
递归函数就是定义了一个函数，然后在函数内，自己调用了自己这个函数
递归函数内必须要有结束，不然就会一只调用下去，直到调用的层数越来越多，栈溢出
递归函数是一层一层的进入，再一层一层的返回
'''

def digui(num):
    print(num)  # 3 2 1 0
    if num > 0:
        digui(num-1)
    print(num)    # 0 1 2 3

#digui(3)

#计算阶乘1*2*3*4*5*6*7
def jiecheng(sum):
    if sum < 1:
        return 1
    else:
        return sum*jiecheng(sum-1)

#print(jiecheng(7))

#实现斐波那契数列 1 1 2 3 5 8 13 21 34……
def fbnq(n):
    if n==1 or n==2:
        return 1
    else:
        return fbnq(n-1) + fbnq(n-2)

if __name__ == '__main__':
    #digui(3)
    print(jiecheng(7))
    for i in range(1, 7):
        print(fbnq(i), end=' ')


"""
Good example of:
    - type validation for lists of dictionaries
    - type validation for complex types (datetime, timedelta)
    - error handling
    - spaces/characters in key names (dictionary['indexing'] and namespace.indexing)
"""

from __future__ import annotations

import argparse
import json
from datetime import datetime, timedelta
from pathlib import Path

import ruamel.yaml
import tomli

import cargparse

def parse_config(filename: Path | str) -> cargparse.Namespace:
    def min_sec(arg: str) -> timedelta:
        try:
            minutes, seconds = arg.split(":")
        except:
            # nicely formatted error message including the key (--duration; keys are otherwise inaccessible)
            raise argparse.ArgumentTypeError(f"{arg} failed to parse (expected MM:SS)")
        return timedelta(minutes=int(minutes), seconds=int(seconds))

    def year_month_day(arg: str) -> datetime:
        return datetime.strptime(arg, "%Y %m %d")

    def list_member_namespace(args: str) -> list[cargparse.Namespace]:
        args = eval(args)  # we expect args to be a list
        parser = argparse.ArgumentParser()
        parser.add_argument("--name", type=str)
        parser.add_argument("--dob", type=year_month_day)
        # use the same parser for each element in the list
        return [cargparse.Cargparse(parser).parse_dict(item) for item in args]

    mode = "rb" if filename.suffix == ".toml" else "r"
    with open(filename, mode) as f:
        if filename.suffix == ".yaml":
            config_str = ruamel.yaml.safe_load(f)
        elif filename.suffix == ".json":
            config_str = json.load(f)
        elif filename.suffix == ".toml":
            config_str = tomli.load(f)

    parser = argparse.ArgumentParser()
    parser.add_argument("--title", type=str)
    parser.add_argument("--artist", type=str)
    parser.add_argument("--label", type=str)
    parser.add_argument("--genre", type=cargparse.list_str)
    parser.add_argument("--duration", type=min_sec)
    parser.add_argument("--release date", type=year_month_day)
    parser.add_argument("--members", type=list_member_namespace)  # or cargparse.list_dict for list[dict[str, str]]
    return cargparse.Cargparse(parser).parse_dict(config_str)

if __name__ == "__main__":

    extensions = ["json", "toml", "yaml"]
    configs = [parse_config(Path(__file__).parent / f"twice_fancy.{ext}") for ext in extensions]

    try:
        assert configs[0] == configs[1] == configs[2]
        print("All good!\n")
    except AssertionError as e:
        print(e.__class__.__name__)
        exit(1)

    config = configs[2]

    print(f"{config['release date'].strftime('%Y %m %d')} - TWICE's smash hit 'Fancy' released")
    print(f"{datetime.now().strftime('%Y %m %d')} - Today's date")

    years = (datetime.now() - config["release date"]).days // 365
    days = (datetime.now() - config["release date"]).days % 365
    print(f"-> {years} years and {days} day{'s' if days != 1 else ''} have elapsed since then\n")

    print("How old is each TWICE member?")
    ages = {member: datetime.now().year - member.dob.year for member in config.members}
    for member, age in sorted(ages.items(), key=lambda x: x[1], reverse=True):
        msg = f"{age} - {member.name}"
        if datetime.now().month == member.dob.month and datetime.now().day == member.dob.day:
            msg += " (today is her birthday!)"
        print(msg)


import tkinter as tk
from tkinter import filedialog
import pandas as pd
import numpy as np
import tensorflow as tf
from sklearn.preprocessing import MinMaxScaler
from matplotlib.figure import Figure
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from datetime import datetime

# Assuming the model expects images of this size

model = None  # Initially, no model is loaded

def load_model():
    global model
    model_path = filedialog.askopenfilename(title="Load TensorFlow Model", filetypes=[("Model Files", "*.h5")])
    if not model_path:
        return
    model = tf.keras.models.load_model(model_path)
    status_label.config(text="Model Loaded Successfully!")

def open_data_and_predict():
    global model
    if not model:
        status_label.config(text="Please load a model first!")
        return

    file_path = filedialog.askopenfilename(title="load data", filetypes=[("CSV Files", "*.csv")])

    if not file_path:
        return

    reciept_dataframe = pd.read_csv(file_path, usecols=[1], engine='python')
    # Convert to Numpy Array and Normalize
    reciept_array = reciept_dataframe.values.astype('float32')
    scaler=MinMaxScaler(feature_range=(0, 1))
    normalized_reciept_data= scaler.fit_transform(reciept_array)
    # divide into training and testing sets
    training_rate= int(len(normalized_reciept_data)*0.80)
    train_partition, test_partition = normalized_reciept_data[0:training_rate,:], normalized_reciept_data[training_rate:len(normalized_reciept_data),:]
    def organize_data(sequence,history_length=1):
        input_data, target_data = [], []
        for i in range (len(sequence)-history_length-1):
            fragment=sequence[i:(i+history_length),0]
            input_data.append(fragment)
            target_data.append(sequence[i+history_length,0])
        return np.array(input_data),np.array(target_data)
    history_length=1
    x_train,y_train=organize_data(train_partition,history_length)
    x_test,y_test=organize_data(test_partition,history_length)

    x_train=np.reshape(x_train,(x_train.shape[0],1,x_train.shape[1]))
    x_test=np.reshape(x_test,(x_test.shape[0],1,x_test.shape[1]))

    train_forecast = model.predict(x_train)
    test_forecast = model.predict(x_test)

    train_forecast = scaler.inverse_transform(train_forecast)
    train_target = scaler.inverse_transform([y_train])
    test_forecast = scaler.inverse_transform(test_forecast)
    test_target = scaler.inverse_transform([y_test])

    print(test_forecast)
    # Clear the previous figure
    for widget in image_frame.winfo_children():
        widget.destroy()

    # Create a figure to plot
    fig = Figure(figsize=(8, 4), dpi=100)
    plot = fig.add_subplot(1, 1, 1)

    # Plot the predictions and ground truth
    plot.plot(scaler.inverse_transform(normalized_reciept_data), label='Ground Truth', color='blue')#.argsort() #np.arange(len(y_test))
    plot.plot([item for item in train_forecast], label='training forecast', color='green')#.argsort()
    plot.plot([item+len(train_forecast) for item in range(len(test_forecast))], test_forecast ,label='test_forecast', color='red')#.argsort()
    plot.set_title('Predictions vs Ground Truth')
    plot.legend()

    # Embed the plot into the Tkinter GUI
    canvas = FigureCanvasTkAgg(fig, master=image_frame)
    canvas.draw()
    canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=True)

app = tk.Tk()
app.title("Time Series Prediction")

# Create main frame
main_frame = tk.Frame(app)
main_frame.pack(padx=10, pady=10)

# Button to load model
load_model_button = tk.Button(main_frame, text="Load Model", command=load_model)
load_model_button.pack(pady=10)

# Button to open the image
open_button = tk.Button(main_frame, text="Load Data and Predict", command=open_data_and_predict)
open_button.pack(pady=10)

# Label to display model status
status_label = tk.Label(main_frame, text="", font=("Arial", 12))
status_label.pack(pady=10)

# Frame to display the plot
image_frame = tk.Frame(main_frame)
image_frame.pack(padx=5, pady=5, fill=tk.BOTH, expand=True)

app.mainloop()


import json
import os
from typing import List, Tuple, Union

from indago.avf.env_configuration import EnvConfiguration
from indago.config import DONKEY_ENV_NAME, ENV_NAMES, HUMANOID_ENV_NAME, PARK_ENV_NAME
from indago.envs.donkey.donkey_env_configuration import DonkeyEnvConfiguration
from indago.envs.humanoid.humanoid_env_configuration import HumanoidEnvConfiguration
from indago.envs.park.parking_env_configuration import ParkingEnvConfiguration

def read_logs(log_path: str, filename: str) -> json:
    assert os.path.exists(os.path.join(log_path, filename)), "Filename {} not found".format(os.path.join(log_path, filename))
    with open(os.path.join(log_path, filename), "r+", encoding="utf-8") as f:
        return json.load(f)

def get_training_logs_path(folder: str, algo: str, env_id: str, exp_id: int, resume_dir: str = None) -> str:
    if resume_dir is not None:
        log_path = os.path.join(folder, algo, resume_dir)
    else:
        log_path = os.path.join(folder, algo, "{}_{}".format(env_id, exp_id))
    assert os.path.isdir(log_path), "The {} folder was not found".format(log_path)
    return log_path

def parse_experiment_file(
    exp_file: str, env_name: str, return_failures: bool = True
) -> Union[List[EnvConfiguration], List[Tuple[EnvConfiguration, float]]]:
    assert os.path.exists(exp_file), "Exp file {} not found".format(exp_file)
    assert env_name in ENV_NAMES, "Env name {} not valid. Choose among: {}".format(env_name, ENV_NAMES)
    result = []
    f = False
    num_experiments = 0
    # for non deterministic environments
    num_trials = 1
    with open(exp_file, "r+", encoding="utf-8") as f:
        for line in f.readlines():

            if "Num experiments" in line:
                split = line.split(":")
                num_experiments = int(split[3].replace(" ", "").split("/")[1])

            if "INFO:Avf:Generating" in line:
                sentence = line.split(":")[2]
                num_trials = int("".join(list(filter(str.isdigit, sentence))))

            if return_failures and "INFO:experiments:FAIL -" in line:
                env_config_str = line.split(" - ")[1].split(":")[0].replace("Failure probability for env config ", "")
                result.append(get_env_config_of_env(env_config_str=env_config_str, env_name=env_name))
            elif not return_failures and f is True and "Failure probability for env config" in line:
                env_config_str = line.split(":")[2].replace("FAIL - ", "").replace("Failure probability for env config ", "")
                failure_probability = float(line.split(":")[3].replace(" ", "").split("(")[1].split(",")[0])
                env_config = get_env_config_of_env(env_config_str=env_config_str, env_name=env_name)
                result.append((env_config, failure_probability))
            elif not return_failures and "DEBUG:experiments:Num experiments:" in line:
                current_episodes_count = int(line.replace(" ", "").split(":")[3].split("/")[0])
                total_episodes_count = int(line.replace(" ", "").split(":")[3].split("/")[1])
                if current_episodes_count == total_episodes_count:
                    f = True

    if return_failures:
        return result
        # assert len(result) > 0, 'No failure in exp file {}'.format(exp_file)

    assert len(result) > 0, "No env configuration in exp file {}".format(exp_file)
    assert num_experiments > 0, "Num experiments cannot be <= 0"
    assert (
        len(result) == num_experiments // num_trials
    ), "Errors in parsing file. Num env configurations {} != num experiments {}".format(
        len(result), num_experiments // num_trials
    )

    return result

def get_env_config_of_env(env_config_str: str, env_name: str) -> EnvConfiguration:
    if env_name == PARK_ENV_NAME:
        return ParkingEnvConfiguration().str_to_config(s=env_config_str)
    elif env_name == HUMANOID_ENV_NAME:
        return HumanoidEnvConfiguration().str_to_config(s=env_config_str)
    elif env_name == DONKEY_ENV_NAME:
        return DonkeyEnvConfiguration().str_to_config(s=env_config_str)
    else:
        raise RuntimeError("Env name {} not supported".format(env_name))


#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# File : insert_data.py
# Description : Insert data for testing.
# Auteur : Nils Schaetti <nils.schaetti@unine.ch>
# Date : 30.05.2017
# Lieu : Nyon, Suisse
#
# This file is part of the PyLabXP Project.
# The PyLabXP Project is a set of free software:
# you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Foobar is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
#

import sys
from db.Connection import Connection

rc_size = 500

if __name__ == "__main__":

    # Open a connection
    con = Connection()

    # New instance
    instance = con.instance(lab_name="RCNLP", exp_name="Exploring reservoir size", instance_id=768477309779781668)

    # Locals
    instance.save_variables(locals())

    # Save params
    instance.save_parameter("leaky_rate", 0.5)
    instance.save_parameter("spectral_radius", 0.9)

    try:
        # Save result
        instance.save_results("success_rate", 91.0, params={"size": 10})
        instance.save_results("success_rate", 93.0, params={"size": 30})
        test = 10.0 / 0
        instance.save_results("success_rate", 85.0, params={"size": 50})
    except Exception as e:
        instance.save_traces()
    # end try

# end if


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Thu Sep 29 17:25:39 2022

@author: dani
"""

#gene expression can be leaky

import numpy as np
import bokeh.io
import bokeh.plotting

bokeh.io.output_notebook()
R=np.linspace(0,20,200)
b0=1
kd=1
a0=0.25

beta= a0+b0/(1+R/kd)

p=bokeh.plotting.figure(
height=275,
width=400,
x_axis_label="R",
y_axis_label="B(R)",
x_range=[R[0],R[-1]],
y_range=[0,beta.max()],
)

p.line(R,beta,line_width=2, color="tomato", legend_label="B(R)")
p.line(
[R[0],R[-1]],
    [a0,a0],
    line_width=2,
    color="orange",
    legend_label="bassal expression",
)
p.title.text="kd=1, b0=1, a0=0.25"
bokeh.io.show(p)


import ctypes
from itertools import repeat
import mmap
from types import FrameType
from unittest import mock

import pytest

from cpytraceafl import tracehook

def _get_populated_map_bytes(map_size_bits, loc_value_pairs):
    _map = bytearray(repeat(0, 1<<map_size_bits))
    for loc, value in loc_value_pairs:
        _map[loc] = value
    return bytes(_map)

@pytest.mark.parametrize("map_size_bits,ngram_size,map_prepop,lineno_lasti_pairs,expected_nonzeros", (
    (16, 0, (), ((123, 234), (345, 456)), ((0x19a5, 1),),),
    (16, 0, (), ((124, 234), (345, 456)), ((0x7d19, 1),),),
    (16, 0, (), ((567, 678), (123, 234), (345, 456)), ((0x19a5, 1),),),
    (16, 0, (), ((0, 0), (0, 0)), ((0x9b6d, 1),),),
    # alias because of zero-multiplication avoidance, but extremely unlikely in practice
    (16, 0, (), ((0, 0), (0, 0xffffffff)), ((0x9b6d, 1),),),
    (16, 0, (), ((0, 0), (0, 1)), ((0x6492, 1),),),
    # alias because of symmetry of operations, again extremely unlikely as lineno is usually
    # offset by a startlineno which we seed
    (16, 0, (), ((0, 0), (1, 0)), ((0x6492, 1),),),
    (12, 0, (), ((111, 222), (333, 444)), ((0x998, 1),),),

    # tests with a non-zero ngram_size must make at least enough calls to flush their full
    # ngram buffer, else result will depend on pre-test state of buffer
    (16, 2, (), ((567, 678), (123, 234), (345, 456)), ((0x25df, 1),),),
    (16, 2, (), ((789, 890), (567, 678), (123, 234), (345, 456)), ((0x25df, 1),),),
    (16, 3, (), ((789, 890), (567, 678), (123, 234), (345, 456)), ((0x7c5b, 1),),),
    (16, 3, (), ((789, 891), (567, 678), (123, 234), (345, 456)), ((0x0f3f, 1),),),

    # test never-zero overflow behaviour
    (12, 0, ((0xa88, 0xfe),), ((321, 432), (543, 654)), ((0xa88, 0xff),),),
    (12, 0, ((0xa88, 0xff),), ((321, 432), (543, 654)), ((0xa88, 1),),),

    (16, 0, ((0x123, 0x11),), ((322, 433), (544, 655)), ((0x123, 0x11), (0x1179, 1),),),
))
def test_line_trace_hook(map_size_bits, ngram_size, map_prepop, lineno_lasti_pairs, expected_nonzeros):
    with mmap.mmap(-1, 1<<map_size_bits, flags=mmap.MAP_PRIVATE) as mem:
        first_byte = ctypes.c_byte.from_buffer(mem)
        try:
            tracehook.set_map_start(ctypes.addressof(first_byte))
            tracehook.set_map_size_bits(map_size_bits)
            tracehook.set_ngram_size(ngram_size)

            for lineno, lasti in lineno_lasti_pairs[:-1]:
                mock_frame = mock.create_autospec(
                    FrameType,
                    instance=True,
                    f_lineno=lineno,
                    f_lasti=lasti,
                )
                tracehook.line_trace_hook(mock_frame, "line", mock.Mock())

            # we can't effectively assert the action of the prior calls as they will depend on
            # their *previous* call arguments, so clear it so we can make a clean assertion
            # following the next call
            mem.write(_get_populated_map_bytes(map_size_bits, map_prepop))
            mem.seek(0)

            lineno, lasti = lineno_lasti_pairs[-1]
            mock_frame = mock.create_autospec(
                FrameType,
                instance=True,
                f_lineno=lineno,
                f_lasti=lasti,
            )
            tracehook.line_trace_hook(mock_frame, "line", mock.Mock())

            assert mem.read() == _get_populated_map_bytes(map_size_bits, expected_nonzeros)

        finally:
            del first_byte

@pytest.mark.parametrize("value", (1, 128,))
def test_invalid_ngram_size(value):
    with pytest.raises(ValueError):
        tracehook.set_ngram_size(value)

@pytest.mark.parametrize("value", (0, 2, 3,))
def test_valid_ngram_size(value):
    tracehook.set_ngram_size(value)