import numpy as np
from numpy.lib.stride_tricks import as_strided
from numpy.fft import fft, fft2, ifft2, ifft, ifftshift, fftshift
import random
import shutil as sh

def normal_pdf(length, sensitivity):
    return np.exp(-sensitivity * (np.arange(length) - length / 2)**2)

def cartesian_mask(shape, acc, sample_n=10, centred=False):
    """
    Sampling density estimated from implementation of kt FOCUSS
    shape: tuple - of form (..., nx, ny)
    acc: float - doesn't have to be integer 4, 8, etc..
    """
    N, Nx, Ny = int(np.prod(shape[:-2])), shape[-2], shape[-1]
    pdf_x = normal_pdf(Nx, 0.5/(Nx/10.)**2)
    lmda = Nx/(2.*acc)
    n_lines = int(Nx / acc)

    # add uniform distribution
    pdf_x += lmda * 1./Nx

    if sample_n:
        pdf_x[Nx//2-sample_n//2:Nx//2+sample_n//2] = 0
        pdf_x /= np.sum(pdf_x)
        n_lines -= sample_n

    mask = np.zeros((N, Nx))
    for i in range(N):
        idx = np.random.choice(Nx, n_lines, False, pdf_x)
        mask[i, idx] = 1

    if sample_n:
        mask[:, Nx//2-sample_n//2:Nx//2+sample_n//2] = 1

    size = mask.itemsize
    mask = as_strided(mask, (N, Nx, Ny), (size * Nx, size, 0))

    mask = mask.reshape(shape)

    if not centred:
        mask = ifftshift(mask, axes=(-1, -2))

    return mask

def normalize_volume(img_vol):

    h,w = img_vol.shape[0],img_vol.shape[1]
    norm_img_vol = np.empty([h,w,0])

    for sl_no in range(img_vol.shape[-1]):

        img = img_vol[:,:,sl_no]
        img_norm = img / float(np.max(img))

        norm_img_vol = np.dstack([norm_img_vol,img_norm])

    return norm_img_vol

def undersample_volume_static(img_vol,us_factors,us_masks):

    h,w = img_vol.shape[0],img_vol.shape[1]

    us_volumes = {}

    for ii in range(len(us_factors)):
        print("us_factor: ",us_factors[ii])
        us_factor = us_factors[ii]
        us_mask   = us_masks[ii]

        us_img_vol    = np.empty([h,w,0])
        us_kspace_vol = np.empty([h,w,0])

        for sl_no in range(img_vol.shape[-1]):
            #print("sl_no: ",sl_no)

            img = img_vol[:,:,sl_no]

            kspace     = np.fft.fft2(img,norm='ortho')
            us_kspace  = kspace * us_mask
            us_kspace_vol = np.dstack([us_kspace_vol,us_kspace])

            us_img        = np.abs(np.fft.ifft2(us_kspace,norm='ortho'))
            us_img_vol    = np.dstack([us_img_vol,us_img])

        us_volumes['img_volus_{}x'.format(str(us_factor))] = us_img_vol
        us_volumes['kspace_volus_{}x'.format(str(us_factor))] = us_kspace_vol

    return us_volumes

def undersample_volume_dynamic(img_vol,us_factors):

    h,w = img_vol.shape[0],img_vol.shape[1]

    us_volumes = {}

    for us_factor in us_factors:
        us_img_vol  = np.empty([h,w,0])

        for sl_no in range(img_vol.shape[-1]):

            img = img_vol[:,:,sl_no]
            img_us   = np.fft.ifft2(np.fft.fft2(img) * cartesian_mask((h,w),us_factor)).real
            img_us  /= float(np.max(img_us))

            us_img_vol =  np.dstack([us_img_vol,img_us])

        us_volumes['volus_{}x'.format(str(us_factor))] = us_img_vol

    return us_volumes

def create_dataset_split(src_dir,train_dir,validation_dir,file_ext,split_ratio=0.7):

    file_list = glob.glob(os.path.join(src_dir,'.*{}'.format(file_ext))) #Works only for files in the first level of the folder structure
    random.shuffle(file_list)

    train_file_count = int(len(file_list) * split_ratio)

    train_files = file_list[:train_file_count]
    validation_files = file_list[train_file_count:]

    for file_path in train_files:
        dst_path = os.path.join(train_dir,os.path.basename(file_path))
        sh.copy(file_path,dst_path)

    for file_path in validation_files:
        dst_path = os.path.join(validation_dir,os.path.basename(file_path))
        sh.copy(file_path,dst_path)

    return

def range_np(input):

    return np.max(input),np.min(input)


import os
from django.conf import settings
import dj_database_url

DEBUG = False

DATABASES = settings.DATABASES

# Parse database configuration from $DATABASE_URL
DATABASES['default'] = dj_database_url.config()
DATABASES['default']['CONN_MAX_AGE'] = 500

# Honor the 'X-Forwarded-Proto' header for request.is_secure()
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')

# Allow all host headers
ALLOWED_HOSTS = ['*']

STATICFILES_STORAGE = 'whitenoise.django.GzipManifestStaticFilesStorage'

ADMIN_MEDIA_PREFIX = '/static/admin/'

STATICFILES_DIRS = (os.path.join(BASE_DIR, 'static'),)

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.messages',
    'whitenoise.runserver_nostatic',
    'django.contrib.staticfiles',
    'apps.services',
    'django.contrib.admin',
    'crispy_forms',
    'registration',
)

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.contrib.auth.context_processors.auth',
                'django.template.context_processors.debug',
                'django.template.context_processors.i18n',
                'django.template.context_processors.media',
                'django.template.context_processors.static',
                'django.template.context_processors.tz',
                'django.contrib.messages.context_processors.messages',
            ],
            'debug': DEBUG,
        },
    },
]


#!/usr/bin/python3
import rrdtool
import time
import sqlite3
import os

# print("hi")

def creat(rrdFile):

    # create filename [--start|-b start time] [--step|-s step] [DS:ds-name:DST:heartbeat:min:max] [RRA:CF:xff:steps:rows]
    # filename创建的rrdtool数据库文件名，默认后缀为.rrd;
    # --start 指定rrdtool第一条记录的起始时间，必须是timestamp的格式；
    # --step 指定rrdtool每隔多长时间就收到一个值，默认为5分钟；
    # 数据写频率--step为300秒（即5分钟一个数据点）
    rrd = rrdtool.create(rrdFile, "--start=now-1800", "--step=1",
    # 定义数据源 flow （数据量）; 类型都为 GAUGE（真实值）; 300秒为心跳值，
    # 其含义是300秒没有收到值，则用 UNKNOWN 代替；0为最小值；最大值用U代替，表示不确定
        'DS:ds1:GAUGE:300:0:U',

        # RRA定义格式为[RRA：CF：xff：steps：rows]，CF定义了AVERAGE、MAX、MIN、LAST四种数据合并方式
        # xff定义为0.5,表示一个CDP中的PDP值如超过一半值为UNKNOWN，则该CDP的值就被标为UNKNOWN
        # 每隔5分钟（1*300秒）存一次数据的最新值，存600笔，即2.08天
        'RRA:LAST:0.5:1:600',
        'RRA:LAST:0.5:3:400',
        'RRA:LAST:0.5:6:300')

    if(not rrd):
        print(rrdtool.OperationalError())
        # print(rrdtool.ProgrammingError)

def fetch(rrdFile):

    rrd_result = rrdtool.fetch(rrdFile, "LAST", "--start=now-60", "--end=now")

    print(rrd_result)

# def graph(title, pngFile, rrdFile):

    # rrdtool.graph(pngFile, "--start=now-1800", "--end=now",
    # "--width=600", "--height=200", "--title", title,
    # "--vertical-label=G/used",
    # "DEF:vtest",rrdFile)

def getDataSelected(dataSelected):

    conn = sqlite3.connect('/home/yingqi/Desktop/monitoring/server/datasHistory.db')

    cu = conn.cursor()

    cu.execute(dataSelected)

    result = cu.fetchall()

    conn.commit()

    conn.close()

    return result

def graph(dataColor, infoColor, dataType, dataSelected, rrdFile, pngFile):

    data=getDataSelected(dataSelected)
    # creat(rrdFile)
    # print(data)

    # starttime = int(time.time())
    # fetch(rrdFile)
    for i in range(len(data)):
        # print("\033[1;%s;40m%s\033[0m"%(dataColor,data[i][0]))
        rrdtool.update(rrdFile, 'N:%s'%(str(data[i][0])))
        # 数据有几个DS， N后面就有几个value
        # starttime+=10

    title = dataType + time.strftime('%Y-%m-%d', time.localtime(time.time()))

    # fetch(rrdFile)

    rrdtool.graph(pngFile, "--start=now-60", "--end=now",
                "--width=600", "--height=200", "--title", title,
                "--vertical-label=(%)/used",
                "DEF:vtest={}:ds1:LAST".format(rrdFile),
                "LINE:vtest%s:%s"%(infoColor,dataType))

bashCommand_listF = os.popen("ls /home/yingqi/Desktop/monitoring/server").read().strip('\n')
listF = bashCommand_listF.split()

# CPU
rrdFileCPU = 'usedCPU.rrd'
rrdFile_CPU = "/home/yingqi/Desktop/monitoring/server/usedCPU.rrd"
pngFile_CPU = "/home/yingqi/Desktop/monitoring/server/usedCPU.png"
dataSelected_CPU = " SELECT CPUutilisation FROM SystemDatas ORDER BY ReceiveDate DESC; "
dataType_CPU = "CPU utilisation"
dataColor_CPU = "31"
infoColor_CPU = "#ff0000"
if(rrdFileCPU not in listF):
    creat(rrdFile_CPU)
graph(dataColor_CPU , infoColor_CPU, dataType_CPU ,dataSelected_CPU,rrdFile_CPU,pngFile_CPU)

# HARDDISK
rrdFileHARDDISK = 'usedHARDDISK.rrd'
rrdFile_HARDDISK = "/home/yingqi/Desktop/monitoring/server/usedHARDDISK.rrd"
pngFile_HARDDISK = "/home/yingqi/Desktop/monitoring/server/usedHARDDISK.png"
dataSelected_HARDDISK = " SELECT HardDiskUsedSpace_percent FROM SystemDatas ORDER BY ReceiveDate DESC; "
dataType_HARDDISK = "HARD_DISK utilisation"
dataColor_HARDDISK = "33"
infoColor_HARDDISK = "#efc377"
if(rrdFileHARDDISK not in listF):
    creat(rrdFile_HARDDISK)
graph(dataColor_HARDDISK ,infoColor_HARDDISK, dataType_HARDDISK ,dataSelected_HARDDISK,rrdFile_HARDDISK,pngFile_HARDDISK)

# RAM
rrdFileRAM = 'usedRAM.rrd'
rrdFile_RAM = "/home/yingqi/Desktop/monitoring/server/usedRAM.rrd"
pngFile_RAM = "/home/yingqi/Desktop/monitoring/server/usedRAM.png"
dataSelected_RAM = " SELECT RAMusedSpace_percent FROM SystemDatas ORDER BY ReceiveDate DESC; "
dataType_RAM = "RAM utilisation"
dataColor_RAM = "35"
infoColor_RAM = "#e979fa"
if(rrdFileRAM not in listF):
    creat(rrdFile_RAM)
graph(dataColor_RAM ,infoColor_RAM, dataType_RAM ,dataSelected_RAM,rrdFile_RAM,pngFile_RAM)


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

import re
import time
import random
import base64

from lxml import etree

from odoo import models, fields, api, _
from odoo.tools import float_round, DEFAULT_SERVER_DATE_FORMAT
from odoo.exceptions import UserError, ValidationError

def check_valid_SEPA_str(string):
    if re.search('[^-A-Za-z0-9/?:().,\'+ ]', string) is not None:
        raise ValidationError(_("The text used in SEPA files can only contain the following characters :\n\n"
            "a b c d e f g h i j k l m n o p q r s t u v w x y z\n"
            "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z\n"
            "0 1 2 3 4 5 6 7 8 9\n"
            "/ - ? : ( ) . , ' + (space)"))

def prepare_SEPA_string(string):
    """ Make string comply with the recomandations of the EPC. See section 1.4 (Character Set) of document
        'sepa credit transfer scheme customer-to-bank implementation guidelines', issued by The European Payment Council.
    """
    if not string:
        return ''
    while '//' in string:  # No double slash allowed
        string = string.replace('//', '/')
    while string.startswith('/'):  # No leading slash allowed
        string = string[1:]
    while string.endswith('/'):  # No ending slash allowed
        string = string[:-1]
    string = re.sub('[^-A-Za-z0-9/?:().,\'+ ]', '', string)  # Only keep allowed characters
    return string

class AccountSepaCreditTransfer(models.TransientModel):
    _name = "account.sepa.credit.transfer"
    _description = "Create SEPA credit transfer files"

    @api.multi
    def _get_warning_message(self):
        for wiz in self:
            warning_message = self._context.get('warning_message', '')
            if warning_message:
                wiz.warning_message = _('The generated payment file is not a generic SEPA credit transfer. Be aware that some banks may reject it because it is not implemented on their side.\n\nIn particular, the reason why it this payment file is not a generic is the following:\n   ') + warning_message

    journal_id = fields.Many2one('account.journal', string="Journal", readonly=True)
    bank_account_id = fields.Many2one('res.partner.bank', string="Bank Account", readonly=True)
    is_generic = fields.Boolean(readonly=True,
        help=u"Technical feature used during the file creation. A SEPA message is said to be 'generic' if it cannot be considered as "
             u"a standard european credit transfer. That is if the bank journal is not in €, a transaction is not in € or a payee is "
             u"not identified by an IBAN account number and a bank BIC.")
    warning_message = fields.Text(string='Warning', compute=_get_warning_message, store=False)
    file = fields.Binary('SEPA XML File', readonly=True)
    filename = fields.Char(string='Filename', size=256, readonly=True)

    @api.model
    def create_sepa_credit_transfer(self, payments):
        """ Create a new instance of this model then open a wizard allowing to download the file
        """
        # Since this method is called via a client_action_multi, we need to make sure the received records are what we expect
        payments = payments.filtered(lambda r: r.payment_method_id.code == 'sepa_ct' and r.state in ('posted', 'sent')).sorted(key=lambda r: r.id)

        if len(payments) == 0:
            raise UserError(_("Payments to export as SEPA Credit Transfer must have 'SEPA Credit Transfer' selected as payment method and be posted"))
        if any(payment.journal_id != payments[0].journal_id for payment in payments):
            raise UserError(_("In order to export a SEPA Credit Transfer file, please only select payments belonging to the same bank journal."))

        journal = payments[0].journal_id
        bank_account = journal.bank_account_id
        if not bank_account.acc_type == 'iban':
            raise UserError(_("The account %s, of journal '%s', is not of type IBAN.\nA valid IBAN account is required to use SEPA features.") % (bank_account.acc_number, journal.name))
        for payment in payments:
            if not payment.partner_bank_account_id:
                raise UserError(_("There is no bank account selected for payment '%s'") % payment.name)

        is_generic, warning_msg = self._require_generic_message(journal, payments)
        res = self.create({
            'journal_id': journal.id,
            'bank_account_id': bank_account.id,
            'filename': "SCT-" + journal.code + "-" + time.strftime("%Y%m%d") + ".xml",
            'is_generic': is_generic,
        })

        if journal.company_id.sepa_pain_version == 'pain.001.001.03.ch.02':
            xml_doc = res._create_pain_001_001_03_ch_document(payments)
        elif journal.company_id.sepa_pain_version == 'pain.001.003.03':
            xml_doc = res._create_pain_001_003_03_document(payments)
        else:
            xml_doc = res._create_pain_001_001_03_document(payments)
        res.file = base64.encodestring(xml_doc)

        payments.write({'state': 'sent'})
        payments.write({'payment_reference': res.filename})

        # Alternatively, return the id of the transient and use a controller to download the file
        return {
            'type': 'ir.actions.act_window',
            'view_mode': 'form',
            'res_model': 'account.sepa.credit.transfer',
            'target': 'new',
            'res_id': res.id,
            'context': {'warning_message': warning_msg}
        }

    @api.model
    def _require_generic_message(self, journal, payments):
        """ Find out if generating a credit transfer initiation message for payments requires to use the generic rules, as opposed to the standard ones.
            The generic rules are used for payments which are not considered to be standard european credit transfers.
        """
        # A message is generic if :
        debtor_currency = journal.currency_id and journal.currency_id.name or journal.company_id.currency_id.name
        if debtor_currency != 'EUR':
            return True, _('Your bank account is not labelled in EUR')
        for payment in payments:
            bank_account = payment.partner_bank_account_id
            if payment.currency_id.name != 'EUR':
                return True, _('The transaction %s is instructed in another currency than EUR') % payment.name
            if not bank_account.bank_bic:
                return True, _('The creditor bank account %s used in payment %s is not identified by a BIC') % (payment.partner_bank_account_id.acc_number, payment.name)
            if not bank_account.acc_type == 'iban':
                return True, _('The creditor bank account %s used in payment %s is not identified by an IBAN') % (payment.partner_bank_account_id.acc_number, payment.name)
        return False, ''

    def _create_pain_001_001_03_document(self, doc_payments):
        """ Create a sepa credit transfer file that follows the European Payment Councile generic guidelines (pain.001.001.03)

            :param doc_payments: recordset of account.payment to be exported in the XML document returned
        """
        Document = self._create_iso20022_document('pain.001.001.03')
        return self._create_iso20022_credit_transfer(Document, doc_payments)

    def _create_pain_001_001_03_ch_document(self, doc_payments):
        """ Create a sepa credit transfer file that follows the swiss specific guidelines, as established
            by SIX Interbank Clearing (pain.001.001.03.ch.02)

            :param doc_payments: recordset of account.payment to be exported in the XML document returned
        """
        Document = etree.Element("Document", nsmap={
            None: "http://www.six-interbank-clearing.com/de/pain.001.001.03.ch.02.xsd",
            'xsi': "http://www.w3.org/2001/XMLSchema-instance"})
        return self._create_iso20022_credit_transfer(Document, doc_payments)

    def _create_pain_001_003_03_document(self, doc_payments):
        """ Create a sepa credit transfer file that follows the german specific guidelines, as established
            by the German Bank Association (Deutsche Kreditwirtschaft) (pain.001.003.03)

            :param doc_payments: recordset of account.payment to be exported in the XML document returned
        """
        Document = self._create_iso20022_document('pain.001.003.03')
        return self._create_iso20022_credit_transfer(Document, doc_payments)

    def _create_iso20022_document(self, pain_version):
        Document = etree.Element("Document", nsmap={
            None: "urn:iso:std:iso:20022:tech:xsd:%s" % (pain_version,),
            'xsi': "http://www.w3.org/2001/XMLSchema-instance"})
        return Document

    def _create_iso20022_credit_transfer(self, Document, doc_payments):
        CstmrCdtTrfInitn = etree.SubElement(Document, "CstmrCdtTrfInitn")

        # Create the GrpHdr XML block
        GrpHdr = etree.SubElement(CstmrCdtTrfInitn, "GrpHdr")
        MsgId = etree.SubElement(GrpHdr, "MsgId")
        val_MsgId = str(int(time.time() * 100))[-10:]
        val_MsgId = prepare_SEPA_string(self.journal_id.company_id.name[-15:]) + val_MsgId
        val_MsgId = str(random.random()) + val_MsgId
        val_MsgId = val_MsgId[-30:]
        MsgId.text = val_MsgId
        CreDtTm = etree.SubElement(GrpHdr, "CreDtTm")
        CreDtTm.text = time.strftime("%Y-%m-%dT%H:%M:%S")
        NbOfTxs = etree.SubElement(GrpHdr, "NbOfTxs")
        val_NbOfTxs = str(len(doc_payments))
        if len(val_NbOfTxs) > 15:
            raise ValidationError(_("Too many transactions for a single file."))
        if not self.bank_account_id.bank_bic:
            raise UserError(_("There is no Bank Identifier Code recorded for bank account '%s' of journal '%s'") % (self.bank_account_id.acc_number, self.journal_id.name))
        NbOfTxs.text = val_NbOfTxs
        CtrlSum = etree.SubElement(GrpHdr, "CtrlSum")
        CtrlSum.text = self._get_CtrlSum(doc_payments)
        GrpHdr.append(self._get_InitgPty())

        # Create one PmtInf XML block per execution date
        payments_date_wise = {}
        for payment in doc_payments:
            if payment.payment_date not in payments_date_wise:
                payments_date_wise[payment.payment_date] = []
            payments_date_wise[payment.payment_date].append(payment)
        count = 0
        for payment_date, payments_list in payments_date_wise.items():
            count += 1
            PmtInf = etree.SubElement(CstmrCdtTrfInitn, "PmtInf")
            PmtInfId = etree.SubElement(PmtInf, "PmtInfId")
            PmtInfId.text = (val_MsgId + str(self.journal_id.id) + str(count))[-30:]
            PmtMtd = etree.SubElement(PmtInf, "PmtMtd")
            PmtMtd.text = 'TRF'
            BtchBookg = etree.SubElement(PmtInf, "BtchBookg")
            BtchBookg.text = 'false'
            NbOfTxs = etree.SubElement(PmtInf, "NbOfTxs")
            NbOfTxs.text = str(len(payments_list))
            CtrlSum = etree.SubElement(PmtInf, "CtrlSum")
            CtrlSum.text = self._get_CtrlSum(payments_list)
            PmtInf.append(self._get_PmtTpInf())
            ReqdExctnDt = etree.SubElement(PmtInf, "ReqdExctnDt")
            ReqdExctnDt.text = time.strftime('%Y-%m-%d', time.strptime(payment_date, DEFAULT_SERVER_DATE_FORMAT))
            PmtInf.append(self._get_Dbtr())
            PmtInf.append(self._get_DbtrAcct())
            DbtrAgt = etree.SubElement(PmtInf, "DbtrAgt")
            FinInstnId = etree.SubElement(DbtrAgt, "FinInstnId")
            BIC = etree.SubElement(FinInstnId, "BIC")
            BIC.text = self.bank_account_id.bank_bic

            # One CdtTrfTxInf per transaction
            for payment in payments_list:
                PmtInf.append(self._get_CdtTrfTxInf(PmtInfId, payment))

        return etree.tostring(Document, pretty_print=True, xml_declaration=True, encoding='utf-8')

    def _get_CtrlSum(self, payments):
        return str(float_round(sum(payment.amount for payment in payments), 2))

    def _get_company_PartyIdentification32(self, org_id=True, postal_address=True):
        """ Returns a PartyIdentification32 element identifying the current journal's company
        """
        ret = []
        company = self.journal_id.company_id
        name_length = self.is_generic and 35 or 70

        Nm = etree.Element("Nm")
        Nm.text = prepare_SEPA_string(company.sepa_initiating_party_name[:name_length])
        ret.append(Nm)

        if postal_address and company.partner_id.city and company.partner_id.country_id.code:
            PstlAdr = etree.Element("PstlAdr")
            Ctry = etree.SubElement(PstlAdr, "Ctry")
            Ctry.text = company.partner_id.country_id.code
            if company.partner_id.street:
                AdrLine = etree.SubElement(PstlAdr, "AdrLine")
                AdrLine.text = prepare_SEPA_string(company.partner_id.street)
            if company.partner_id.zip and company.partner_id.city:
                AdrLine = etree.SubElement(PstlAdr, "AdrLine")
                AdrLine.text = prepare_SEPA_string(company.partner_id.zip) + " " + prepare_SEPA_string(company.partner_id.city)
            ret.append(PstlAdr)

        if org_id and company.sepa_orgid_id:
            Id = etree.Element("Id")
            OrgId = etree.SubElement(Id, "OrgId")
            Othr = etree.SubElement(OrgId, "Othr")
            _Id = etree.SubElement(Othr, "Id")
            _Id.text = prepare_SEPA_string(company.sepa_orgid_id)
            if company.sepa_orgid_issr:
                Issr = etree.SubElement(Othr, "Issr")
                Issr.text = prepare_SEPA_string(company.sepa_orgid_issr)
            ret.append(Id)

        return ret

    def _get_InitgPty(self):
        InitgPty = etree.Element("InitgPty")
        InitgPty.extend(self._get_company_PartyIdentification32(org_id=True, postal_address=False))
        return InitgPty

    def _get_PmtTpInf(self):
        PmtTpInf = etree.Element("PmtTpInf")
        InstrPrty = etree.SubElement(PmtTpInf, "InstrPrty")
        InstrPrty.text = 'NORM'

        if not self.is_generic:
            SvcLvl = etree.SubElement(PmtTpInf, "SvcLvl")
            Cd = etree.SubElement(SvcLvl, "Cd")
            Cd.text = 'SEPA'

        return PmtTpInf

    def _get_Dbtr(self):
        Dbtr = etree.Element("Dbtr")
        Dbtr.extend(self._get_company_PartyIdentification32(org_id=lambda: not self.is_generic, postal_address=True))
        return Dbtr

    def _get_DbtrAcct(self):
        DbtrAcct = etree.Element("DbtrAcct")
        Id = etree.SubElement(DbtrAcct, "Id")
        IBAN = etree.SubElement(Id, "IBAN")
        IBAN.text = self.bank_account_id.sanitized_acc_number
        Ccy = etree.SubElement(DbtrAcct, "Ccy")
        Ccy.text = self.journal_id.currency_id and self.journal_id.currency_id.name or self.journal_id.company_id.currency_id.name

        return DbtrAcct

    def _get_CdtTrfTxInf(self, PmtInfId, payment):
        CdtTrfTxInf = etree.Element("CdtTrfTxInf")
        PmtId = etree.SubElement(CdtTrfTxInf, "PmtId")
        InstrId = etree.SubElement(PmtId, "InstrId")
        InstrId.text = prepare_SEPA_string(payment.name)
        EndToEndId = etree.SubElement(PmtId, "EndToEndId")
        EndToEndId.text = (PmtInfId.text + str(payment.id))[-30:]
        Amt = etree.SubElement(CdtTrfTxInf, "Amt")
        val_Ccy = payment.currency_id and payment.currency_id.name or payment.journal_id.company_id.currency_id.name
        val_InstdAmt = str(float_round(payment.amount, 2))
        max_digits = val_Ccy == 'EUR' and 11 or 15
        if len(re.sub('\.', '', val_InstdAmt)) > max_digits:
            raise ValidationError(_("The amount of the payment '%s' is too high. The maximum permitted is %s.") % (payment.name, str(9) * (max_digits - 3) + ".99"))
        InstdAmt = etree.SubElement(Amt, "InstdAmt", Ccy=val_Ccy)
        InstdAmt.text = val_InstdAmt
        CdtTrfTxInf.append(self._get_ChrgBr())
        CdtTrfTxInf.append(self._get_CdtrAgt(payment.partner_bank_account_id))
        Cdtr = etree.SubElement(CdtTrfTxInf, "Cdtr")
        Nm = etree.SubElement(Cdtr, "Nm")
        Nm.text = prepare_SEPA_string(payment.partner_id.name[:70])
        CdtTrfTxInf.append(self._get_CdtrAcct(payment.partner_bank_account_id))
        val_RmtInf = self._get_RmtInf(payment)
        if val_RmtInf is not False:
            CdtTrfTxInf.append(val_RmtInf)
        return CdtTrfTxInf

    def _get_ChrgBr(self):
        ChrgBr = etree.Element("ChrgBr")
        ChrgBr.text = self.is_generic and "SHAR" or "SLEV"
        return ChrgBr

    def _get_CdtrAgt(self, bank_account):
        bank = bank_account.bank_id

        CdtrAgt = etree.Element("CdtrAgt")
        FinInstnId = etree.SubElement(CdtrAgt, "FinInstnId")
        val_BIC = bank_account.bank_bic
        if val_BIC:
            BIC = etree.SubElement(FinInstnId, "BIC")
            BIC.text = val_BIC
        elif not self.is_generic:
            raise UserError(_("There is no Bank Identifier Code recorded for bank account '%s'") % bank_account.acc_number)

        return CdtrAgt

    def _get_CdtrAcct(self, bank_account):
        if not self.is_generic and (not bank_account.acc_type or not bank_account.acc_type == 'iban'):
            raise UserError(_("The account %s, linked to partner '%s', is not of type IBAN.\nA valid IBAN account is required to use SEPA features.") % (bank_account.acc_number, bank_account.partner_id))

        CdtrAcct = etree.Element("CdtrAcct")
        Id = etree.SubElement(CdtrAcct, "Id")
        if self.is_generic:
            Othr = etree.SubElement(Id, "Othr")
            _Id = etree.SubElement(Othr, "Id")
            _Id.text = bank_account.acc_number
        else:
            IBAN = etree.SubElement(Id, "IBAN")
            IBAN.text = bank_account.sanitized_acc_number

        return CdtrAcct

    def _get_RmtInf(self, payment):
        if not payment.communication:
            return False
        RmtInf = etree.Element("RmtInf")
        Ustrd = etree.SubElement(RmtInf, "Ustrd")
        Ustrd.text = prepare_SEPA_string(payment.communication)
        return RmtInf


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sun Oct 16 22:27:47 2022

@author: alex
"""

import numpy as np

from pyro.dynamic  import massspringdamper
from pyro.control  import controller
from pyro.analysis import costfunction
from pyro.planning import dynamicprogramming
from pyro.planning import discretizer

sys  = massspringdamper.FloatingSingleMass()

sys.x_ub[0] =  10.0
sys.x_lb[0] = -10.0
sys.x_lb[1] = -5.0
sys.x_ub[1] = 5.0
sys.u_ub[0] = 5.0
sys.u_lb[0] = -5.0

# Discrete world
grid_sys = discretizer.GridDynamicSystem( sys , [101,101] , [41] , 0.05)

# Cost Function
qcf = costfunction.QuadraticCostFunction.from_sys(sys)

qcf.xbar = np.array([ -0 , 0 ]) # target
qcf.INF  = 300

qcf.R[0,0] = 10.0

qcf.S[0,0] = 10.0
qcf.S[1,1] = 10.0

# DP algo
dp = dynamicprogramming.DynamicProgrammingWithLookUpTable( grid_sys, qcf)

dp.solve_bellman_equation( tol = 0.5 )

ctl = dp.get_lookup_table_controller()

dp.plot_cost2go()
dp.plot_cost2go_3D()

ctl.plot_control_law( sys = sys , n = 100)

#asign controller
sys.C = np.eye(2)
sys.p = 2
cl_sys = controller.ClosedLoopSystem( sys , ctl )

##############################################################################

# Simulation and animation
cl_sys.x0   = np.array([+5,+3])
cl_sys.compute_trajectory( 20, 10001, 'euler')
cl_sys.plot_trajectory('xu')
cl_sys.plot_phase_plane_trajectory()
cl_sys.animate_simulation()


from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait

class ResultsPage:

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

    def is_bestseller(self, book) -> bool:
        """ Returns if the book is bestseller or not. """

        product = WebDriverWait(self.driver, 20).until(
            EC.presence_of_element_located(
                (By.XPATH, '//div[@data-cel-widget="search_result_1"]')
            )
        )
        ans = WebDriverWait(product, 20).until(
            EC.presence_of_all_elements_located(
                (By.XPATH, ".//a")
            )
        )[0].text
        # ans = product.find_elements_by_xpath(".//a")[0].text
        if ans == "Best Seller" or "Amazon Charts" in ans:
            is_bestseller = True
        else:
            is_bestseller = False

        book_link = None
        for p in product.find_elements_by_xpath(".//a"):
            if book in p.text:
                book_link = p
                break
        if book_link: book_link.click()

        return is_bestseller


"""This script sorts and renames files in the OCR output folder, saving you from doing shitton of robot work...
It makes ALTO and txt folders, moves files according to their extensions and renames .xml to .alto"""

import os
import shutil
import glob

# Methods definition

def foldercreate():  # creates folders ALTO and txt in specified directory

    os.chdir(folder)
    print("\nMaking ALTO and txt folders at:", os.getcwd(), "\n")

    if os.path.exists(folder+"/ALTO/") is False:
        os.mkdir(folder + "/ALTO/")

    if os.path.exists(folder + "/txt/") is False:
        os.mkdir(folder + "/txt/")

    print("Done...")

def move():  # moves all .xml files from list to ALTO folder

    print("\nMoving txt and xml files. If there are already .alto files, script won't touch them\n")
    os.chdir(folder)        # Probably not necessary, but just to be sure

    for file in glob.glob("*.xml"):
        shutil.move(file, folder + "/ALTO/" + file)  # .xml --> ALTO folder

    for file in glob.glob("*.txt"):
        shutil.move(file, folder + "/txt/" + file)  # .txt --> txt folder

    print("\nDone...directory now looks like this:\n", os.listdir(folder))

def rename():

    os.chdir(folder + "/ALTO/")

    for file in glob.glob("*.xml"):  # looks up all .xml files and stores them into file variable as list of strings
        filename, ext = os.path.splitext(file)  # splits files in list into filename and extension
        os.rename(file, filename + ".alto")  # renames each file from list as filename (file without extension) + .alto

# now the script itself

script_status = "running"
print("Hello there, please do note that I am not perfect and always check if all things went smoothly.")
print("It will save you much trouble and nerves...trust me ^_^ \n")

while script_status == "running":
    workspace = input("\nEnter folder path: \n")

    while os.path.isdir(workspace) is False:  # ensures that valid path is provided
        print("Folder doesn't exist")
        workspace = input("\nEnter folder path: \n")

    os.chdir(workspace)

    for subdir in glob.glob("*/"):
        folder = str(workspace + "/" + subdir)
        foldercreate()
        move()
        rename()

    # subfolder path is saved into "folder" variable, methods foldercreate(), move() and rename() are used on given path

    input("\n\nAll subfolders successfully processed...Press ENTER to continue, or CTRL + C to stop the script")

    # script loops back to folder selection / exits depending on input

exit()


# This is a function to write and call the GMTSAR SBAS control files
# Because it only does the GMTSAR standard options, I think it's better
# to use nsbas.py in almost all cases.
# The staging_directory functionality doesn't work right now because this authomatically reads intf_all/*/unwrap.grd

import numpy as np
import sentinel_utilities
from subprocess import call

def do_sbas(config_params, staging_directory):
    [stems, tbaseline, xbaseline, mission_days] = sentinel_utilities.read_baseline_table('raw/baseline_table.dat');
    t_int = [];
    for t in tbaseline:
        t_int.append(round(float(t)));  # a list of integers like 2016214 for 2016-day-214.

    mission_days_sorted = [x for (y, x) in sorted(zip(t_int, mission_days))];
    t_int.sort();
    tbaseline.sort();

    intf_computed = sentinel_utilities.glob_intf_computed();  # looks like a list of labels like 2016217_2016205
    n_intf = len(intf_computed);
    outfile = open("README_sbas.txt", 'w');
    outfile.write("# First, prepare the input files needed for sbas\n#\n");
    outfile.write("rm -f SBAS\nmkdir SBAS\ncd SBAS\n\n\n");
    outfile.write("# based on baseline_table.dat create the intf.tab and scene.tab for sbas\n");

    # writing intf.tab
    outfile.write("# phase  corherence  ref_id  rep_id  baseline\n")
    for img_pair in intf_computed:
        first_image = img_pair[0:7]
        second_image = img_pair[8:]
        for a, b in zip(xbaseline, t_int):
            if abs(int(np.floor(b)) - int(first_image)) <= 1:
                # print "first image found";
                # print int(np.floor(b))
                # print int(first_image)
                master_xbaseline = a;
            if abs(int(np.floor(b)) - int(second_image)) <= 1:
                slave_xbaseline = a;
                # print "second image found";
                # print int(np.floor(b))
                # print int(second_image)
        total_baseline = slave_xbaseline - master_xbaseline;
        outfile.write('echo "../intf_all/' + img_pair + '/unwrap.grd ')
        outfile.write('../intf_all/' + img_pair + '/corr.grd ')
        outfile.write(first_image + ' ' + second_image + ' ')
        outfile.write(str(total_baseline))
        outfile.write('" >> intf.tab\n');
    outfile.write("#\n\n");

    # writing scene.tab (only the scenes that are actually used in SBAS processing)
    # Right now this isn't producing anything.
    outfile.write("# scene_id  day\n");
    scenes_used = '';
    n_scenes = 0;
    scenes_used = [];
    for intf in intf_computed:
        scenes_used.append(intf[0:7]);  # catch which scenes are actually used in SBAS processing.
        scenes_used.append(intf[8:15]);
    for x in range(len(tbaseline)):
        temp = tbaseline[x];
        tempint = int(np.round(temp))
        if str(tempint) in scenes_used or str(tempint + 1) in scenes_used or str(tempint - 1) in scenes_used:
            outfile.write('echo "' + str(tempint) + ' ' + mission_days_sorted[x] + '" >> scene.tab\n');
            n_scenes += 1;
    outfile.write("\n\n");

    intf_ex = intf_computed[0];  # an example interferogram where we get the geographic coordinates for grdinfo
    outfile.write("xdim=`gmt grdinfo -C ../intf_all/" + intf_ex + "/unwrap.grd | awk '{print $10}'`\n");
    outfile.write("ydim=`gmt grdinfo -C ../intf_all/" + intf_ex + "/unwrap.grd | awk '{print $11}'`\n\n\n");

    outfile.write("# run sbas\n");
    outfile.write("sbas intf.tab scene.tab " + str(n_intf) + " " + str(
        n_scenes) + " $xdim $ydim -smooth 1.0 -wavelength 0.0554658 -incidence 30 -range 800184.946186 -rms -dem\n\n\n")

    outfile.write("# project the velocity to Geocooridnates\n");
    outfile.write('echo "writing to georeferenced coordinates..."\n');
    outfile.write("ln -s ../topo/trans.dat .\n");
    outfile.write("proj_ra2ll.csh trans.dat vel.grd vel_ll.grd\n");
    outfile.write("gmt grd2cpt vel_ll.grd -T= -Z -Cjet > vel_ll.cpt\n");
    outfile.write("grd2kml.csh vel_ll vel_ll.cpt\n");
    outfile.write("cd ..\n\n");
    outfile.write('echo "SBAS operation performed!"\n\n')

    outfile.close();
    print("README_sbas.txt written. Ready to call README_sbas.txt.")
    call("chmod u+x README_sbas.txt", shell=True);
    call("./README_sbas.txt", shell=True);  # Make sbas!
    return;


import math
import itertools
from time import time

class VrpSolver(object):
  def __init__(self, customers, vehicle_count, vehicle_capacity):
    self.CMP_THRESHOLD = 10 ** -6
    self.customers = customers
    assert self.customers[0].demand == 0
    self.c_ct = len(customers)
    self.v_ct = vehicle_count
    self.v_cap = vehicle_capacity
    self.obj = 0
    self.tours = self.greedy_init()
    print(self.obj)
    return

  def __str__(self):
    obj = self.total_tour_dist()
    opt = 0
    if not self.is_valid_soln():
      raise ValueError("Solution not valid")
    output_str = "{:.2f} {}\n".format(obj, opt)
    for tour in self.tours:
      output_str += (' '.join(map(str, [c for c in tour])) + '\n')
    return output_str

  @staticmethod
  def dist(c1, c2):
    return math.sqrt((c1.x - c2.x) ** 2 + (c1.y - c2.y) ** 2)

  def tour_demand(self, tour):
    return sum([self.customers[i].demand for i in tour])

  def have_duplicate_missing(self):
    customers = set(range(1, len(self.customers)))
    for tour in self.tours:
      for c in tour[1:-1]:
        if c not in customers:
          print("Duplicate")
          return True
    if customers:
      print("Missing")
      return True
    return False

  def is_valid_tour(self, tour):
    """
    :param tour: list of int, tour of a single vehicle
    :return: True if tour is valid
    a tour is valid if:
    1. total demand doesn't not exceed vehicle cap
    2. start and end at customer[0], which is the base
    3. does not go back to base during the tour
    4. does not contain duplicate stop
    """
    is_valid = (self.tour_demand(tour) <= self.v_cap) and \
           (tour[0] == 0) and (tour[-1] == 0) and \
           (0 not in tour[1:-1]) and \
           (len(set(tour[1:-1])) == len(tour[1:-1]))
    return is_valid

  def is_valid_soln(self):
    """
    :return: True if the whole solution is valid
    a solution is valid if:
    1. every tour is valid
    2. (TODO)no duplicate/missing customer
    """
    return all([self.is_valid_tour(tour) for tour in self.tours])

  def single_tour_dist(self, tour):
    if not self.is_valid_tour(tour):
      return math.inf
    tour_dist = 0
    for i in range(1, len(tour)):
      customer_1 = self.customers[tour[i - 1]]
      customer_2 = self.customers[tour[i]]
      tour_dist += self.dist(customer_1, customer_2)
    return tour_dist

  def every_tour_dists(self):
    return [self.single_tour_dist(tour) for tour in self.tours]

  def total_tour_dist(self):
    dists = self.every_tour_dists()
    if math.inf in dists:
      raise ValueError("Invalid tour detected.")
    else:
      return sum(dists)

  def greedy_init(self):
    tours = []
    remaining_customers = set(self.customers[1:])
    for v in range(self.v_ct):
      remaining_cap = self.v_cap
      tours.append([])
      tours[-1].append(0)
      while remaining_customers and remaining_cap > min([c.demand for c in remaining_customers]):
        for customer in sorted(remaining_customers, reverse=True, key=lambda c: c.demand):
          if customer.demand <= remaining_cap:
            tours[-1].append(customer.index)
            remaining_cap -= customer.demand
            remaining_customers.remove(customer)
      tours[-1].append(0)
    if remaining_customers:
      raise ValueError("Greedy solution does not exist.")
    else:
      self.tours = tours
      self.obj = self.total_tour_dist()
      return self.tours

  def shift(self, i_from, start_from, end_from, i_to, j_to, debug=False):
    """
    :param i_from: index of tour shift from
    :param start_from: start index of segment
    :param end_from: end index of segment (inclusive)
    :param i_to: index of tour shift to
    :param j_to: location
    :param debug: print details if True
    :return: True if improved
    shift a segment of tour into another tour
    2 possible ways:
    shift directly and reverse after shift
    """
    tour_from_old = self.tours[i_from]
    tour_to_old = self.tours[i_to]
    improved = False
    if debug:
      print("".join(["-"] * 10))
      print("old tours")
      print(tour_from_old)
      print(tour_to_old)

    seg_shift = tour_from_old[start_from: end_from + 1]

    tour_from_new = tour_from_old[:start_from] + tour_from_old[end_from + 1:]
    tour_to_new_1 = tour_to_old[:j_to] + seg_shift + tour_to_old[j_to:]
    tour_to_new_2 = tour_to_old[:j_to] + seg_shift[::-1] + tour_to_old[j_to:]
    if debug:
      print("seg_shift")
      print(seg_shift)
      print("new tours")
      print("{}|{}".format(tour_from_old[:start_from], tour_from_old[end_from + 1:]))
      print("{}|{}|{}".format(tour_to_old[:j_to], seg_shift, tour_to_old[j_to:]))
      print("{}|{}|{}".format(tour_to_old[:j_to], seg_shift[::-1], tour_to_old[j_to:]))

    dist_from_old = self.single_tour_dist(tour_from_old)
    dist_to_old = self.single_tour_dist(tour_to_old)

    dist_from_new = self.single_tour_dist(tour_from_new)

    dist_to_new_1 = self.single_tour_dist(tour_to_new_1)
    dist_to_new_2 = self.single_tour_dist(tour_to_new_2)

    obj_new_1 = self.obj - \
          (dist_from_old + dist_to_old) + \
          (dist_from_new + dist_to_new_1)

    obj_new_2 = self.obj - \
          (dist_from_old + dist_to_old) + \
          (dist_from_new + dist_to_new_2)

    if obj_new_1 < self.obj - self.CMP_THRESHOLD:
      self.tours[i_from] = tour_from_new
      self.tours[i_to] = tour_to_new_1
      # self.obj = obj_new_1
      self.obj = self.total_tour_dist()
      improved = True

    if obj_new_2 < self.obj - self.CMP_THRESHOLD:
      self.tours[i_from] = tour_from_new
      self.tours[i_to] = tour_to_new_2
      # self.obj = obj_new_2
      self.obj = self.total_tour_dist()
      improved = True

    return improved

  def interchange(self, i_1, start_1, end_1, i_2, start_2, end_2, debug=False):
    """
    :param i_1:
    :param start_1:
    :param end_1:
    :param i_2:
    :param start_2:
    :param end_2:
    :param debug:
    :return:
    interchange 2 segments from 2 tours
    4 possible ways:
    interchange directly, reverse either segment, reverse both segments
    """
    tour_1_old = self.tours[i_1]
    tour_2_old = self.tours[i_2]
    improved = False
    if debug:
      print("".join(["-"] * 10))
      print("old tours")
      print(tour_1_old)
      print(tour_2_old)

    seg_1 = tour_1_old[start_1: end_1 + 1]
    seg_2 = tour_2_old[start_2: end_2 + 1]
    if debug:
      print("segs")
      print("{}, {}, {}".format(start_1, end_1, seg_1))
      print("{}, {}, {}".format(start_2, end_2, seg_2))

    # tour1 <- seg2, not reversed
    tour_1_new_1 = tour_1_old[: start_1] + seg_2 + tour_1_old[end_1 + 1:]
    # tour1 <- seg2, reversed
    tour_1_new_2 = tour_1_old[: start_1] + seg_2[::-1] + tour_1_old[end_1 + 1:]
    # tour2 <- seg1, not reversed
    tour_2_new_1 = tour_2_old[: start_2] + seg_1 + tour_2_old[end_2 + 1:]
    # tour2 <- seg1, reversed
    tour_2_new_2 = tour_2_old[: start_2] + seg_1[::-1] + tour_2_old[end_2 + 1:]
    if debug:
      print("new tours")
      print("{}|{}|{}".format(tour_1_old[: start_1], seg_2, tour_1_old[end_1 + 1:]))
      print("{}|{}|{}".format(tour_1_old[: start_1], seg_2[::-1], tour_1_old[end_1 + 1:]))
      print("{}|{}|{}".format(tour_2_old[: start_1], seg_1, tour_2_old[end_2 + 1:]))
      print("{}|{}|{}".format(tour_2_old[: start_1], seg_1[::-1], tour_2_old[end_2 + 1:]))

    # old tour lengths
    dist_1_old = self.single_tour_dist(tour_1_old)
    dist_2_old = self.single_tour_dist(tour_2_old)

    # new tour lengths
    dist_1_new_1 = self.single_tour_dist(tour_1_new_1)
    dist_1_new_2 = self.single_tour_dist(tour_1_new_2)
    dist_2_new_1 = self.single_tour_dist(tour_2_new_1)
    dist_2_new_2 = self.single_tour_dist(tour_2_new_2)

    new_obj_1 = self.obj - (dist_1_old + dist_2_old) + (dist_1_new_1 + dist_2_new_1)
    new_obj_2 = self.obj - (dist_1_old + dist_2_old) + (dist_1_new_1 + dist_2_new_2)
    new_obj_3 = self.obj - (dist_1_old + dist_2_old) + (dist_1_new_2 + dist_2_new_1)
    new_obj_4 = self.obj - (dist_1_old + dist_2_old) + (dist_1_new_2 + dist_2_new_2)

    if new_obj_1 < self.obj - self.CMP_THRESHOLD:
      self.tours[i_1] = tour_1_new_1
      self.tours[i_2] = tour_2_new_1
      # self.obj = new_obj_1
      self.obj = self.total_tour_dist()
      improved = True

    if new_obj_2 < self.obj - self.CMP_THRESHOLD:
      self.tours[i_1] = tour_1_new_1
      self.tours[i_2] = tour_2_new_2
      # self.obj = new_obj_2
      self.obj = self.total_tour_dist()
      improved = True

    if new_obj_3 < self.obj - self.CMP_THRESHOLD:
      self.tours[i_1] = tour_1_new_2
      self.tours[i_2] = tour_2_new_1
      # self.obj = new_obj_3
      self.obj = self.total_tour_dist()
      improved = True

    if new_obj_4 < self.obj - self.CMP_THRESHOLD:
      self.tours[i_1] = tour_1_new_2
      self.tours[i_2] = tour_2_new_2
      # self.obj = new_obj_4
      self.obj = self.total_tour_dist()
      improved = True

    return improved

  def exchange(self, i, start, end, debug=False):
    """
    :param i:
    :param start:
    :param end:
    :param debug:
    :return:
    reverse a segment of a tour
    only 1 way to do this
    """
    improved = False
    tour_old = self.tours[i]
    seg = tour_old[start: end + 1]
    tour_new = tour_old[:start] + seg[::-1] + tour_old[end + 1:]
    if debug:
      print("".join(["-"] * 10))
      print("old tour")
      print(tour_old)
      print("seg")
      print(seg)
      print("new tour")
      print("{}|{}|{}".format(tour_old[:start], seg[::-1], tour_old[end + 1:]))

    new_obj = self.obj - self.single_tour_dist(tour_old) + self.single_tour_dist(tour_new)
    if new_obj < self.obj - self.CMP_THRESHOLD:
      self.tours[i] = tour_new
      # self.obj = new_obj
      self.obj = self.total_tour_dist()
      improved = True
    return improved

  def ladder(self, i_1, i_2, j_1, j_2, debug=False):
    """
    :param i_1:
    :param i_2:
    :param j_1:
    :param j_2:
    :param debug:
    :return:
    split two tours into head and tail respectively, and re-shuffle them
    2 possible ways
    """
    tour_1_old = self.tours[i_1]
    tour_2_old = self.tours[i_2]
    improved = False
    if debug:
      print("".join(["-"] * 10))
      print("old tours")
      print(tour_1_old)
      print(tour_2_old)

    seg_1_head = tour_1_old[:j_1]
    seg_1_tail = tour_1_old[j_1:]
    seg_2_head = tour_2_old[:j_2]
    seg_2_tail = tour_2_old[j_2:]

    # head + tail
    tour_1_new_1 = seg_1_head + seg_2_tail
    tour_2_new_1 = seg_2_head + seg_1_tail

    # head + head(reversed) / tail(reversed) + tail
    tour_1_new_2 = seg_1_head + seg_2_head[::-1]
    tour_2_new_2 = seg_1_tail[::-1] + seg_2_tail
    if debug:
      print("new tours")
      print("{}|{}".format(seg_1_head, seg_2_tail))
      print("{}|{}".format(seg_2_head, seg_1_tail))
      print("{}|{}".format(seg_1_head, seg_2_head[::-1]))
      print("{}|{}".format(seg_1_tail[::-1], seg_2_tail))

    # old tour lengths
    dist_1_old = self.single_tour_dist(tour_1_old)
    dist_2_old = self.single_tour_dist(tour_2_old)

    # new tour lengths
    dist_1_new_1 = self.single_tour_dist(tour_1_new_1)
    dist_1_new_2 = self.single_tour_dist(tour_1_new_2)
    dist_2_new_1 = self.single_tour_dist(tour_2_new_1)
    dist_2_new_2 = self.single_tour_dist(tour_2_new_2)

    new_obj_1 = self.obj - (dist_1_old + dist_2_old) + (dist_1_new_1 + dist_2_new_1)
    new_obj_2 = self.obj - (dist_1_old + dist_2_old) + (dist_1_new_2 + dist_2_new_2)

    if new_obj_1 < self.obj - self.CMP_THRESHOLD:
      self.tours[i_1] = tour_1_new_1
      self.tours[i_2] = tour_2_new_1
      # self.obj = new_obj_1
      self.obj = self.total_tour_dist()
      improved = True

    if new_obj_2 < self.obj - self.CMP_THRESHOLD:
      self.tours[i_1] = tour_1_new_2
      self.tours[i_2] = tour_2_new_2
      # self.obj = new_obj_2
      self.obj = self.total_tour_dist()
      improved = True

    return improved

  def solve(self,
        shift=False,
        interchange=False,
        exchange=True,
        ladder=False,
        tl=None,
        verbose=False,
        debug=False):
    improved = True
    t_start = time()
    iterations = 0

    while improved:
      if tl and time() - t_start >= tl:
        break
      shift_improved = False
      interchange_improved = False
      exchange_improved = False
      ladder_improved = False
      self.obj = self.total_tour_dist()
      prev_obj = self.obj
      if verbose or debug:
        print(self.obj)

      # try shift
      if shift:
        for i_from, tour_from in enumerate(self.tours):
          if shift_improved: break
          for start_from, end_from in itertools.combinations(range(1, len(tour_from) - 1), 2):
            if shift_improved: break
            for i_to, tour_to in enumerate(self.tours):
              if shift_improved: break
              if i_from == i_to: continue
              for j_to in range(1, len(tour_to) - 1):
                if self.shift(i_from, start_from, end_from, i_to, j_to, debug):
                  shift_improved = True
                  break

      # try interchange
      if interchange:
        for i_1, tour_1 in enumerate(self.tours):
          if interchange_improved: break
          for start_1, end_1 in itertools.combinations(range(1, len(tour_1) - 1), 2):
            if interchange_improved: break
            for i_2, tour_2 in enumerate(self.tours):
              if interchange_improved: break
              if i_1 == i_2: continue
              for start_2, end_2 in itertools.combinations(range(1, len(tour_2) - 1), 2):
                if self.interchange(i_1, start_1, end_1, i_2, start_2, end_2, debug):
                  interchange_improved = True
                  break

      # try exchange
      if exchange:
        for i, tour in enumerate(self.tours):
          for start, end in itertools.combinations(range(1, len(tour) - 1), 2):
            if self.exchange(i, start, end, debug):
              exchange_improved = True
              break

      # try ladder
      if ladder:
        for i_1, tour_1 in enumerate(self.tours):
          if ladder_improved: break
          for j_1 in range(2, len(tour_1) - 2):
            if ladder_improved: break
            for i_2, tour_2 in enumerate(self.tours):
              if i_1 == i_2: continue
              if ladder_improved: break
              for j_2 in range(2, len(tour_2) - 2):
                if self.ladder(i_1, i_2, j_1, j_2, debug):
                  ladder_improved = True
                  break
      if verbose or debug:
        print(shift_improved, interchange_improved, exchange_improved, ladder_improved)
      print(iterations, self.obj)
      iterations += 1
      improved = shift_improved or interchange_improved or exchange_improved or ladder_improved
    return self.tours


import pigo
import time  # import just in case students need
import random

# esetup logs
import logging

LOG_LEVEL = logging.INFO
LOG_FILE = "/home/pi/PnR-Final/log_robot.log"  # don't forget to make this file!
LOG_FORMAT = "%(asctime)s %(levelname)s %(message)s"
logging.basicConfig(filename=LOG_FILE, format=LOG_FORMAT, level=LOG_LEVEL)

class Piggy(pigo.Pigo):
    """Student project, inherits teacher Pigo class which wraps all RPi specific functions"""

    def __init__(self):
        """The robot's constructor: sets variables and runs menu loop"""
        print("I have been instantiated!")
        # Our servo turns the sensor. What angle of the servo( ) method sets it straight?
        self.MIDPOINT = 103
        # YOU DECIDE: How close can an object get (cm) before we have to stop?
        self.SAFE_STOP_DIST = 45 #if it is too small then it will get confused
        self.HARD_STOP_DIST = 30
        # YOU DECIDE: What left motor power helps straighten your fwd()?
        self.LEFT_SPEED = 155
        # YOU DECIDE: What left motor power helps straighten your fwd()?
        self.RIGHT_SPEED =150
        # This one isn't capitalized because it changes during runtime, the others don't
        self.turn_track = 0
        # Our scan list! The index will be the degree and it will store distance
        self.scan = [None] * 180
        self.set_speed(self.LEFT_SPEED, self.RIGHT_SPEED)
        # let's use an event-driven model, make a handler of sorts to listen for "events"
        self.left_total=0
        self.right_total=0
        self.A_LITTLE_BIT=3
        if __name__ == "__main__":
            while True:
                self.stop()
                self.menu()

    def menu(self):
        """Displays menu dictionary, takes key-input and calls method"""
        ## This is a DICTIONARY, it's a list with custom index values
        # You may change the menu if you'd like to add an experimental method
        menu = {"n": ("Navigate forward", self.nav),
                "d": ("Dance", self.dance),
                "o": ("Obstacle count", self.obstacle_count),
                "c": ("Calibrate", self.calibrate),
                "s": ("Check status", self.status),
                "h": ("Open House", self.open_house),
                "q": ("Quit", quit_now),
                "t": ("Test", self.skill_test)}
        # loop and print the menu...
        for key in sorted(menu.keys()):
            print(key + ":" + menu[key][0])
        # store the user's answers
        ans = raw_input("Your selection: ")
        # activate the item selected
        menu.get(ans, [None, error])[1]()

    def open_house(self):
        """reacts to distant measurement in a cute way"""
        while True:
            if self.dist() < 20:
                self.set_speed(60, 60)
                self.encB(18)
                self.set_speed(90, 90)
                self.unsure()
                self.skid_back()
                self.encF(28)
            time.sleep(.1)

    def skid_back(self):
        for x in range(3):
            self.encB(2)

    def unsure(self):
        self.set_speed(90, 90)
        self.encF(14)
        self.encB(20)
        for x in range(2):
            for angle in range(self.MIDPOINT - 20, self.MIDPOINT + 20, 10):
                self.servo(angle)

    # YOU DECIDE: How does your GoPiggy dance?
    def dance(self):
        """executes a series of methods that add up to a compound dance"""
        if not self.safe_to_dance():
            print("\n---- NOT SAFE TO DANCE ----\n")
            return
        print("\n---- LET'S DANCE ----\n")
        ##### WRITE YOUR FIRST PROJECT HERE
        for x in range(2):
            self.shuffle_forward()
            self.bob_head()
            self.spin()
            self.shuffle_backwards()
            self.circle_shake()
            self.skid()
            self.shake_head()
            self.fake()
            self.back_up()
            self.turn()
            self.shake_head()
            self.pivot()
            self.spin()
            self.shimmy()
            self.run()
            self.sprinkler_body()
            self.spin()
            self.skid()
            self.sprinkler_body()
            self.bob_head()
            self.shake()
            self.shimmy()
            self.skid()
            self.circle_shake()
            self.sprinkler()

    def shuffle_forward(self):
        """move left right to right and go forward"""
        for x in range(2):
            self.encF(9)
            self.encL(2)
            self.encR(2)
            self.encF(10)

    def bob_head(self):
        """move head side to side"""
        for x in range(self.MIDPOINT - 20, self.MIDPOINT - 20, 5):
            self.servo(x)

    def spin(self):
        """go in circles"""
        self.encL(20)
        self.encR(20)

    def shuffle_backwards(self):
        """move left and write then go back"""
        for x in range(2):
            self.encB(5)
            self.encF(2)
            self.encB(5)

    def skid(self):
        """move minimal amount back and forth"""
        for x in range(3):
            self.encF(1)
            self.encB(1)

    def fake(self):
        """look like going left then go right"""
        self.encF(10)
        self.encL(1)  # fake small move left
        self.encR(5)
        self.encF(10)

    def sprinkler_body(self):
        """move left and right"""
        for x in range(5):
            self.encL(1)
        self.encR(5)  # move pack
        for x in range(5):
            self.encL(1)
        self.encL(5)  # move back

    def back_up(self):
        """move backwards"""
        for x in range(3):
            self.encB(5)
            self.encF(1)
            self.encB(1)

    def turn(self):
        """turn to the side"""
        self.encL(20)
        self.encF(10)  # make a square
        self.encR(20)
        self.encB(10)

    def shake_head(self):
        """shake head quickly one one side"""
        for x in range(3):
            for x in range(self.MIDPOINT - 60, self.MIDPOINT - 16, 10):
                self.servo(x)

    def pivot(self):
        """go in a half circle one point at a time"""
        for x in range(14):  # is this half cirlce?
            self.encL(1)  # move slowly in a half cicle

    def shimmy(self):
        """move left and right"""
        for x in range(3):
            self.encL(3)
            self.encF(1)
            self.encR(3)
            self.encF(1)

    def run(self):
        """start slow and then go"""
        for x in range(2):
            self.encL(1)
            self.encF(1)  # minimal movement
            self.encR(1)
            self.encF(1)
            self.encF(20)  # forward a lot

    def shake(self):
        """move left and right """
        for x in range(5):
            self.encL(2)
            self.encR(2)

    def circle_shake(self):
        """move 90 deg at a time then go back"""
        for x in range(4):
            self.encR(7)  # is this 90 deg?
            self.encB(4)

    def safe_to_dance(self):
        """circles around the room"""
        # check for problems
        for x in range(4):
            if not self.is_clear():
                return False
            self.encR(8)  # is this 90 deg?
        return True

    def sprinkler(self):
        """moves your head like a sprinkler"""
        # repeat the move 5 times
        for x in range(5):
            for angle in range(self.MIDPOINT - 20, self.MIDPOINT + 20, 5):
                self.servo(angle)

        # If we find no problems
        return True

    def obstacle_count(self):
        """scans and estimates the number of obstacles within sight"""
        self.wide_scan()
        found_something = False
        counter = 0
        term_dist = 150
        for ang, distance in enumerate(self.scan):
            if distance and distance < term_dist and not found_something:
                found_something = True
                counter += 1
                print("Object # %d found, I think" % counter)
            if distance and distance > term_dist and found_something:
                found_something = False
        print("\n----I SEE %d OBJECTS----\n" % counter)

    def skill_test(self):
        """demonstrates nav skills"""
        choice = raw_input("left/right or Turn Until Clear")

        if "l" in choice:
            self.wide_scan(count=6)  # scan the area
            # pick left or right

            # create two variables, left_total and right_total
            left_total = 0
            right_total = 0
            # loop from self.MIDPOINT - 60 to self.MIDPOINT
            for angle in range(self.MIDPOINT - 60, self.MIDPOINT):
                if self.scan[angle]:
                    # add up the numbers to right_total
                    right_total += self.scan[angle]
            # loop from self.MIDPOINT to self.MIDPOINT + 60
            for angle in range(self.MIDPOINT, self.MIDPOINT + 60):
                if self.scan[angle]:
                    # add up the numbers to left_total
                    left_total += self.scan[angle]
            # if right is bigger:
            if right_total > left_total:
                # turn right
                self.encR(3)
            # if left is bigger:
            if right_total < left_total:
                # turn left
                self.encL(3)
        else:
            while not self.is_clear():
                self.encR(1)

    def safety_check(self):
        """subroutine of the dance method"""
        self.servo(self.MIDPOINT)  # look straight ahead
        for loop in range(4):
            if not self.is_clear():
                print("NOT GOING TO DANCE")
                return False
            print("Check #%d" % (loop + 1))
            self.encR(8)  # figure out 90 deg
        print("Safe to dance!")
        return True

    def nav(self):
        """auto pilots and attempts to maintain original heading"""
        logging.debug("Starting the nav method")
        print("-----------! NAVIGATION ACTIVATED !------------\n")
        print("-------- [ Press CTRL + C to stop me ] --------\n")
        print("-----------! NAVIGATION ACTIVATED !------------\n")
        count = 0
        error_count = 0

        error_count = 0
        while True:
            if self.is_clear():
                self.cruise()
                error_count = 0 #if the robot get's stuck in a loop
            else:
                error_count += 1 #add everytime it gets stuck
                if error_count == 10:
                    raw_input("Hey, what's up?")
                self.direction_change()

    def direction_change(self):
        """this method helps the robot change direction, it takes the left and right totals to decide where to turn"""
        if self.is_clear():
            self.cruise()

        else:
            self.wide_scan(count=10)
            left_total = 0
            right_total = 0
            for angle in range(self.MIDPOINT -60, self.MIDPOINT): #the MIDPOINT -60 to the mipoint
                if self.scan[angle]:
                    right_total += self.scan[angle] # adding to the right value
            for angle in range(self.MIDPOINT, self.MIDPOINT +60): #adding 60 to the midpoint
                if self.scan[angle]:
                    left_total += self.scan[angle] #adding to the left value
            if right_total < 110 and left_total < 110:
                print("\n\n I MUST BE UP AGAINST A BOX, RIGHT? (%d, %d) \n \n" % (left_total, right_total))
                self.encB(self.A_LITTLE_BIT)
            elif right_total > left_total:
                print("\n\n I'M GOING RIGHT (%d, %d) \n \n" % (left_total, right_total))
                self.encB(self.A_LITTLE_BIT) #moving a set value
                self.encR(self.A_LITTLE_BIT) #turning right
            else:
                print("\n\n I'M GOING LEFT (%d, %d) \n \n" % (left_total, right_total))
                self.encB(self.A_LITTLE_BIT) #turning left
                self.encL(self.A_LITTLE_BIT)

    def front_clear (self):
        """checks the scan array to see if there is a path dead ahead"""
        for ang in range (self.MIDPOINT-30, self.MIDPOINT +30):
            if self.scan[ang] and self.scan[ang] < self.SAFE_STOP_DIST:
                return False

    def cruise(self):
        """ drive straight while path is clear"""
        self.fwd()
        while self.dist() > self.SAFE_STOP_DIST:
            time.sleep(.001) #making it only sleep for a minimal amount of time
        self.stop()

    """def cruise(self):
         pulse drive straight while path is clear

        self.servo(self.MIDPOINT)  # make head straight
        if self.dist() < self.SAFE_STOP_DIST:
            break  # break each time to avoid being stuck in a loop

        self.servo(self.MIDPOINT + 50)  # if 15 degrees from the midpoint is
        if self.dist() > self.SAFE_STOP_DIST:
            break  # pulse drive

        self.servo(self.MIDPOINT - 50)  # looking left?
        if self.dist() > self.SAFE_STOP_DIST:
            return

        self.encF(5)

        self.stop()

    #-this method did not work - but I left it in to show progress- trying to copy the Skill_test method -"""
    def check(self):
        self.wide_scan(count=4)  # scan the area #i would really like the robot to move faster
        left_total = 0
        right_total = 0
        for angle in range(self.MIDPOINT - 60, self.MIDPOINT):
            if self.scan[angle]:
                right_total += self.scan[angle]
        for angle in range(self.MIDPOINT, self.MIDPOINT + 60):
            if self.scan[angle]:
                left_total += self.scan[angle]
        if right_total > left_total:
            self.encR(6)
        elif right_total < left_total:
            self.encL(6)

####################################################
############### STATIC FUNCTIONS

def error():
    """records general, less specific error"""
    logging.error("ERROR")
    print('ERROR')

def quit_now():
    """shuts down app"""
    raise SystemExit

##################################################################
######## The app starts right here when we instantiate our GoPiggy

try:
    g = Piggy()
except (KeyboardInterrupt, SystemExit):
    pigo.stop_now()
except Exception as ee:
    logging.error(ee.__str__())


# -*- coding: utf-8 -*-
from flask import request, current_app
from flask.ext.bouncer import requires, POST
from flask.ext.restful import abort

from api.base_resource import BaseResource
from repo.arkivverdig_info_repo import ArkivverdigInfoRepo
from documents.arkiv import send_to_arkiv

class ArkivverdigInfoProcessorResource(BaseResource):
    @requires(POST, 'ArkivverdigInfo')
    def post(self):
        data = request.get_json()

        batch_size = None
        if data and 'batch_size' in data:
            batch_size = data['batch_size']
            if batch_size <= 0:
                abort(400, __errors__=[u'Invalid batch_size=%s, it has to be a positive integer.'])

        arkivverdig_info_list = ArkivverdigInfoRepo.find_arkivverdig_info_to_send_to_arkiv(
            **({"batch_size": batch_size} if batch_size else {}))

        processed_ids = []
        for arkivverdig_info in arkivverdig_info_list:
            current_app.logger.debug("Sending arkivverdig_info id=%s to arkiv." % arkivverdig_info.id)
            send_to_arkiv(arkivverdig_info)
            ArkivverdigInfoRepo.mark_as_sent(arkivverdig_info)
            processed_ids.append(arkivverdig_info.id)

        return processed_ids, 201


"""
    test_domonic
    ~~~~~~~~~~~~
    unit tests for css
"""

import unittest
# import json
# import requests
# from mock import patch

from domonic.html import *
from domonic.CDN import *

class domonicTestCase(unittest.TestCase):

    def test_domonic_CDN(self):
        myjs = script(_src=CDN_JS.JQUERY_3_5_1)
        print(myjs)

        # css
        mycss = link(_href=CDN_CSS.MARX)
        print(mycss)
        mycss = link(_rel="stylesheet", _href=CDN_JS.JQUERY_3_5_1)
        print(mycss)

        myimg = img(_src=CDN_IMG.PLACEHOLDER(100, 100))
        print(myimg)

if __name__ == '__main__':
    unittest.main()


import json

def load_data(file_path='Бары.json'):
    with open(file_path) as data_file:
        data = json.load(data_file)
    return data

def get_bar_data(bar):
    return bar['Cells']['SeatsCount'], bar['Cells']['Name'], bar['Cells']['Address'], \
               bar['Cells']['geoData']['coordinates'][0], bar['Cells']['geoData']['coordinates'][1]

def print_bar_data(bar_info, bar, coordinates=False):
    seats_count, name, address, longitude, latitude = get_bar_data(bar)
    bar_string = '{bar_info} называется "{name}", в нем {seats_count} мест, находится по адресу "{address}"'
    if coordinates:
         bar_string += "коардинаты: {longitude}, {latitude}"
    bar_string = bar_string.format(bar_info=bar_info, name=name, seats_count=seats_count, address=address,
                                   longitude=str(longitude), latitude=str(latitude))
    print(bar_string)

def get_biggest_bar(data):
    biggest_bar = max(data, key=lambda bar: bar['Cells']['SeatsCount'])
    return biggest_bar

def get_smallest_bar(data, is_bars_without_seats_include_from_user):
    is_bars_without_seats_include_from_user = is_bars_without_seats_include_from_user.lower()
    if is_bars_without_seats_include_from_user == 'n' or is_bars_without_seats_include_from_user == 'нет':
        for num, bar in enumerate(data):
            if not bar['Cells']['SeatsCount']:
                data.pop(num)

    smallest_bar = min(data, key=lambda bar: bar['Cells']['SeatsCount'])
    return smallest_bar

def get_closest_bar(data, longitude, latitude):
    def get_distance(bar):
        return ((longitude - bar['Cells']['geoData']['coordinates'][0])**2 + (latitude - bar['Cells']['geoData']['coordinates'][1])**2) ** .5
    closest_bar = min(data, key=get_distance)
    return closest_bar

if __name__ == '__main__':
    path_to_file = input('введите путь к файлу с данными ')
    longitude = float(input('введите долготу в формате 37.00000000 '))
    latitude = float(input('введите широту в формате 37.00000000 '))
    is_bars_without_seats_include_from_user = input('учитываем ли бары без мест при определении самого маленького? (Y/N)')

    data = load_data(path_to_file)
    biggest_bar = get_biggest_bar(data)
    print_bar_data('самый большой бар', biggest_bar)
    smallest_bar = get_smallest_bar(data, is_bars_without_seats_include_from_user)
    print_bar_data('самый маленький бар', smallest_bar)
    closest_bar = get_closest_bar(data, longitude, latitude)
    print_bar_data('ближайший бар', closest_bar, True)


# -------------
# -- MODULES --
# -------------

from random import randint

# ---------------------
# -- 1ST DECLARATION --
# ---------------------

x = 2
y = 0
# INPUT
def giveInput(query):
    return input(query + " ").lower()
# OUTPUT
def giveOutput(output):
    print(output)

# -------------
# -- CLASSES --
# -------------

#object-Item
class Item(object):
    def __init__(self, itemName):
        self.itemName = itemName
        self.itemType = "untyped"
#object-Item-Weapon
class Weapon(Item):
    def __init__(self, itemName, damage): # NAME DAMAGE
        self.itemName = itemName
        self.damage = damage
        self.itemType = "weapon"
#object-Item-Armour
class Armour(Item):
    def __init__(self, itemName, armourQuality): # NAME ARMOUR
        self.itemName = itemName
        self.armourQuality = armourQuality
        self.itemType = "armour"
#object-Item-Magic
class Magic(Item):
    def __init__(self, itemName, spell, strength): # NAME SPELL STRENGTH
        self.itemName = itemName
        self.spell = spell
        self.strength = strength
        self.itemType = "magic"
    def doSpell(self, enemy, player):
        if self.spell == "weaken":
            self.useMagic(enemy)
        elif self.spell == "shield":
            self.useMagic(player)
        elif self.spell == "fireball":
            self.useMagic(enemy)
        else:
            pass
    def useMagic(self, recipient):
        if self.spell == "weaken":
            recipient.weakness = recipient.weakness * self.strength
        if self.spell == "shield":
            recipient.tempArmourVal = self.strength
            recipient.tempArmour()
        if self.spell == "fireball":
            recipient.health -= self.strength
            recipient.checkLiving()
            giveOutput("You did " + str(self.strength) + " damage!")
#object-Entity
class Entity(object):
    def __init__(self, health = 10, armourValue = 1):
        self.health = health
        self.maxHealth = health
        self.entityType = "untyped"
        self.armourValue = armourValue
        self.weakness = 1
        self.alive = True
    def dealDamage(self, damage, recipient):
        if recipient.alive:
            recipient.health -= round(damage / (recipient.armourValue * self.weakness))
            recipient.checkLiving()
    def checkLiving(self):
        if self.health <= 0:
            self.alive = False
#object-Entity-Enemy
class Enemy(Entity):
    def __init__(self, name, damage = 2, health = 5, armourValue = 1): # NAME DAMAGE HEALTH ARMOUR
        Entity.__init__(self)
        self.entityType = "enemy"
        self.name = name
        self.damage = damage
        self.health = health
        self.armourValue = armourValue
    def attack(self, recipient):
        self.dealDamage(self.damage, recipient)
        giveOutput(
            "You took " + str(
                int(
                    round(self.damage / (recipient.armourValue * self.weakness))
                )
            ) + " damage!"
        )
#object-Entity-Enemy-Mage
class Mage(Enemy):
    def __init__(self, name, damage = 2, health = 5, armourValue = 1): # NAME DAMAGE HEALTH ARMOUR
        Enemy.__init__(self, name, damage, health, armourValue)
        self.entityType = "mage"
    def attack(self, recipient):
        recipient.health -= self.damage
        giveOutput(
            "You took " + str(
                self.damage
            ) + " damage!"
        )
#object-Entity-HealStation
class HealStation(Entity):
    def __init__(self, healStrength): # STRENGTH
        Entity.__init__(self)
        self.entityType = "healer"
        self.healStrength = healStrength
    def heal(self, recipient):
        if self.alive:
            for i in range(1, self.healStrength):
                self.dealDamage(-1 * recipient.armourValue, recipient)
                if recipient.health >= recipient.maxHealth:
                    break
        self.alive = False
#object-Entity-Player
class Player(Entity):
    def __init__(self):
        Entity.__init__(self)
        self.tempArmourVal = 1
        self.entityType = "player"
        self.damage = 1
        self.won = False
        self.inventory = []
        self.equipment = {
            "armour": None,
            "weapon": None,
            "magic": None
        }
    def dealDamage(self, recipient):
        if recipient.alive:
            decideDamage = self.damage / (
                recipient.armourValue * self.weakness * (float(randint(6, 14)) / 10)
            )
            recipient.health -= round(decideDamage)
            recipient.checkLiving()
        return "You did " + str(int(round(decideDamage))) + " damage!"
    def getItem(self, item, secret = False):
        if secret:
            self.inventory.append(item)
        else:
            equipDecision = giveInput("You got a " + item.itemName + ". Equip? (y/n)")
            if equipDecision == "y":
                self.equipItem(item, True)
            else:
                self.inventory.append(item)
    def loseItem(self, item):
        self.inventory.remove(item)
    def equipItem(self, item , force = False):
        if not item in self.inventory:
            if force:
                if type(item) is Armour:
                    if self.equipment["armour"] != None:
                        self.getItem(self.equipment["armour"], True)
                    self.equipment["armour"] = item
                    #self.loseItem(item)
                    self.armourValue = self.equipment["armour"].armourQuality
                    return 0
                elif type(item) is Weapon:
                    if self.equipment["weapon"] != None:
                        self.getItem(self.equipment["weapon"], True)
                    self.equipment["weapon"] = item
                    #self.loseItem(item)
                    self.damage = self.equipment["weapon"].damage
                    return 0
                elif type(item) is Magic:
                    if self.equipment["magic"] != None:
                        self.getItem(self.equipment["magic"], True)
                    self.equipment["magic"] = item
                    #self.loseItem(item)
                    return 0
                else:
                    return 2
            else:
                return 1
        elif item.itemType == "armour":
            if self.equipment["armour"] != None:
                self.getItem(self.equipment["armour"], True)
            self.equipment["armour"] = item
            self.loseItem(item)
            self.armourValue = self.equipment["armour"].armourQuality
            return 0
        elif item.itemType == "weapon":
            if self.equipment["weapon"] != None:
                self.getItem(self.equipment["weapon"], True)
            self.equipment["weapon"] = item
            self.loseItem(item)
            self.damage = self.equipment["weapon"].damage
            return 0
        elif item.itemType == "magic":
            if self.equipment["magic"] != None:
                self.getItem(self.equipment["magic"], True)
            self.equipment["magic"] = item
            self.loseItem(item)
            return 0
        else:
            return 2
    def tempArmour(self):
        self.armourValue = self.armourValue * self.tempArmourVal
    def checkLiving(self):
        if self.health <= 0:
            self.alive = False
        if self.equipment[
            "armour"
        ] != None and self.armourValue != self.equipment[
            "armour"
        ].armourQuality and randint(1,3) == 3:
            self.armourValue = self.equipment["armour"].armourQuality
            giveOutput("~~ You lost your magical shield!")
        elif self.equipment["armour"] == None and self.armourValue != 1 and randint(1,3) == 3:
            self.armourValue = 1
            giveOutput("~~ You lost your magical shield!")
    def fightEnemy(self, enemy):
        giveOutput("You see a " + enemy.name + " with " + str(enemy.health) + " health!")
        while True:
            fightIn = giveInput("What do you do? (attack, magic, equip)")
            if fightIn == "attack":
                giveOutput(self.dealDamage(enemy))
                if not enemy.alive:
                    giveOutput("You defeated the " + enemy.name + "!")
                    break
            elif fightIn == "magic":
                if self.equipment["magic"] == None:
                    giveOutput("You don't have any magic equipped!")
                    continue
                else:
                    self.equipment["magic"].doSpell(enemy, self)
                    if not enemy.alive:
                        giveOutput("You defeated the " + enemy.name + "!")
                        break
            elif fightIn == "equip":
                itemToEquip = object()
                giveOutput("Items to equip: \n")
                for i in ["'" + item.itemName.title() + "'\n" for item in self.inventory]:
                    giveOutput(" - " + i)
                itemNameToEquip = giveInput("Which do you equip?")
                for item in self.inventory:
                    if item.itemName == itemNameToEquip:
                        itemToEquip = item
                        break
                equipError = self.equipItem(itemToEquip)
                if equipError == 0:
                    giveOutput("Equipping successful!")
                elif equipError == 1:
                    giveOutput("Item doesn't exist!")
                elif equipError == 2:
                    giveOutput("Item is not equippable!")
                else:
                    pass
                continue
            else:
                giveOutput("Choose either 'attack', 'magic' or 'equip'")
                continue
            enemy.attack(self)
            giveOutput("- your health: " + str(int(self.health)))
            giveOutput("- " + enemy.name + "'s health: " + str(int(enemy.health)))
            if not self.alive:
                Area([Layer(None, None, True)]).enterArea(self)
                break
#object-Layer
class Layer(object):
    def __init__(self, items = None, enemy = None, hell = False, autoWin = False):
        self.items = items
        self.enemy = enemy
        self.hell = hell
        self.autoWin = autoWin
    def enterLayer(self, playerIn):
        if self.hell:
            giveOutput("-------------- \nYou lose!")
            mainLoopCondition = False
        elif self.autoWin:
            playerIn.won = True
        else:
            if self.items != None:
                for item in self.items:
                    playerIn.getItem(item)
            if self.enemy != None:
                if type(self.enemy) is HealStation:
                    doHeal = giveInput("You found medical supplies. Heal? (y/n)")
                    if doHeal == "y":
                        self.enemy.heal(playerIn)
                        giveOutput("You now have " + str(int(playerIn.health)) + " health!")
                else:
                    playerIn.fightEnemy(self.enemy)
#object-Area
class Area(object):
    def __init__(self, layers, finalArea = False):
        self.layers = layers
        self.finalArea = finalArea
        self.areaType = ""
        self.story = ""
    def enterArea(self, playerIn, areaType = "path"):
        self.areaType = areaType
        #giveOutput(self.areaType) #DEBUG
        if self.story == "":
            self.story = self.generateStory()
        layerNum = 0
        giveOutput(self.story)
        for layer in self.layers:
            #giveOutput(" -- layer: " + str(layerNum)) #DEBUG
            layer.enterLayer(playerIn)
            #giveOutput(" - alive: " + str(thePlayer.alive) + " won: " + str(thePlayer.won)) #DEBUG
            layerNum += 1
    def generateStory(self):
        if self.areaType == "path":
            return "\n~ This path is over " + str(
                randint(1,30) * 100
            ) + " years old, and was used by the " + races[randint(0, len(races) - 1)] + ".\n"
        elif self.areaType == "castle":
            return "\n~ This castle was built " + str(
                randint(1,20) * 10
            ) + " years ago to protect from the " + races[randint(0, len(races) - 1)] + ".\n"
        elif self.areaType == "cave":
            return "\n~ Once, this cave housed one of the five mighty dragons of the land, \
vanquished by a true hero. You must kill the mightiest of them all.\n"
        elif self.areaType == "village":
            return "\n~ This village used to be inhabited, but was fled due to a raid " + str(
                randint(2,50) * 10
            ) + " years ago by the " + races[randint(0, len(races) - 1)] + ".\n"
        else:
            return "<AREA TYPE ERROR>"
# --------------------------
# -- FUNCTION DECLARATION --
# --------------------------

# LEFT/RIGHT CHOICE
def leftOrRight(lr):
    global x
    global y
    if lr.lower() == "left":
        x -= 1
        y += 1
        return 0
    elif lr.lower() == "right":
        x += 1
        y += 1
        return 0
    else:
        return 1

# -----------------------
# -- OTHER DECLARATION --
# -----------------------
areas = [
    # *,0
    [
        # 0,0
        None,
        # 1,0
        None,
        # 2,0
        Area([
            # 2,0 L0
            Layer()
        ]),
        # 3,0
        None,
        # 4,0
        None
    ],
    # *,1
    [
        # 0,1
        None,
        # 1,1
        Area([
            # 1,1 L0
            Layer(None, Enemy("gel", 1, 1, 1)),
            # 1,1 L1
            Layer([Weapon("sword made of iron", 2)])
        ]),
        # 2,1
        None,
        # 3,1
        Area([
            # 3,1 L0
            Layer(None, Enemy("gel", 1, 1, 1)),
            # 3,1 L1
            Layer([Armour("piece of iron armour", 1.3)])
        ]),
        # 4,1
        None
    ],
    # *,2
    [
        # 0,2
        Area([
            # 0,2 L0
            Layer(None, Enemy("skeleton", 2, 4, 1)),
            # 0,2 L1
            Layer([Armour("piece of leather padding", 1.1)]),
            # 0,2 L2
            Layer(None, Enemy("big gel", 1, 4, 1)),
            # 0,2 L3
            Layer(None, Enemy("gel", 1, 1, 1)),
            # 0,2 L4
            Layer(None, Enemy("gel", 1, 1, 1))
        ]),
        # 1,2
        None,
        # 2,2
        Area([
            # 2,2 L0
            Layer([Magic("spell of the arcane bolt", "fireball", 2)]),
            # 2,2 L1
            Layer(None, Enemy("dark knight", 4, 3, 3)),
            # 2,2 L2
            Layer(None, Mage("mage", 2, 2, 2))
        ]),
        # 3,2
        None,
        # 4,2
        Area([
            # 4,2 L0
            Layer([Magic("spell of entanglement", "weaken", 1.4), Weapon("club", 2)]),
            # 4,2 L1
            Layer(None, Enemy("rogue", 4, 3, 1)),
            # 4,2 L2
            Layer(None, Enemy("skeleton", 2, 4, 1))
        ])
    ],
    # *,3
    [
        # 0,3
        None,
        # 1,3
        Area([
            # 1,3 L0
            Layer(None, HealStation(4)),
            # 1,3 L1
            Layer([Weapon("sword with a blue aura", 5)]),
            # 1,3 L2
            Layer(None, Enemy("rock golem", 3, 6, 2)),
            # 1,3 L3
            Layer([Magic("spell of arcane shield", "shield", 1.8)], Enemy("heinous adventurer", 2, 10, 1.1))
        ]),
        # 2,3
        None,
        # 3,3
        Area([
            # 3,3 L0
            Layer(None, HealStation(6)),
            # 3,3 L1
            Layer([Magic("spell of fire destruction", "fireball", 4)]),
            # 3,3 L2
            Layer([Weapon("sword made of dragonsteel", 3)], Enemy("cyclops", 2, 8, 6)),
            # 3,3 L3
            Layer(None, Enemy("big skeleton", 2, 12, 0.4))
        ]),
        # 4,3
        None
    ],
    # *,4
    [
        # 0,4
        None,
        # 1,4
        None,
        # 2,4
        Area([
            # 2,4 L0
            Layer(None, Enemy("rock elemental", 4, 6, 3)),
            # 2,4 L1
            Layer(None, HealStation(1)),
            # 2,4 L2
            Layer(), # mage?
            # 2,4 L3
            Layer(None, HealStation(4)),
            # 2,4 L4
            Layer(),
            # 2,4 L5
            Layer(),
            # 2,4 L6
            Layer(),
            # 2,4 L7
            Layer(),
            # 2,4 L8
            Layer(None, None, False, True)
        ], True),
        # 3,4
        None,
        # 4,4
        None
    ]
]

twoPaths = ["path", "cave", "castle", "village"]

races = ["dwarves", "elves", "goblins", "orcs"]

areaTypeRandom = twoPaths[randint(0, len(twoPaths) - 1)]

lrError = 0

mainLoopCondition = True

thePlayer = Player()

# ---------------
# -- MAIN LOOP --
# ---------------

while mainLoopCondition:
    #giveOutput(" --- x: " + str(x) + " y: " + str(y)) #DEBUG
    #giveOutput(areaTypeRandom) #DEBUG
    areas[y][x].enterArea(thePlayer, areaTypeRandom)
    if thePlayer.won:
        giveOutput("You win!\n")
        break
    if x == 0:
        x += 1; y += 1
    elif x == len(areas[0]) - 1:
        x -= 1; y += 1
    else:
        if areas[y + 1][x + 1] != None and areas[y + 1][x - 1] != None:
            if lrError == 0:
                areaTypeRandom = twoPaths[randint(0, len(twoPaths) - 1)]
            lrError = leftOrRight(
                giveInput(
                    "\nThere are two " + areaTypeRandom + "s: left and right. Which do you pick?"
                )
            )
        elif areas[y + 1][x + 1] == None and areas[y + 1][x - 1] != None:
            x -= 1; y += 1
            areaTypeRandom = twoPaths[randint(0, len(twoPaths) - 1)]
        elif areas[y + 1][x + 1] != None and areas[y + 1][x - 1] == None:
            x += 1; y += 1
            areaTypeRandom = twoPaths[randint(0, len(twoPaths) - 1)]
giveOutput("Restart game to try again.")


from util.common import Common
import datetime
from domain.command import Command
import sys

class Console(object):
    """Console based user interface."""
    def __init__(self,person_controller,activity_controller,participation_controller):
        self.__person_controller = person_controller
        self.__activity_controller = activity_controller
        self.__participation_controller = participation_controller

    def read_command_index(self):
        cmd_index = input("command:")

        if not Common.get_type(cmd_index) is int:
            raise ValueError("Command index must be an integer.")

        return int(cmd_index)

    def execute_command(self,command:Command):
        raw_input = []
        count = 0

        # read the needed arguments in order to execute the command
        for func_name,args in command.arguments.items():
            raw_input.append([])
            for arg in args:
                raw_input[count].append(input(arg.name+":"))
            count += 1

        if len(raw_input)>1:
            return command.execute(raw_input[0],raw_input[1])

        return command.execute(raw_input[0])

    def print_commands(self,commands):
        for key in commands:
            print("{0}.{1}".format(key,commands[key].name))

    def print_participations(self,participations:list):
        for p in participations:
            print(p,self.__activity_controller.find_by_id(p.activity_id))

    def exit(self):
        raise SystemExit

    def load_predefinded_data(self):
        self.__person_controller.add(1,"John0","1234567890","str1")
        self.__person_controller.add(2,"John1","1234567890","str1")
        self.__person_controller.add(3,"John2","1234567890","str1")

        self.__activity_controller.add(1,Common.convert_to_date("15.11.2016"),Common.convert_to_time("06:03"),"description")
        self.__activity_controller.add(2,Common.convert_to_date("16.11.2016"),Common.convert_to_time("06:03"),"description")
        self.__activity_controller.add(3,Common.convert_to_date("16.11.2016"),Common.convert_to_time("06:04"),"description")
        self.__activity_controller.add(4,Common.convert_to_date("16.11.2016"),Common.convert_to_time("06:06"),"description")
        self.__activity_controller.add(5,Common.convert_to_date("16.11.2016"),Common.convert_to_time("06:07"),"description")
        self.__activity_controller.add(6,Common.convert_to_date("23.11.2016"),Common.convert_to_time("06:07"),"description")

        self.__participation_controller.add(1,1,1)
        self.__participation_controller.add(2,2,1)
        self.__participation_controller.add(3,1,2)
        self.__participation_controller.add(4,1,2)
        self.__participation_controller.add(5,3,2)
        self.__participation_controller.add(6,3,6)

    def run(self):
        commands = {1:Command("add person",self.__person_controller.add),
                    2:Command("remove person",self.__participation_controller.delete_person),
                    3:Command("update person",self.__person_controller.update),
                    4:Command("list persons",Common.print_iterable,"iterable",arg=self.__person_controller.get_all),
                    5:Command("add activity",self.__activity_controller.add),
                    6:Command("remove activity",self.__participation_controller.delete_activity),
                    7:Command("update activity",self.__activity_controller.update),
                    8:Command("list activities",Common.print_iterable,"iterable",arg=self.__activity_controller.get_all),
                    9:Command("add participation",self.__participation_controller.add),
                    10:Command("remove participation",self.__participation_controller.remove),
                    11:Command("update participation",self.__participation_controller.update),
                    12:Command("list participations",self.print_participations,"participations",arg=self.__participation_controller.get_all),
                    13:Command("search person by name",Common.print_iterable,"iterable",arg=self.__person_controller.find_by_name),
                    14:Command("search person by phone number",Common.print_iterable,"iterable",arg=self.__person_controller.find_by_phone_number),
                    15:Command("search participation by date",self.print_participations,"participations",arg=self.__participation_controller.find_by_activity_date),
                    16:Command("search participation by time",self.print_participations,"participations",arg=self.__participation_controller.find_by_activity_time),
                    17:Command("search participation by description",self.print_participations,"participations",arg=self.__participation_controller.find_by_activity_description),
                    18:Command("statistics participation by day",self.print_participations,"participations",arg=self.__participation_controller.statistics_activity_by_day),
                    19:Command("statistics participation by week",self.print_participations,"participations",arg=self.__participation_controller.statistics_activity_by_week),
                    20:Command("statistics participation busiest",Common.print_iterable,"iterable",arg=self.__participation_controller.statistics_sorted_busiest),
                    21:Command("statistics participation persons",Common.print_iterable,"iterable",arg=self.__participation_controller.statistics_sorted_persons),
                    22:Command("exit",self.exit)
                    }

        self.load_predefinded_data()
        self.print_commands(commands)

        while True:
            try:
                cmd_index = self.read_command_index()

                if cmd_index<1 or cmd_index>len(commands):
                    print("No command with id {0} exists.".format(cmd_index))

                self.execute_command(commands[cmd_index])
            except Exception as ex:
                print(ex)


from functions import *

def ant_miner(dataset, no_of_ants, min_case_per_rule, max_uncovered_cases, no_rules_converg):

    training_dataset = copy.deepcopy(dataset)
    discovered_rule_list = []

    dataset_stagnation_test = 0
    no_of_remaining_cases = len(training_dataset.data)

    while no_of_remaining_cases > max_uncovered_cases:

        last_no_of_remaining_cases = no_of_remaining_cases

        if no_of_remaining_cases == last_no_of_remaining_cases:
            dataset_stagnation_test += 1

        if dataset_stagnation_test == no_rules_converg:
            # print('Dataset length stagnation')
            break

        ant_index = 0
        converg_test_index = 1
        list_of_current_rules = []
        list_of_current_rules_quality = []

        list_of_terms = get_terms(training_dataset.attr_values)
        list_of_terms = set_pheromone_init(list_of_terms)
        list_of_terms = set_heuristic_values(list_of_terms, training_dataset)

        while True:

            if ant_index == no_of_ants:
                # print('Rule iteration: exceeded no_of_ants')
                break
            elif converg_test_index == no_rules_converg:
                # print('Rule iteration: rule converged')
                break

            current_rule = rule_construction(list_of_terms, min_case_per_rule, training_dataset)

            if current_rule is None:
                # print('Empty rule')
                ant_index += 1
                converg_test_index += 1
                continue

            current_rule.set_quality(training_dataset)

            current_rule_pruned = rule_pruning(current_rule, min_case_per_rule, training_dataset)

            converg_test_index = check_convergence(current_rule_pruned, list_of_current_rules, converg_test_index)

            if converg_test_index == 1:
                list_of_current_rules.append(current_rule_pruned)
                list_of_current_rules_quality.append(current_rule_pruned.quality)

            list_of_terms = pheromone_updating(list_of_terms, current_rule_pruned)

            ant_index += 1

        if not list_of_current_rules_quality:
            continue

        best_rule_idx = list_of_current_rules_quality.index(max(list_of_current_rules_quality))
        best_rule = copy.deepcopy(list_of_current_rules[best_rule_idx])
        discovered_rule_list.append(best_rule)

        covered_cases = np.array(best_rule.covered_cases)
        training_dataset.data = np.delete(training_dataset.data, covered_cases, axis=0)
        training_dataset.data_updating()
        no_of_remaining_cases = len(training_dataset.data)

    # generating rule for remaining cases
    rule_for_remaining_cases = get_remaining_cases_rule(training_dataset)
    discovered_rule_list.append(rule_for_remaining_cases)

    return discovered_rule_list, training_dataset, no_of_remaining_cases


s1 = 'adc'
s2 = 'dcda'

class Solution:
    def checkInclusion(self, s1, s2):
        """
        :type s1: str
        :type s2: str
        :rtype: bool
        """
        from collections import Counter

        window = len(s1)
        idx = 0
        c1 = Counter(s1)

        while idx+window <= len(s2):
            c2 = Counter(s2[idx:idx+window])
            if c1 == c2:
                return True
            idx += 1
        return False

if __name__ == '__main__':
    leetcode = Solution()
    print(leetcode.checkInclusion(s1, s2))