import pandas as pd

def GoodBets(data):
    good_bets = pd.DataFrame(columns=data.columns)
    res = pd.DataFrame(columns=data.columns)
    prediction = []
    for index, bet in data.iterrows():
        match_prediction = []

        if (bet['HTMatches'] > 3) & (bet['ATMatches'] > 3):

            # HOME
            if 1.53 < bet.AvgCH <= 1.67:
                if Home(bet, 1.06, 0.99, 1.3, 0):
                    good_bets.loc[len(good_bets)] = bet
                    match_prediction.append('Home')
            elif 1.67 < bet.AvgCH <= 2.12:
                continue
            elif 2.12 < bet.AvgCH <= 3.16:
                if Home(bet, 0.98, 1.01, 1, 1):
                    good_bets.loc[len(good_bets)] = bet
                    match_prediction.append('Home')
            elif 3.16 < bet.AvgCH <= 4.2:
                if Home(bet, 1.05, 0.99, 0.6, 0.4):
                    good_bets.loc[len(good_bets)] = bet
                    match_prediction.append('Home')

            # DRAW
            if 2 < bet.AvgCD <= 3.2:
                if Draw(bet, 1.14, 1.01, 0.7, 0.8):
                    good_bets.loc[len(good_bets)] = bet
                    match_prediction.append('Draw')
            elif 3.2 < bet.AvgCD <= 3.5:
                if Draw(bet, 0.89, 0.99, 0.5, 0.8):
                    good_bets.loc[len(good_bets)] = bet
                    match_prediction.append('Draw')
            elif 3.5 < bet.AvgCD <= 3.95:
                if Draw(bet, 0.97, 0.98, 1.4, 0.6):
                    good_bets.loc[len(good_bets)] = bet
                    match_prediction.append('Draw')
            elif 3.95 < bet.AvgCD <= 5.4:
                if Draw(bet, 0.8, 0.97, 0.2, 0.5):
                    good_bets.loc[len(good_bets)] = bet
                    match_prediction.append('Draw')

            # AWAY
            if 1.4 < bet.AvgCA <= 1.46:
                if Away(bet, 1.3, 1.05, 3, 1.5):
                    good_bets.loc[len(good_bets)] = bet
                    match_prediction.append('Away')
            elif 1.46 < bet.AvgCA <= 2:
                if Away(bet, 1.1, 1, 0.3, 0.6):
                    good_bets.loc[len(good_bets)] = bet
                    match_prediction.append('Away')
            elif 2 < bet.AvgCA <= 3.16:
                if Away(bet, 1.03, 1.03, 2, 1.5):
                    good_bets.loc[len(good_bets)] = bet
                    match_prediction.append('Away')
            elif 3.16 < bet.AvgCA <= 3.7:
                if Away(bet, 1.3, 0.99, 0.5, 1.5):
                    good_bets.loc[len(good_bets)] = bet
                    match_prediction.append('Away')
            elif 3.7 < bet.AvgCA <= 4.2:
                if Away(bet, 1.02, 0.95, 0.5, 1.2):
                    good_bets.loc[len(good_bets)] = bet
                    match_prediction.append('Away')

            # HomeDraw
            elif 1.35 < bet.DoubleChanceHD <= 1.36:
                if HomeDraw(bet, 1.1, 0.99, 0.8, 0.7):
                    good_bets.loc[len(good_bets)] = bet
                    match_prediction.append('Home or Draw')
            elif 1.36 < bet.DoubleChanceHD <= 1.5:
                if HomeDraw(bet, 0.99, 0.98, 1.3, 0.9):
                    good_bets.loc[len(good_bets)] = bet
                    match_prediction.append('Home or Draw')
            elif 1.5 < bet.DoubleChanceHD <= 1.63:
                if HomeDraw(bet, 0.94, 0.99, 0.5, 0.5):
                    good_bets.loc[len(good_bets)] = bet
                    match_prediction.append('Home or Draw')
            elif 1.63 < bet.DoubleChanceHD <= 1.9:
                if HomeDraw(bet, 1, 0.99, 0.3, 0.2):
                    good_bets.loc[len(good_bets)] = bet
                    match_prediction.append('Home or Draw')

            # AwayDraw
            if 1.25 < bet.DoubleChanceAD <= 1.36:
                if AwayDraw(bet, 1.3, 1.04, 1.2, 1.5):
                    good_bets.loc[len(good_bets)] = bet
                    match_prediction.append('Away or Draw')
            elif 1.36 < bet.DoubleChanceAD <= 1.5:
                if AwayDraw(bet, 1.3, 1.06, 1.9, 1.2):
                    good_bets.loc[len(good_bets)] = bet
                    match_prediction.append('Away or Draw')

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

            prediction = prediction + match_prediction

    good_bets['Prediction'] = prediction
    return good_bets

def Home(bet, bookie, rating, points, goals):
    if (bet.HomeProb/bet.AvgCH < bookie) & (bet.HTRating / bet.ATRating > rating) & (bet.HTPoints5 /(bet.ATPoints5 + 0.0001) > points) & ((bet.HTMGS / (bet.HTMGC + 0.0001))/(bet.ATMGS / (bet.ATMGC + 0.0001) + 0.0001) > goals):
        return True
    return False

def Draw(bet, bookie, rating, points, goals):
    if (bet.DrawProb/bet.AvgCD < bookie) & (bet.HTRating / bet.ATRating > rating) & (bet.HTPoints5 /(bet.ATPoints5 + 0.0001) > points) & ((bet.HTMGS / (bet.HTMGC + 0.0001))/(bet.ATMGS / (bet.ATMGC + 0.0001) + 0.0001) > goals):
        return True
    return False

def Away(bet, bookie, rating, points, goals):
    if (bet.AwayProb/bet.AvgCA < bookie) & (bet.ATRating / bet.HTRating > rating) & (bet.ATPoints5 /(bet.HTPoints5 + 0.0001) > points) & ((bet.ATMGS / (bet.ATMGC + 0.0001))/(bet.HTMGS / (bet.HTMGC + 0.0001) + 0.0001) > goals):
        return True
    return False

def HomeDraw(bet, bookie, rating, points, goals):
    if (bet.HD_Prob/bet.DoubleChanceHD < bookie) & (bet.HTRating / bet.ATRating > rating) & (bet.HTPoints5 /(bet.ATPoints5 + 0.0001) > points) & ((bet.HTMGS / (bet.HTMGC + 0.0001))/(bet.ATMGS / (bet.ATMGC + 0.0001) + 0.0001) > goals):
        return True
    return False

def HomeAway(bet, bookie, rating, points, goals):
    if (bet.HA_Prob/bet.DoubleChanceHA < bookie) & (bet.HTRating / bet.ATRating > rating) & (bet.HTPoints5 /(bet.ATPoints5 + 0.0001) > points) & ((bet.HTMGS / (bet.HTMGC + 0.0001))/(bet.ATMGS / (bet.ATMGC + 0.0001) + 0.0001) > goals):
        return True
    return False

def AwayDraw(bet, bookie, rating, points, goals):
    if (bet.AD_Prob/bet.DoubleChanceAD < bookie) & (bet.ATRating / bet.HTRating > rating) & (bet.ATPoints5 /(bet.HTPoints5 + 0.0001) > points) & ((bet.ATMGS / (bet.ATMGC + 0.0001))/(bet.HTMGS / (bet.HTMGC + 0.0001) + 0.0001) > goals):
        return True
    return False


"""
Avaible commands: .stickertoimage
"""
from telethon import events
from telethon.errors.rpcerrorlist import YouBlockedUserError

from userbot.utils import lightning_cmd

@borg.on(lightning_cmd(pattern="stickertoimage ?(.*)"))
async def _(event):
    if event.fwd_from:
        return
    if not event.reply_to_msg_id:
        await event.edit("```Reply to any user message.```")
        return
    reply_message = await event.get_reply_message()
    if not reply_message.media:
        await event.edit("```Reply to sticker message```")
        return
    chat = "@DownloadStickersBot"
    reply_message.sender
    if reply_message.sender.bot:
        await event.edit("```Reply to actual users message.```")
        return
    await event.edit("```Making a sticker to image```")
    async with event.client.conversation(chat) as conv:
        try:
            response = conv.wait_event(
                events.NewMessage(incoming=True, from_users=658563529)
            )
            await event.client.forward_messages(chat, reply_message)
            response = await response
        except YouBlockedUserError:
            await event.reply("```Please unblock me (@DownloadStickersBot) ```")
            return
        if response.text.startswith("Hi!"):
            await event.edit(
                "```Can you kindly disable your forward privacy settings for good?```"
            )
        else:
            await event.delete()
            await event.client.send_message(event.chat_id, response.message)


import os

import matplotlib.pyplot as plt
import numpy as np

from FileProcess.GraphClass import Graph

work_dir = '../data/Mmusculus/Full'
file_list = os.listdir(work_dir)
work_dir2 = '../data/Mmusculus/Full/Cleann'
file_list2 = os.listdir(work_dir2)
print(file_list)
print(file_list2)

n_vert_list_total = []
n_vert_list_nemo = []
n_list_profile = []
relative_frequency = []

cnt = 0
for i in range(len(file_list)):
    rel_freq = []
    filename = file_list[i]
    graph = Graph()
    curPath = work_dir + '/' + filename
    if os.path.isfile(curPath):
        with open(curPath) as f:
            first = True
            for line in f:
                if first:
                    first = False
                    continue
                v1, v2, w = line.split('\t', 2)
                id1 = v1.split('|')[0]
                id2 = v2.split('|')[0]
                graph.add_edge(id1, id2)

        verts = dict.fromkeys(graph.vertices.keys())
        gg = {}

        print(curPath)
        curPath = work_dir + '/Cleann/' + file_list2[cnt]
        print(curPath)
        with open(curPath) as f:
            for line in f:
                if not line.startswith('DIP'):
                    if line.startswith('CF') or line.startswith('CN') or line.startswith('C^') \
                            or line.startswith('C~') or line.startswith('CR') or line.startswith('Cr'):
                        rel_freq.append(float(line.split()[1].replace('%', '')))
                    continue
                else:
                    ll = list(line.split())
                    verts[ll[0]] = list(map(int, ll[1:]))
                    gg[ll[0]] = list(map(int, ll[1:]))
        print('length of nemoprofile nodes and original vertices', len(gg), len(verts))
        profile = [0 for x in range(6)]

        for v in gg:
            for j in range(len(gg[v])):
                profile[j] += gg[v][j]

        for j in range(len(profile)):
            profile[j] = profile[j] / 4
        print(profile)
        n_vert_list_total.append(len(verts))
        n_vert_list_nemo.append(len(gg))
        n_list_profile.append(profile)
        cnt += 1
        relative_frequency.append(rel_freq)

print(relative_frequency)
print(n_vert_list_total)
print(n_vert_list_nemo)
# print(n_list_profile)
# label = ['CF', 'CN', 'CR', 'C^', 'Cr', 'C~']
label = ['CF', 'CN', 'CR', 'C^', 'Cr', 'C~']
n_list_profile = np.array(n_list_profile)

n_list_profile_change = []

# print(n_list_profile)
gens = list(range(0, 10))
plt.xlabel("Generation")
plt.ylabel("Number of node")
plt.title("Node number vs Generations")
for i in range(6):
    temp_list = []
    prev = n_list_profile[:, i][0]
    for temp in n_list_profile[:, i]:
        temp_list.append(temp - prev)
    n_list_profile_change.append(temp_list)

for i in range(6):
    plt.plot(gens, n_list_profile_change[i], label=label[i])

plt.legend()
plt.show()

n_list_profile_change_per = []

for i in range(6):
    temp_list = []
    prev = n_list_profile[:, i][0]
    for temp in n_list_profile[:, i]:
        temp_list.append(100 * (temp - prev) / prev)
    n_list_profile_change_per.append(temp_list)

plt.xlabel("Generation")
plt.ylabel("Percentage of node number change")
plt.title("Percentage Change vs Generations")
for i in range(6):
    plt.plot(gens, n_list_profile_change_per[i], label=label[i])

plt.legend()
plt.show()

label = ['CF', 'CN', 'C^', 'C~', 'CR', 'Cr']

relative_frequency = np.array(relative_frequency)
rel_list = []
for i in range(6):
    temp_list = []
    for temp in relative_frequency[:, i]:
        temp_list.append(temp)
    rel_list.append(temp_list)

for i in range(6):
    plt.xlabel("Generation")
    plt.ylabel("Relative frequency")
    plt.title("Relative frequency vs Generations")
    plt.plot(gens, rel_list[i], label=label[i])
    plt.legend()
    plt.show()

plt.xlabel("Generation")
plt.ylabel("Relative frequency")
plt.title("Relative frequency vs Generations")
for i in range(6):
    plt.plot(gens, rel_list[i], label=label[i])
plt.legend()
plt.show()


# Union-Find算法实现

class UF:
    def __init__(self, n):
        self.count = n
        self.parent = [0 for _ in range(n)]
        self.size = [0 for _ in range(n)]       # size记录树的权重
        for i in range(n):
            self.parent[i] = i
            self.size[i] = 1

    def union(self, p, q):
        rootP = self.find(p)
        rootQ = self.find(q)
        if rootP == rootQ:
            return

        # 小树接到大树下面，较平衡
        if self.size[rootP] > self.size[rootQ]:
            self.parent[rootQ] = self.parent[rootP]
            self.size[rootP] += self.size[rootQ]
        else:
            self.parent[rootP] = self.parent[rootQ]
            self.size[rootQ] += self.size[rootP]
        self.count -= 1

    def connected(self, p, q):
        # 判断p和q是否互相连通
        rootP = self.find(p)
        rootQ = self.find(q)
        return rootP == rootQ

    def find(self, x):
        # 返回某个节点x的根节点
        while self.parent[x] != x:
            # 进行路径压缩
            self.parent[x] = self.parent[self.parent[x]]
            x = self.parent[x]
        return x

    def count(self):
        return self.count


from __future__ import (
    unicode_literals,
    print_function,
    absolute_import,
    division,
    )

import sys
import os
import optparse
import textwrap
import logging
import locale
import traceback
import glob
from itertools import chain

try:
    # Optionally import optcomplete (for auto-completion) if it's installed
    import optcomplete
except ImportError:
    optcomplete = None

# Use the user's default locale instead of C
locale.setlocale(locale.LC_ALL, '')

# Set up a console logging handler which just prints messages without any other
# adornments
_CONSOLE = logging.StreamHandler(sys.stderr)
_CONSOLE.setFormatter(logging.Formatter('%(message)s'))
_CONSOLE.setLevel(logging.DEBUG)
logging.getLogger().addHandler(_CONSOLE)

def normalize_path(path):
    """
    Eliminates symlinks, makes path absolute and normalizes case
    """
    return os.path.normcase(os.path.realpath(os.path.abspath(
        os.path.expanduser(path)
    )))

def glob_arg(arg):
    """
    Perform shell-style globbing of arguments
    """
    if set('*?[') & set(arg):
        args = glob.glob(normalize_path(arg))
        if args:
            return args
    # Return the original parameter in the case where the parameter contains no
    # wildcards or globbing returns no results
    return [arg]

def flatten(arg):
    """
    Flatten one level of nesting
    """
    return chain.from_iterable(arg)

def expand_args(args):
    """
    Expands @response files and wildcards in the command line
    """
    windows = sys.platform.startswith('win')
    result = []
    for arg in args:
        if arg.startswith('@') and len(arg) > 1:
            arg = normalize_path(arg[1:])
            try:
                with open(arg, 'rU') as resp_file:
                    for resp_arg in resp_file:
                        # Only strip the line break (whitespace is
                        # significant)
                        resp_arg = resp_arg.rstrip('\n')
                        # Only perform globbing on response file values for
                        # UNIX
                        if windows:
                            result.append(resp_arg)
                        else:
                            result.extend(glob_arg(resp_arg))
            except IOError as exc:
                raise optparse.OptionValueError(str(exc))
        else:
            result.append(arg)
    # Perform globbing on everything for Windows
    if windows:
        result = list(flatten(glob_arg(f) for f in result))
    return result

class HelpFormatter(optparse.IndentedHelpFormatter):
    """
    Customize the width of help output
    """
    def __init__(self):
        width = 75
        optparse.IndentedHelpFormatter.__init__(
                self, max_help_position=width // 3, width=width)

class OptionParser(optparse.OptionParser):
    """
    Customized OptionParser which raises an exception but doesn't terminate
    """
    def error(self, msg):
        raise optparse.OptParseError(msg)

class TerminalApplication(object):
    """
    Base class for command line applications.

    This class provides command line parsing, file globbing, response file
    handling and common logging configuration for command line utilities.
    Descendent classes should override the main() method to implement their
    main body, and __init__() if they wish to extend the command line options.
    """
    # Get the default output encoding from the default locale
    encoding = locale.getdefaultlocale()[1]

    # This class is the abstract base class for each of the command line
    # utility classes defined. It provides some basic facilities like an option
    # parser, console pretty-printing, logging and exception handling

    def __init__(self, version, usage=None, description=None):
        super(TerminalApplication, self).__init__()
        self.wrapper = textwrap.TextWrapper()
        self.wrapper.width = 75
        if usage is None:
            usage = self.__doc__.strip().split('\n')[0]
        if description is None:
            description = self.wrapper.fill('\n'.join(
                line.lstrip()
                for line in self.__doc__.strip().split('\n')[1:]
                if line.lstrip()
                ))
        self.parser = OptionParser(
            usage=usage,
            version=version,
            description=description,
            formatter=HelpFormatter()
            )
        self.parser.set_defaults(
            debug=False,
            logfile='',
            loglevel=logging.WARNING
            )
        self.parser.add_option(
            '-q', '--quiet', dest='loglevel', action='store_const',
            const=logging.ERROR, help='produce less console output')
        self.parser.add_option(
            '-v', '--verbose', dest='loglevel', action='store_const',
            const=logging.INFO, help='produce more console output')
        self.parser.add_option(
            '-l', '--log-file', dest='logfile',
            help='log messages to the specified file')
        if optcomplete:
            opt.completer = optcomplete.RegexCompleter(['.*\.log', '.*\.txt'])
        self.parser.add_option(
            '-P', '--pdb', dest='debug', action='store_true',
            help='run under PDB (debug mode)')
        self.arg_completer = None

    def __call__(self, args=None):
        sys.excepthook = self.handle
        if args is None:
            args = sys.argv[1:]
        if optcomplete:
            optcomplete.autocomplete(self.parser, self.arg_completer)
        elif 'COMP_LINE' in os.environ:
            return 0
        (options, args) = self.parser.parse_args(expand_args(args))
        _CONSOLE.setLevel(options.loglevel)
        if options.logfile:
            logfile = logging.FileHandler(options.logfile)
            logfile.setFormatter(
                logging.Formatter('%(asctime)s, %(levelname)s, %(message)s'))
            logfile.setLevel(logging.DEBUG)
            logging.getLogger().addHandler(logfile)
        if options.debug:
            logging.getLogger().setLevel(logging.DEBUG)
        else:
            logging.getLogger().setLevel(logging.INFO)
        if options.debug:
            import pdb
            return pdb.runcall(self.main, options, args)
        else:
            return self.main(options, args) or 0

    def handle(self, exc_type, exc_value, exc_trace):
        "Global application exception handler"
        if issubclass(exc_type, (SystemExit, KeyboardInterrupt)):
            # Just ignore system exit and keyboard interrupt errors (after all,
            # they're user generated)
            return 130
        elif issubclass(exc_type, (ValueError, IOError)):
            # For simple errors like IOError just output the message which
            # should be sufficient for the end user (no need to confuse them
            # with a full stack trace)
            logging.critical(str(exc_value))
            return 1
        elif issubclass(exc_type, (optparse.OptParseError,)):
            # For option parser errors output the error along with a message
            # indicating how the help page can be displayed
            logging.critical(str(exc_value))
            logging.critical('Try the --help option for more information.')
            return 2
        else:
            # Otherwise, log the stack trace and the exception into the log
            # file for debugging purposes
            for line in traceback.format_exception(exc_type, exc_value, exc_trace):
                for msg in line.rstrip().split('\n'):
                    logging.critical(msg)
            return 1

    def main(self, options, args):
        "Called as the main body of the utility"
        raise NotImplementedError

import io
import serial
from xml.etree.ElementTree import fromstring, tostring

from oxitopped import __version__
from oxitopped.bottles import Bottle
from oxitopped.logger import DataLogger, DummyLogger, LoggerError
from oxitopped.nullmodem import null_modem

class OxiTopApplication(TerminalApplication):
    """
    Base class for oxitop command line applications.

    This class enhances the base TerminalApplication class with some facilities
    common to all the oxitop command line utilities - mostly to do with
    progress notifications.
    """

    def __init__(self):
        super(OxiTopApplication, self).__init__(__version__)
        self.dummy_logger = None
        self.data_logger = None
        self.progress_visible = False
        self.parser.set_defaults(
            port='COM1' if sys.platform.startswith('win') else '/dev/ttyUSB0',
            timeout=3,
            )
        self.parser.add_option(
            '-p', '--port', dest='port', action='store',
            help='specify the port which the OxiTop Data Logger is connected '
            'to. This will be something like /dev/ttyUSB0 on Linux or COM1 '
            'on Windows. Default: %default')
        self.parser.add_option(
            '-t', '--timeout', dest='timeout', action='store',
            help='specify the number of seconds to wait for data from the '
            'serial port. Default: %default')

    def __call__(self, args=None):
        try:
            return super(OxiTopApplication, self).__call__(args)
        finally:
            if self.dummy_logger:
                self.dummy_logger.terminated = True
            if self.data_logger:
                self.data_logger.close()

    def handle(self, exc_type, exc_value, exc_trace):
        "Global application exception handler"
        if issubclass(exc_type, (serial.SerialException, LoggerError)):
            # Extend simple exception handling to serial exceptions
            logging.critical(str(exc_value))
            return 1
        else:
            return super(OxiTopApplication, self).handle(
                    exc_type, exc_value, exc_trace)

    def print_table(self, lines, header_lines=1, footer_lines=0):
        """
        Routine for pretty-printing a text table.

        `lines` : a sequence of tuples representing a row of values in the table
        `header_lines` : number of lines at the start that are headers
        `footer_lines` : number of lines at the end that are footers
        """
        lines = list(lines)
        # Calculate the maximum length of each field
        columns = max(len(line) for line in lines)
        lengths = [
            max(len(line[column])
                if column < len(line) else 0 for line in lines)
            for column in range(columns)
            ]
        # Insert separators
        if header_lines != 0:
            lines.insert(header_lines, tuple('-' * l for l in lengths))
        if footer_lines != 0:
            lines.insert(-footer_lines, tuple('-' * l for l in lengths))
        # Output the data
        for line in lines:
            print(' '.join('%-*s' % (l, s) for (l, s) in zip(lengths, line)))

    def print_form(self, lines, fmt='{field: <{width}}{value}'):
        """
        Routine for pretty-printing a form of fields.

        `lines` : a sequence of 2-tuples representing each field and its value
        `fmt` : a format string specifying how to lay out each line
        """
        lines = list(lines)
        columns = max(len(line) for line in lines)
        assert columns == 2
        # Calculate the maximum length of each field
        width = max(len(line[0]) for line in lines) + 2
        for (field, value) in lines:
            print(fmt.format(width=width, field=field, value=value))

    progress_spinner = ['\\', '|', '/' ,'-']

    def progress_start(self):
        self.progress_index = 0
        self.progress_update(erase=False)

    def progress_update(self, erase=True):
        if not self.progress_visible:
            return
        if erase:
            sys.stderr.write('\b')
        sys.stderr.write(self.progress_spinner[self.progress_index % len(self.progress_spinner)])
        sys.stderr.flush()
        self.progress_index += 1

    def progress_finish(self):
        if not self.progress_visible:
            return
        sys.stderr.write('\b')

    def main(self, options, args):
        self.progress_visible = (options.loglevel == logging.INFO)
        if options.port == 'TEST':
            data_logger_port, dummy_logger_port = null_modem(
                baudrate=9600, bytesize=serial.EIGHTBITS,
                parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE,
                timeout=options.timeout, rtscts=True)
            with io.open(
                    os.path.join(os.path.dirname(__file__),
                        'example.xml'), 'r') as bottles_file:
                bottles_xml = fromstring(bottles_file.read())
            self.dummy_logger = DummyLogger(dummy_logger_port, [
                Bottle.from_xml(tostring(bottle))
                for bottle in bottles_xml.findall('bottle')
                ])
        else:
            data_logger_port = serial.Serial(
                options.port, baudrate=9600, bytesize=serial.EIGHTBITS,
                parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE,
                timeout=options.timeout, rtscts=True)
        self.data_logger = DataLogger(data_logger_port, progress=(
            self.progress_start,
            self.progress_update,
            self.progress_finish,
            ))


from flask import Blueprint, json, jsonify, request
from flask_login import login_required, current_user

from app.models import db, Post, User, Like, Comment, Tag_Post
from app.forms import UploadForm

post_routes = Blueprint('posts', __name__)

# Get posts
# Create a new post
@post_routes.route('/', methods=['GET', 'POST'])
# @login_required()
def post():
    m = request.method
    if m == 'GET':  # Get a list of posts
        posts = []
        postQuery = db.session.query(Post, User).join(User, User.id == Post.userId).all()
        for post in postQuery:
            likeQuery = db.session.query(Like, User).join(User, User.id == Like.userId).filter(Like.postId == post[0].id).all()
            commentQuery = db.session.query(Comment, User).join(User, User.id == Comment.userId).filter(Comment.postId == post[0].id).all()

            likes = []
            comments = []

            for like in likeQuery:
                likes.append({
                    "likes": like[0].to_dict(),
                    "liked_by": like[1].to_dict(),
                })

            for comment in commentQuery:
                comments.append({
                    "comment": comment[0].to_dict(),
                    "comment_by": comment[1].to_dict(),
                })

            posts.append({
                'post': post[0].to_dict(),
                'user': post[1].to_dict(),
                'likeData': likes,
                'commentData': comments,
            })
        return jsonify(posts)
    elif m == 'POST':  # Create a new post
        form = UploadForm()
        form['csrf_token'].data = request.cookies['csrf_token']
        post = ''
        if form.validate_on_submit():
            post = Post(
                userId=current_user.id,
                photo=form.data['photo'],
                caption=form.data['caption']
            )
            db.session.add(post)
            db.session.commit()
        return jsonify({'post': post.to_dict(), 'user':current_user.to_dict(), 'likeData':[], 'commentData':[]} if post else 'Invalid operation')

@ post_routes.route('/<int:id>', methods=['GET', 'DELETE'])
# @login_required
def postById(id):
    m = request.method
    if m == 'GET':  # Get a data for a given post
        postQuery = db.session.query(Post, User).join(User, User.id == current_user.id).filter(Post.id == id).first()
        likeQuery = db.session.query(Like, User).join(User, User.id == Like.userId).filter(Like.postId == id).all()
        commentQuery = db.session.query(Comment, User).join(User, User.id == Comment.userId).filter(Comment.postId == id).all()

        likes = []
        comments = []
        for like in likeQuery:
            likes.append({
                "likes": like[0].to_dict(),
                "liked_by": like[1].to_dict(),
            })

        for comment in commentQuery:
            comments.append({
                "comment": comment[0].to_dict(),
                "comment_by": comment[1].to_dict(),
            })

        post = {
            'post': postQuery[0].to_dict(),
            'user': postQuery[1].to_dict(),
            'likeData': likes,
            'commentData': comments,
        }
        return jsonify(post)

    elif m == 'DELETE':  # Delete a given post
        success = Post.query.filter(Post.id == id).delete()
        db.session.commit()
        return jsonify('Successfully deleted.' if success else 'Invalid operation.')

@ post_routes.route('/<int:id>/likes', methods=['GET', 'POST', 'DELETE'])
# @login_required
def likesByPostId(id):
    m = request.method
    if m == 'GET':  # Get number of likes for a given post
        likes = []
        for like in Like.query.filter(Like.postId == id).all():
            user = User.query.get(like.userId)

            likes.append({
                "like":like.to_dict(),
                "user":user.to_dict()
            })
        res = {
            'count': len(likes),
            'likes': likes

        }
        return jsonify(res)
    elif m == 'POST':  # Create a new like for the given post
        # userId should come from currentUser
        # userId = current_user.id???
        like = Like(postId=id, userId=current_user.id)
        db.session.add(like)
        db.session.commit()
        return jsonify({"like":like.to_dict(), "liked_by":current_user.to_dict()})
    elif m == 'DELETE':  # Delete a like for the given post
        like = Like.query.filter(Like.userId == current_user.id, Like.postId == id).first()
        db.session.delete(like)
        db.session.commit()
        return jsonify({"like":like.to_dict()})

@ post_routes.route('/<int:id>/comments', methods=['GET', 'POST'])
# @login_required
def commentsByPostId(id):
    m = request.method
    if m == 'GET':  # Get comments for given post
        comments = []
        for comment in Comment.query.filter(Comment.postId == id).all():
            comments.append(comment.to_dict())
        return jsonify(comments)
    elif m == 'POST':  # Create new comment for given post
        content = request.json['commentInput']
        # userId should come from currentUser
        userId = current_user.id
        comment = Comment(postId=id, userId=userId, content=content)
        db.session.add(comment)
        db.session.commit()
        return jsonify({"comment":comment.to_dict(), "comment_by": current_user.to_dict()})

@ post_routes.route('/<int:id>/tags', methods=['GET', 'POST', 'DELETE'])
# @login_required
def tagsByPostId(id):
    m = request.method
    if m == 'GET':  # Get the tags for a given post
        tags = []
        for tag in Tag_Post.query.filter(Tag_Post.postId == id).all():
            tags.append(tag.to_dict())
        res = {
            'length': len(tags),
            'tags': tags
        }
        return jsonify(res)
    elif m == 'POST':  # Create a new tag for the given post
        return 'POST TAG'
    elif m == 'DELETE':  # Delete a tag from the given post
        return 'DELETE TAG'


# Welcome.

# In this kata you are required to, given a string, replace every letter with its position in the alphabet.

# If anything in the text isn't a letter, ignore it and don't return it.

# a being 1, b being 2, etc.

# As an example:

# alphabet_position("The sunset sets at twelve o' clock.")
# Should return "20 8 5 19 21 14 19 5 20 19 5 20 19 1 20 20 23 5 12 22 5 15 3 12 15 3 11" as a string.

import string

def alphabet_position(text):
    nuevaLista = []
    arrayMin = text.lower()
    array = list(arrayMin.replace(' ', ''))

    for elemento in array:
        if elemento in string.ascii_letters:
            numero = ord(elemento) - 96
            nuevaLista.append(numero)
    return ' '.join(str(nuevaLista) for nuevaLista in nuevaLista)

assert (alphabet_position("The sunset sets at twelve o' clock.")) == "20 8 5 19 21 14 19 5 20 19 5 20 19 1 20 20 23 5 12 22 5 15 3 12 15 3 11", "No sustituye bien"
assert (alphabet_position("The narwhal bacons at midnight.")) == "20 8 5 14 1 18 23 8 1 12 2 1 3 15 14 19 1 20 13 9 4 14 9 7 8 20", "No sustituye bien"

Codewars/Replace With Alphabet Position.py


import configparser, json, crawl, vendormanage, elasticsearch, asyncio

config = configparser.ConfigParser()
config.read('config/elastic.ini')

url = config['elastic']['url']

es = elasticsearch.ElasticSearch(url)
vendors = vendormanage.load_vendors()

index = "vendors/"

endpoint = f"{index}vendor/"

returneddata = asyncio.run(crawl.crawl(f"{url}{index}", 'PUT'))

print(json.loads(returneddata))

for vendor in vendors:
    vendor_endpoint = f"{endpoint}{vendor['uuid']}"
    vendor_returneddata = asyncio.run(es.store(vendor_endpoint, vendor))
    print(json.loads(vendor_returneddata))


# --- STL Imports ---
import sys

class NamedObject:
    _invalidCharacters = " .+-*/%='\"!<>()"

    def __init__(self, name: str, validate=True):
        self._name, self._nameSpace = self._parseName(name, validate=validate)

    @property
    def name(self):
        return self._name

    @name.setter
    def name(self, name: str):
        self._name, self._nameSpace = self._parseName(name)

    def __str__(self):
        return "".join("{}::".format(nameSpace) for nameSpace in self._nameSpace) + self._name

    @property
    def fullName(self):
        return self.name

    @property
    def shortName(self):
        return self._name

    @staticmethod
    def _parseName(name: str, validate=True):
        """Split the input name to its namespace and name stub."""
        if validate:
            for char in NamedObject._invalidCharacters:
                if char in name:
                    raise NameError("Invalid character '{}' in name: {}".format(char, name))

        if not name:
            return "", []

        name = name.replace("typename","").split("::")
        return name[-1], name[:-1]

class Template(NamedObject):
    def __init__(self, string: str, validate=True):
        NamedObject.__init__(self, "", validate=False)
        self._parameters = [] # set of parameters as tuples (alias,Template)

        # Validate
        string = string.strip()

        # Find scope
        parametersBegin = string.find('<')
        parametersEnd   = string.rfind('>')

        if string and parametersBegin!=-1 and parametersEnd!=-1 and parametersBegin!=parametersEnd:
            # Set name
            self.name = string[:parametersBegin]

            # Parse parameters
            parameters = string[parametersBegin+1:parametersEnd].split(',')
            for parameter in parameters:
                parameter = parameter.strip()
                self._parameters.append(("", Template(parameter)))

        else:
            # Set name
            self.name = string

    def __str__(self):
        if self._parameters:
            return "{name}<{parameters}>".format(
                name = NamedObject.__str__(self),
                parameters = ",".join(str(pair[1]) for pair in self._parameters)
            )
        else:
            return NamedObject.__str__(self)

def extractEnclosedString(string: str, beginCharacter='(', endCharacter=')', validate=True):
    """beginCharacter contents endCharacter"""
    begin  = string.find(beginCharacter)
    end    = string.rfind(endCharacter)

    if begin == -1 or end == -1 or end < begin:
        if validate:
            raise ValueError("'{}' is not enclosed by '{}' and '{}'".format(string, beginCharacter, endCharacter))
    else:
        return string[begin+1:end].strip()

    return ""

class TemplateDetails:
    def __init__(self, string: str, validate=True):
        """[with shorthand_0 = expansion_0; shorthand_1 = expansion_1; ...]"""
        self._types = {}
        string = extractEnclosedString(string, beginCharacter='[', endCharacter=']', validate=validate)

        # Remove 'with'
        begin = string.find("with")
        if begin == -1:
            if validate:
                raise ValueError("Invalid template expansion '{}'".format(string))
            begin = 0
        else:
            begin += len("with")

        string = string[begin:]

        # Parse aliases
        while string:
            # Find scope
            end = string.find(';')
            if end == -1:
                end = len(string)

            contents = string[:end].split('=')
            string   = string[end+1:].strip()

            # Parse components
            if len(contents) != 2:
                raise RuntimeError("Invalid template expansion {}".format(contents))

            self._types[Template(contents[0])] = Template(contents[1])

    def __getitem__(self, key: str):
        return self._types[key]

    def keys(self):
        return self._types.keys()

    def values(self):
        return self._types.values()

    def items(self):
        return self._types.items()

    def __iter__(self):
        return self._types.__iter__()

    def __next__(self):
        return self._types.__next__()

class ArgumentList:
    def __init__(self, string: str, validate=True):
        """(argument_0_type, argument_1_type, ...)"""
        string = extractEnclosedString(string, validate=validate)
        self._types = string.split(',')

    def __getitem__(self, index: int):
        return self._types[index]

    def __iter__(self):
        return self._types.__iter__()

    def __next__(self):
        return self._types.__next__()

class Function(Template):
    def __init__(self, string: str, validate=True):
        """function_name(...arguments) [template_details] (not_yet_recognized)"""
        Template.__init__(self, "", validate=False)
        self._arguments      = ArgumentList("", validate=False)
        self_templateDetails = TemplateDetails("", validate=False)
        self._TODO           = ""

        # Find component separators
        argumentsBegin = string.find('(')
        argumentsEnd   = string.find(')') + 1
        detailsBegin   = string.find('[')
        detailsEnd     = string.find(']') + 1
        returnBegin    = string.rfind('(') + 1
        returnEnd      = string.rfind(')')

        # Parse name
        if argumentsBegin == -1:
            raise ValueError("Missing function name in '{}'".format(string))
        self.name = string[:argumentsBegin]

        # Parse arguments
        if argumentsBegin == -1 or argumentsEnd == 0 or argumentsEnd < argumentsBegin:
            raise ValueError("Missing function arguments in '{}'".format(string))
        self._arguments = ArgumentList(string[argumentsBegin:argumentsEnd])

        # Parse template expansion [optional]
        self._templateDetails = TemplateDetails(string[detailsBegin:detailsEnd], validate=False)

        # Parse return type
        if returnBegin == -1 or returnEnd == 0 or returnEnd < returnBegin:
            raise ValueError("Missing return type in '{}'".format(string))
        self._TODO = string[returnBegin, returnEnd]

if __name__ == "__main__":
    contents = ""

    #filePath = sys.argv[1]
    filePath = "/home/mate/Desktop/error.log"

    with open(filePath, "r") as file:
        contents = file.read().strip()

    print(Function(contents))


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

import os
import itertools
import codecs
import re
import datetime
import cairocffi as cairo
import editdistance
import numpy as np
from scipy import ndimage
import pylab

from keras import backend as K
from keras.layers.convolutional import Conv2D, MaxPooling2D
from keras.layers import Input, Dense, Activation
from keras.layers import Reshape, Lambda
from keras.layers.merge import add, concatenate
from keras.models import Model
from keras.layers.recurrent import GRU
from keras.optimizers import SGD
from keras.utils.data_utils import get_file
from keras.preprocessing import image
import keras.callbacks
from keras.models import load_model
from keras.preprocessing.image import load_img,img_to_array

import matplotlib.pyplot as plt

def ctc_lambda_func(args):
    y_pred, labels, input_length, label_length = args
    # the 2 is critical here since the first couple outputs of the RNN
    # tend to be garbage:
    y_pred = y_pred[:, 2:, :]
    return K.ctc_batch_cost(labels, y_pred, input_length, label_length)

# Reverse translation of numerical classes back to characters
def labels_to_text(labels):
    ret = []
    for c in labels:
        if c == len(alphabet):  # CTC Blank
            ret.append("")
        else:
            ret.append(alphabet[c])
    return "".join(ret)

alphabet = u'abcdefghijklmnopqrstuvwxyz '

absolute_max_string_len = 16
character_count = 28

weight_file = './weights24.h5'
img_w = 128
# Input Parameters
img_h = 64
words_per_epoch = 16000
val_split = 0.2
val_words = int(words_per_epoch * (val_split))

# Network parameters
conv_filters = 16
kernel_size = (3, 3)
pool_size = 2
time_dense_size = 32
rnn_size = 512
minibatch_size = 32

if K.image_data_format() == 'channels_first':
    input_shape = (1, img_w, img_h)
else:
    input_shape = (img_w, img_h, 1)

act = 'relu'
input_data = Input(name='the_input', shape=input_shape, dtype='float32')
inner = Conv2D(conv_filters, kernel_size, padding='same',
               activation=act, kernel_initializer='he_normal',
               name='conv1')(input_data)
inner = MaxPooling2D(pool_size=(pool_size, pool_size), name='max1')(inner)
inner = Conv2D(conv_filters, kernel_size, padding='same',
               activation=act, kernel_initializer='he_normal',
               name='conv2')(inner)
inner = MaxPooling2D(pool_size=(pool_size, pool_size), name='max2')(inner)

conv_to_rnn_dims = (img_w // (pool_size ** 2), (img_h // (pool_size ** 2)) * conv_filters)
inner = Reshape(target_shape=conv_to_rnn_dims, name='reshape')(inner)

# cuts down input size going into RNN:
inner = Dense(time_dense_size, activation=act, name='dense1')(inner)

# Two layers of bidirectional GRUs
# GRU seems to work as well, if not better than LSTM:
gru_1 = GRU(rnn_size, return_sequences=True, kernel_initializer='he_normal', name='gru1')(inner)
gru_1b = GRU(rnn_size, return_sequences=True, go_backwards=True, kernel_initializer='he_normal', name='gru1_b')(inner)
gru1_merged = add([gru_1, gru_1b])
gru_2 = GRU(rnn_size, return_sequences=True, kernel_initializer='he_normal', name='gru2')(gru1_merged)
gru_2b = GRU(rnn_size, return_sequences=True, go_backwards=True, kernel_initializer='he_normal', name='gru2_b')(gru1_merged)

# transforms RNN output to character activations:
inner = Dense(character_count, kernel_initializer='he_normal',
              name='dense2')(concatenate([gru_2, gru_2b]))
y_pred = Activation('softmax', name='softmax')(inner)
Model(inputs=input_data, outputs=y_pred).summary()

labels = Input(name='the_labels', shape=[absolute_max_string_len], dtype='float32')
input_length = Input(name='input_length', shape=[1], dtype='int64')
label_length = Input(name='label_length', shape=[1], dtype='int64')
# Keras doesn't currently support loss funcs with extra parameters
# so CTC loss is implemented in a lambda layer
loss_out = Lambda(ctc_lambda_func, output_shape=(1,), name='ctc')([y_pred, labels, input_length, label_length])

# clipnorm seems to speeds up convergence
sgd = SGD(lr=0.02, decay=1e-6, momentum=0.9, nesterov=True, clipnorm=5)

model = Model(inputs=[input_data, labels, input_length, label_length], outputs=loss_out)

# the loss calc occurs elsewhere, so use a dummy lambda func for the loss
model.compile(loss={'ctc': lambda y_true, y_pred: y_pred}, optimizer=sgd)
model.load_weights(weight_file)
# captures output of softmax so we can decode the output during visualization
#test_func = K.function([input_data], [y_pred])

model_p = Model(inputs=input_data, outputs=y_pred)

#model_p = load_model(MODEL_PATH)

def decode_predict_ctc(out, top_paths = 1):
    results = []
    beam_width = 5
    if beam_width < top_paths:
      beam_width = top_paths
    for i in range(top_paths):
      lables = K.get_value(K.ctc_decode(out, input_length=np.ones(out.shape[0])*out.shape[1],
                           greedy=False, beam_width=beam_width, top_paths=top_paths)[0][i])[0]
      text = labels_to_text(lables)
      results.append(text)
    return results

def predit_a_image(a, top_paths = 1):
  c = np.expand_dims(a.T, axis=0)
  net_out_value = model_p.predict(c)
  top_pred_texts = decode_predict_ctc(net_out_value, top_paths)
  return top_pred_texts

def paint_text(text, w, h, rotate=False, ud=False, multi_fonts=False):
    surface = cairo.ImageSurface(cairo.FORMAT_RGB24, w, h)
    with cairo.Context(surface) as context:
        context.set_source_rgb(1, 1, 1)  # White
        context.paint()
        # this font list works in CentOS 7
        if multi_fonts:
            fonts = [
                'Century Schoolbook', 'Courier', 'STIX',
                'URW Chancery L', 'FreeMono']
            context.select_font_face(
                np.random.choice(fonts),
                cairo.FONT_SLANT_NORMAL,
                np.random.choice([cairo.FONT_WEIGHT_BOLD, cairo.FONT_WEIGHT_NORMAL]))
        else:
            context.select_font_face('Courier',
                                     cairo.FONT_SLANT_NORMAL,
                                     cairo.FONT_WEIGHT_BOLD)
        context.set_font_size(25)
        box = context.text_extents(text)
        border_w_h = (4, 4)
        if box[2] > (w - 2 * border_w_h[1]) or box[3] > (h - 2 * border_w_h[0]):
            raise IOError(('Could not fit string into image.'
                           'Max char count is too large for given image width.'))

        # teach the RNN translational invariance by
        # fitting text box randomly on canvas, with some room to rotate
        max_shift_x = w - box[2] - border_w_h[0]
        max_shift_y = h - box[3] - border_w_h[1]
        top_left_x = np.random.randint(0, int(max_shift_x))
        if ud:
            top_left_y = np.random.randint(0, int(max_shift_y))
        else:
            top_left_y = h // 2
        context.move_to(top_left_x - int(box[0]), top_left_y - int(box[1]))
        context.set_source_rgb(0, 0, 0)
        context.show_text(text)

    buf = surface.get_data()
    a = np.frombuffer(buf, np.uint8)
    a.shape = (h, w, 4)
    a = a[:, :, 0]  # grab single channel
    a = a.astype(np.float32) / 255
    a = np.expand_dims(a, 0)
    if rotate:
        a = image.random_rotation(a, 3 * (w - top_left_x) / w + 1)
    #a = speckle(a)

    return a

h = 64
w = 128
a = paint_text('a game',h = h, w = w)
b = a.reshape((h, w))
#plt.imshow(b, cmap='Greys_r')
#plt.show()
print(a.shape)
c = np.expand_dims(a.T, axis=0)
#print(c)

net_out_value = model_p.predict(c)
pred_texts = decode_predict_ctc(net_out_value)
print(pred_texts)

img = load_img("test2.png", target_size=(h,w))

#plt.imshow(img, cmap='Greys_r')
#plt.show()
c = img_to_array(img)
print(c.shape)
c = c / 255.0
c = c[:, :, 0]  # grab single channel
c = np.expand_dims(c, 0)
print(c.shape)
c = np.expand_dims(c.T, axis=0)
#print(c)

net_out_value = model_p.predict(c)
pred_texts = decode_predict_ctc(net_out_value)
print(pred_texts)

#predit_a_image(a, top_paths = 3)

#plt.imshow(net_out_value[0].T, cmap='binary', interpolation='nearest')
#plt.show()

#K.get_value(K.ctc_decode(net_out_value, input_length=np.ones(net_out_value.shape[0])*net_out_value.shape[1],
#                         greedy=False, beam_width=3, top_paths=3)[0][0])

#K.ctc_decode(net_out_value, input_length=np.ones(net_out_value.shape[0])*net_out_value.shape[1],
#                         greedy=False, beam_width=5, top_paths=3)

#K.get_value(K.ctc_decode(net_out_value, input_length=np.ones(net_out_value.shape[0])*net_out_value.shape[1],
#                         greedy=False, beam_width=3, top_paths=3)[0][0])


from koebe.geometries.spherical2 import *
from koebe.geometries.commonOps import *

def wingDiskOf(dart):
    if dart.dcel.outerFace == dart.face:
        return DiskS2(0, 0, -1, 0)
    else:
        return dart.prev.origin.data

def computeVoronoiArc(d1, d2, d3, d4):
    bisector12 = d1.bisectorWith(d2)
    bisector23 = d1.bisectorWith(d3)
    bisector24 = d1.bisectorWith(d4)

    dual12 = bisector12.dualDiskS2
    dual23 = bisector23.dualDiskS2
    dual24 = bisector24.dualDiskS2

    cfDual12a = CoaxialFamilyS2(dual12, dual23)
    cfDual12b = CoaxialFamilyS2(dual12, dual24)

    genPoints1 = cfDual12a.generatorPoints()
    genPoints2 = cfDual12b.generatorPoints()

    ortho123 = CPlaneS2.throughThreeDiskS2(d1, d2, d3)
    ortho142 = CPlaneS2.throughThreeDiskS2(d1, d4, d2)

    pt1DotOrtho123 = inner_product4(ortho123.a, ortho123.b, ortho123.c, ortho123.d,
                                   genPoints1[0].x, genPoints1[0].y, genPoints1[0].z, 1)

    if len(genPoints1) == 1 or isZero(pt1DotOrtho123):
        pt1 = genPoints1[0]
    else:
        pt1 = genPoints1[1]

    pt2DotOrtho142 = inner_product4(ortho142.a, ortho142.b, ortho142.c, ortho142.d,
                                   genPoints2[0].x, genPoints2[0].y, genPoints2[0].z, 1)

    if len(genPoints2) == 1 or isZero(pt2DotOrtho142):
        pt2 = genPoints2[0]
    else:
        pt2 = genPoints2[1]

    return CircleArcS2(pt1, pt2, dual12)

def computeVoronoiArcForEdge(edge):
    dart = edge.aDart
    disk1 = dart.origin.data
    disk2 = dart.dest.data
    disk3 = wingDiskOf(dart)
    disk4 = wingDiskOf(dart.twin)
    return computeVoronoiArc(disk1, disk2, disk3, disk4)

def inversiveVoronoi(packing):
    return [computeVoronoiArcForEdge(e) for e in packing.edges]


import tkinter as tk
from tkinter import ttk
# from pygame.mixer import music
from song import SongStorage
import vlc
import numpy as np
import warnings

class MusicPlayer:
    def __init__(self):
        # self.startwindow()
        self.storage = None
        self.gui = None

        self.current_song = None
        self.current_media = None
        self.next_song = None
        self.next_media = None
        self.history = []

        self.instance = vlc.Instance()
        # self.media_list = self.instance.media_list_new()
        self.player = self.instance.media_player_new()
        # self.player.set_media_list(self.media_list)
        self.event_manager = self.player.event_manager()
        pass

    max_history_size = 10

    def generate_storage(self, directory_name=None):
        self.storage = SongStorage()
        if directory_name is not None:
            self.storage.import_library(directory_name)

    def load_storage(self, location=SongStorage.DEFAULT_SAVE):
        self.storage = SongStorage.load(location)
        self.storage.update_costs()
        # if "volume" not in self.storage.__dict__.keys():
        #     self.storage.volume = 100.

    def change_target(self, target, strength):
        # Requires np.array of ints!
        self.storage.change_target(target, strength)
        self._select_next()
        # self.set_next_media(self.next_song)

    def _select_next(self):
        try:
            draw = self.storage.select_song(self.max_history_size+1)
        except ValueError:
            print("No songs playable - current song will loop")
            return None
        for song in draw:
            if song not in self.history:
                # print(song.file_name)
                self.next_song = song
                self.next_media = self._create_media(song)
                return song
        print("All playable songs have already been played in history - ignoring history")
        self.next_song = draw[0]
        self.next_media = self._create_media(draw[0])
        return draw[0]
        # raise RuntimeError(f"At least {self.max_history_size+1} songs with nonzero probability required")

    def change_attributes(self, attributes, song=None):
        if song is None:
            song = self.current_song
        self.storage.set_attribute(song, attributes)

    def _create_media(self, song):
        return self.instance.media_new(song.path)

    def _first_start(self):
        # to be called the first time the music is played
        self._select_next()
        self.current_song = self.next_song
        self.current_media = self.next_media
        self.player.set_media(self.current_media)
        self._add_to_history(self.current_song)
        self.player.play()
        self._select_next()
        self.event_manager.event_attach(vlc.EventType.MediaPlayerEndReached, self.when_track_changed)
        self.print_current_info()
        if self.gui is not None:
            self.gui.when_track_changed()

    def when_track_changed(self, _):
        # print("doot")
        # print(self.current_song.file_name, self.next_song.file_name)
        self.current_song = self.next_song
        self.current_media = self.next_media
        self._add_to_history(self.current_song)
        self._select_next()
        # self.player.release()
        self.player = self.instance.media_player_new()
        self.event_manager = self.player.event_manager()
        self.event_manager.event_attach(vlc.EventType.MediaPlayerEndReached, self.when_track_changed)
        # self.player.set_position(0.)
        # print("joot")
        # print(self.player.will_play())
        self.player.set_media(self.current_media)
        self.player.audio_set_volume(self.storage.volume)
        # print("noot")
        self.player.play()
        self.print_current_info()
        if self.gui is not None:
            self.gui.when_track_changed()

    def play_pause(self):
        print("Play/pause!")
        if self.current_song is None:
            self._first_start()
        else:
            self.player.pause()

    def pause(self):
        if self.player.get_state() == vlc.State.Playing:
            self.player.pause()

    def play(self):
        if self.current_song is None:
            self._first_start()
        else:
            self.player.play()

    def skip(self):
        self.player.set_position(1.)

    def previous(self):
        if len(self.history) <= 1:
            return -1
        self.player.stop()
        self.next_song = self.current_song
        self.next_media = self.current_media
        self.history.pop(0)
        self.current_song = self.history[0]
        self.current_media = self._create_media(self.current_song)
        self.player = self.instance.media_player_new()
        self.event_manager = self.player.event_manager()
        self.event_manager.event_attach(vlc.EventType.MediaPlayerEndReached, self.when_track_changed)
        self.player.set_media(self.current_media)
        # print("noot")
        self.player.play()
        self.print_current_info()
        if self.gui is not None:
            self.gui.when_track_changed()

    def _add_to_history(self, song):
        if len(self.history) == self.max_history_size:
            self.history.pop()
        self.history.insert(0, song)

    def print_current_info(self):  # TODO this is a botch job
        if self.current_media is None:
            print("")
            print("Not currently playing anything")
            print("Attributes:")
            print(self.storage.attribute_names)
        else:
            title = self.current_media.get_meta(vlc.Meta.Title)
            # length = self.player.get_length()/1000
            # length_string = f"({length//60}:{length%60})"
            print("")
            print("Now playing: ", title)
            print(self.current_song.file_name)
            print(f"Cost: {self.current_song.cost}")
            print(f"Probability: {self.current_song.probability}")
            print("Attributes:")
            print(self.storage.attribute_names)
            print("Current:")
            print(self.current_song.attributes)
        print("Target:")
        print(list(self.storage.target))
        print("Strength:")
        print(list(self.storage.strength))
        print("Playable songs:")
        print(sum(self.storage.probabilities>0))
        # print("")

class CommandLine:
    def __init__(self):
        self.player = MusicPlayer()
        self._start()

    def _start(self):
        answer = input("Use default library? [default, load, new] ")
        if answer == '' or answer == "default":
            self.player.load_storage()
            self.player.storage.update()
            print("default storage loaded")
        elif answer == 'load':
            filename = input("Filename: ")
            self.player.load_storage(filename)
            self.player.storage.update()
            print("Storage loaded")
        elif answer == 'new':
            self.player.generate_storage()
            print("New storage created!\nUse \"library <filename>\" to add a library")
        else:
            raise RuntimeError("Command not recognised")

    def main_loop(self):
        while True:
            command = input("")
            inputs = command.split()
            if inputs:
                first = inputs[0]
            else:
                continue
            if first == "help" or first == "h":
                print("")
                print("Possible commands:")
                print("exit/quit/q")
                print("pause")
                print("play")
                print("p (pause/play)")
                print("skip")
                print("library <path to library>")
                print("save")
                print("add <attribute_name>")
                print("delete/remove <attribute_name/index>")
                print("set/change current/previous/target/strength")
                print("status/s")
                print("rename <attribute_name/index> <new_name>")
                print("move <attribute_name/index> <new_index>")
                print("history")
                print("refresh")

            elif first == "pause":
                # print("> pause")
                self.player.pause()
            elif first == "play":
                # print("> play")
                self.player.play()
            elif first == "p":
                self.player.play_pause()
            elif first == "skip":
                # print("> skip")
                self.player.skip()
            elif first == "library":
                if len(inputs) == 1:
                    print("Not enough inputs")
                    pass
                else:
                    path = ' '.join(inputs[1:])
                    try:
                        self.player.storage.import_library(path)
                    except FileNotFoundError:
                        print(f"File {path} not found")
            elif first == "save":
                self.player.storage.save()
            elif first == "add":
                if len(inputs) == 1:
                    print("Not enough inputs")
                    pass
                else:
                    self.player.storage.add_attribute(inputs[1])
                print(self.player.storage.attribute_names)
            elif first == "delete" or first == "remove":
                if len(inputs) == 1:
                    print("Not enough inputs")
                    pass
                else:
                    try:
                        self.player.storage.remove_attribute(inputs[1])
                    except ValueError:
                        print(f"Attribute not found")
                    except IndexError:
                        print(f"Index {inputs[1]} out of bounds")
                print(self.player.storage.attribute_names)
            elif first == "set" or first == "change":
                if inputs[1] == "current" or inputs[1] == "c":
                    song = self.player.current_song
                    print("Setting attributes for", song.file_name)
                    print("0: unset, 1: low, 2: moderate, 3: high")
                    print(self.player.storage.attribute_names)
                    print("Current attributes:", song.attributes)
                    new_string = input("New attributes:\n")
                    try:
                        attributes = [int(x) for x in new_string.split()]
                        self.player.change_attributes(attributes, song)
                    except ValueError:
                        print("Incorrect number of attributes or attribute outside of allowed range")
                elif inputs[1] == "previous" or inputs[1] == "p":
                    if len(self.player.history) <= 1:
                        print("No previous songs")
                    song = self.player.history[1]
                    print("Setting attributes for ", song.file_name)
                    print("0: unset, 1: low, 2: moderate, 3: high")
                    print(self.player.storage.attribute_names)
                    print("Current attributes:", song.attributes)
                    new_string = input("New attributes:\n")
                    try:
                        attributes = [int(x) for x in new_string.split()]
                        self.player.change_attributes(attributes, song)
                    except ValueError:
                        print("Incorrect number of attributes or attribute outside of allowed range")
                elif inputs[1] == "target" or inputs[1] == "t":
                    print("0: unset, 1: low, 2: moderate, 3: high")
                    print(self.player.storage.attribute_names)
                    print("Current target:", self.player.storage.target)
                    new_string = input("New target:\n")
                    try:
                        target = np.array([int(x) for x in new_string.split()])
                        self.player.change_target(target, self.player.storage.strength)
                    except ValueError:
                        print("Incorrect number of attributes or attribute outside of allowed range")
                elif inputs[1] == "strength" or inputs[1] == "s":
                    print("0: ignore, 1: approximate, 2: close, 3: perfect")
                    print(self.player.storage.attribute_names)
                    print("Current strength:", self.player.storage.strength)
                    new_string = input("New strength:\n")
                    try:
                        strength = np.array([int(x) for x in new_string.split()])
                        self.player.change_target(self.player.storage.target, strength)
                    except ValueError:
                        print("Incorrect number of strengths or strength outside of allowed range")
            elif first == "exit" or first == "quit" or first == "q":
                self.player.pause()
                break
            elif first == "status" or first == 's':
                # if self.player.current_song is not None:
                #     print("Current:", self.player.current_song.file_name, self.player.current_media.get_mrl().split('/')[-1])
                # if self.player.next_song is not None:
                #     print("Next:", self.player.next_song.file_name, self.player.next_media.get_mrl().split('/')[-1])
                # if self.player.player.get_media() is not None:
                #     print("Current:", self.player.player.get_media().get_mrl().split('/')[-1])
                # print("Status:", self.player.player.get_state())
                self.player.print_current_info()
            elif first == "rename":
                if len(inputs) < 3:
                    print("Not enough inputs")
                    pass
                else:
                    try:
                        self.player.storage.rename_attribute(inputs[1], inputs[2])
                    except ValueError:
                        print("New name cannot be numeric, or old name is not found")
                    except IndexError:
                        print("Index out of range")
                print(self.player.storage.attribute_names)
            elif first == "move":
                if len(inputs) < 3:
                    print("Not enough inputs")
                    pass
                else:
                    try:
                        self.player.storage.move_attribute(inputs[1], inputs[2])
                    except IndexError:
                        print("Index out of range")
                    except ValueError:
                        print("Name not found or new_index not integer")
                print(self.player.storage.attribute_names)
            elif first == "history":
                for i in range(len(self.player.history)):
                    print(self.player.history[i].file_name)
            elif first == "refresh":
                self.player.storage.update()
            else:
                print("Command not recognised")
            # if first != "skip":
            #     print("")


"""AyudaEnPython: https://www.facebook.com/groups/ayudapython

Even though the group is only for spanish speakers, english speakers
are welcome.
-----------------------------------------------------------------------
    ** PYTHON CODE CHALLENGE - BIEBER STRUGGLES IN SINGAPORE **

Justin is in singapore for holiday. while at a cafe, he is mistaken for
do kwon, founder of Luna(crypto) and snatched by a russian hit squad.
Russian opsec being what it is, police intercept unecrypted, but coded
message from a phone immediately after. They want 1,000 btc to release
Justin. Police are clueless, and ask you for help in decoding message.

You know FSB used code, where each letter gets a value, which is
doubled, 'a','b' are 5 and 6 and so on. Then every other 2-digit
number/character starting at second position is reversed so that
'abcdef' encodes to=>'102014161812' (afcdeb)
write code to decode and output the message and help save Justin!

intercept = '1242263422322626121816404638362648184618341226364644'

EDIT: clearer example:
message 'abcdef' to encode it to 'secret string' you do the following

First you give every char a number and double it a starts at 5 so
10, 12,14,16,18,20

then you take chars in position 1,3,5 (12,16,20) and reverse their
order (20,16,12) and put them back into string in 'same position'
So you get
10,20,14,16,18,12
"""

intercept = "1242263422322626121816404638362648184618341226364644"
decoder = {
    str(v*2): k for k, v in zip(
        "abcdefghijklmnopqrstuvwxyz", range(5, 32)
    )
}

def decoded(s):
    ss = [s[i:i+2] for i in range(0, len(s), 2)]
    odd, even = ss[1::2][::-1], ss[::2]
    return [even[i//2] if i % 2 == 0 else odd[i//2] for i in range(len(ss))]

def show(ss):
    print("".join(decoder[s] for s in ss))

show(decoded(intercept))


#!/usr/bin/env python3

__author__ = "Pramit Barua"
__copyright__ = "Copyright 2018, INT, KIT"
__credits__ = ["Pramit Barua"]
__license__ = "INT, KIT"
__version__ = "1"
__maintainer__ = "Pramit Barua"
__email__ = ["pramit.barua@student.kit.edu", "pramit.barua@gmail.com"]

'''

'''

import numpy as np
import argparse
import os
import sys
import time

sys.path.append(os.path.abspath('../NEGF_global'))

from global_write import global_write
from yaml_file_loader import yaml_file_loader

from NEGF_package.NEGF_display import NEGF_display
from NEGF_package.self_energy_v2 import self_energy

def system_gs(item_E, hc, sh, sigma_l, sigma_r):
    start_time = time.time()
    gs = np.linalg.inv(item_E*np.eye(len(sh))@sh - hc - sigma_l - sigma_r)
    end_ts = time.time()
    total_time = end_ts-start_time
    return gs, total_time

def load_dat(location):
    return np.loadtxt(location, delimiter=' ')

if __name__ == '__main__':
    print('=== NEGF starts ===')
    status = True
    start_time = time.time()

    parser = argparse.ArgumentParser(description='Calculate and display DOS '+
                                     'and transmission of the quantum system.')
    parser.add_argument("Folder_Name",
                        help="Name of the folder that contains 'system_parameter.yml' file")
    args = parser.parse_args()

#     location = os.path.realpath(os.path.join(os.getcwd(),
#                                              os.path.dirname(__file__)))

#     location = os.path.join(args.Folder_Name, 'system_parameter.yml')
    input_parameter = yaml_file_loader(args.Folder_Name, 'system_parameter.yml')

    time_list = ['=== Time ===']
    try:
        hc = load_dat(os.path.join(input_parameter['Global']['input_dir'],
                                   'h00.dat'))
        hctl = load_dat(os.path.join(input_parameter['Global']['input_dir'],
                                     'hn1.dat'))
        hctr = load_dat(os.path.join(input_parameter['Global']['input_dir'],
                                     'hp1.dat'))
    except OSError:
        print('!!! Error: Hamiltonian file does not exist !!!')
        status = False
    else:
        try:
            s00 = load_dat(os.path.join(input_parameter['Global']['input_dir'],
                                        's00.dat'))
        except OSError:
            s00 = np.eye(len(hc))

        try:
            sctl = load_dat(os.path.join(input_parameter['Global']['input_dir'],
                                         'sn1.dat'))
        except OSError:
            sctl = np.zeros(hc.shape)

        try:
            sctr = load_dat(os.path.join(input_parameter['Global']['input_dir'],
                                         'sp1.dat'))
        except OSError:
            sctr = np.zeros(hc.shape)

        print('=== Matrices are loaded ===')
        if hc.size == hctl.size == hctr.size == s00.size == sctl.size == sctr.size:
            status = True
            print('=== Matrices are same size ===')
        else:
            status = False
            print('!!! Error: Matrices are not the same size !!!')

    if status:
        e_cap = np.linspace(-10, 10, 1000)
        e_cap = e_cap+1j*0.001

        sigma_l_trace = np.empty(len(e_cap), dtype=complex)
        gs = np.empty(len(e_cap), dtype=object)
        gs_tra = np.empty(len(e_cap), dtype=complex)
        transmission_tra = np.empty(len(e_cap), dtype=complex)

        time_g00_l = 0
        time_g00_r = 0
        time_gs = 0

        for idx1, item_E in enumerate(e_cap):
            g00_l, time_took = self_energy(item_E, hc, hctl, s00, sctl)
            sigma_l = (item_E*sctl - hctl) @ g00_l @ np.matrix.getH(item_E*sctl - hctl)
            time_g00_l = time_g00_l + time_took

            g00_r, time_took = self_energy(item_E, hc, hctr, s00, sctr)
            sigma_r = (item_E*sctr - hctr) @ g00_r @ np.matrix.getH(item_E*sctr - hctr)
            time_g00_r = time_g00_r + time_took

            gs[idx1], time_took = system_gs(item_E, hc, s00, sigma_l, sigma_r)
            time_gs = time_gs + time_took
            gs_tra[idx1] = np.trace(gs[idx1]@s00)

            gamma_l = 1j*(sigma_l-np.matrix.getH(sigma_l))
            gamma_r = 1j*(sigma_r-np.matrix.getH(sigma_r))

            transmission = gamma_l @ gs[idx1] @ gamma_r @ np.matrix.getH(gs[idx1])
            transmission_tra[idx1] = np.trace(transmission)

        end_ts = time.time()
        time_took = end_ts-start_time
        time_g00_l = time_g00_l/len(e_cap)
        time_g00_r = time_g00_r/len(e_cap)
        time_gs = time_g00_l/len(e_cap)

        time_list.append('average time to calculate g00_l %f' % (time_g00_l))
        time_list.append('average time to calculate g00_r %f' % (time_g00_r))
        time_list.append('average time to calculate gs %f' % (time_gs))
        time_list.append('time took for total calculation %f \n' % (time_took))

        print('=== NEGF calculation has completed ===')

        print('=== Saving E.dat file ===')
        global_write(input_parameter['Global']['output_dir'],
                     'E.dat',
                     num_data=e_cap)

        print('=== Saving DOS.dat file ===')
        global_write(input_parameter['Global']['output_dir'],
                     'DOS.dat',
                     num_data=gs_tra)

        print('=== Saving T.dat file ===')
        global_write(input_parameter['Global']['output_dir'],
                     'T.dat',
                     num_data=transmission_tra)

        if input_parameter['NEGF_input']['time'] == 'y':
            for line in time_list:
                print(line)

        if input_parameter['NEGF_input']['plot'] == 'y':
            NEGF_display(e_cap,
                         gs_tra,
                         transmission_tra,
                         input_parameter['Global']['output_dir'])


from typing import Dict, List
from caverna import *
import ai

def play_round(game: Game, state: Game.State, controllers: Dict[Player, Controller]) -> None:
    # Take actions while any player has dwarfs
    while game.work_phase(state):
        player = game.current_player(state)
        action = controllers[player].select_action(game, state)
        print("{} selects {}".format(player, action.name))
        state = game.take(action, state)

    # Return dwarfs
    game.return_dwarfs(state)
    game.harvest(state)
    return state

def main():
    samuel = Player('Samuel')
    maria = Player('Maria')
    controllers = {samuel: ai.MinMax(samuel), maria: ai.Random(maria)}
    game = Game([samuel, maria])
    state = game.initial()
    while not game.over(state):
        print("Round {}".format(state.round))
        state = play_round(game, state, controllers)

    for player in game.players:
        name = player
        score = game.score(state, player)
        print("{name}: {score}".format(name=name, score=score))
        print(state.player_states[player].resources)
    print(controllers[samuel].total)

if __name__ == "__main__":
    main()


import numpy as np

data = np.load('calib_data.npz')['data']
data.resize(32*32,256,1,32)
batch_size=32

def calib_input(iter):

    calib_data = data[iter*batch_size:(iter+1)*batch_size]

    return {'input_1': calib_data}


diasem=input()
qd=int(input())
lisem=['domingo','segunda','terca','quarta','quinta','sexta','sabado']
index = lisem.index(diasem)
if qd==0:
    print(f'chega hoje!')
else:
    entr=(index+qd)%7
    print(f'sera entregue {lisem[entr]}')


from math import degrees, asin

class Measurement:
    def __init__(self, s, h, v0GuessList, distanceList, timeList, timeCorrectionList=None):
        self.s = s  # base range
        self.h = h  # y position of the back of the bazooka
        self.v0GuessList = v0GuessList
        self.distanceList = distanceList
        self.timeList = timeList
        self.timeCorrectionList = timeCorrectionList

    def getAngle(self, y0, l):
        return degrees(asin((y0 - self.h) / l))


import cv2

print("OpenCV Version:\n")
print(cv2.__version__)

img = cv2.imread("mountain.png")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

cv2.imshow("Mountaing",img)
cv2.imshow("Mountain -gray", gray)

cv2.waitKey(0)
cv2.destroyAllWindows()


import requests
import psycopg2
from sqlalchemy import create_engine
from sqlalchemy import text

# Initial config
vm_ip =  "34.176.179.120"# By default the internal ip used by mlflow is 127.0.0.1, but to externalize the model the external  ip of the vm must be written here
vm_port = "5001"

db_pass = "trinibd"
db_ip = "34.176.228.62"
db_name = "postgres"
db_user = "postgres"
db_port = "5432"

def parse_request(request):
  # The request MUST have this format
  # {'dataframe_split': {event_id: '5e82b70d-b550-4bee-9d5d-16a2e73029f9', 'data':[[10,10,10,10]]}}
  #request = request.get_json()

  event_id = request.pop('event_id') if 'event_id' in request else 'no_event_id'

  features = request["data"]
  assert len(features) == 30, 'The request must have the correct ammount of columns (At least)'

  return event_id, features

def save_predictions(event_id, prediction):
  # For remote dbs
  # engine = create_engine(f'postgresql+psycopg2://{db_user}:{db_password}@{db_ip}:{db_port}/{db_name}')

  # For localhost there is no port
  # engine = create_engine(f'postgresql+psycopg2://{db_user}:{db_password}@{db_ip}/{db_name}')

  conn_string = f"host='{db_ip}' dbname='{db_name}' user='{db_user}' password='{db_pass}'"
  conn =  psycopg2.connect(conn_string)
  cursor = conn.cursor()
  cursor.execute(f"""insert into public.inference(id, value) values('{event_id}',{prediction})""")
  conn.commit() # <- We MUST commit to reflect the inserted data
  cursor.close()
  conn.close()

def externalized_model(features) -> str:
  headers = {}

  json_request = {'dataframe_split': {'columns':['casos', 'casospermil', 'hombres80', 'mujeres80', 'pobla80', 'pobla65', 'poblamid', 'pobladata', 'pobladens',
                                                  'mujeres', 'urbano', 'expectvida', 'neontlmort', 'dismort', 'lesion', 'enfnotrans', 'enftrans', 'pbi', 'tuberculosis', 'diabetes', 'medicos',
                                                  'camas', 'immunsaramp', 'tempmarzo', 'hiptenh', 'hiptenm', 'hipten', 'bcg', 'tiempo', 'l10casospermil'],
                                      'data':[features]}}

  response = requests.post(f'http://{vm_ip}:{vm_port}/invocations', headers=headers, json=json_request)
  response = response.json()["predictions"]

  return response[0]

def check_business_logic(features):
  """
  Here We should put some business logic
  We're going to put the min/max of the covid dataset features
  """
  casos, casospermil, hombres80, mujeres80, pobla80, pobla65, poblamid, pobladata, pobladens, mujeres, urbano, expectvida, neontlmort, dismort, lesion, enfnotrans, enftrans, pbi, tuberculosis, diabetes, medicos, camas, immunsaramp, tempmarzo, hiptenh, hiptenm, hipten, bcg, tiempo, l10casospermil = features

  casos_condition =  (2 <= casos) and (casos <= 1699933)
  casospermil_condition =  (0.948707 <= casospermil) and (casospermil <= 	17596.219834)

  hombres80_condition =    (0.087368 <= hombres80) and (hombres80 <= 	6.166254)
  mujeres80_condition =    (0.163864 <= mujeres80) and (mujeres80 <= 	10.556442)

  pobla80_condition =      (0.130777 <= pobla80) and (pobla80 <= 	8.361348)
  pobla65_condition =      (1.085001 <= pobla65) and (pobla65 <= 	27.576370)
  poblamid_condition =     (47.420668 <= poblamid) and (poblamid <=  85.089165)
  pobladata_condition =    (0.001102 <= pobladata) and (pobladata <=  13.927300)
  pobladens_condition =    (0.020406 <= pobladens) and (pobladens <=  79.529984)

  mujeres_condition =      (24.495287	<= mujeres) and (mujeres <= 54.535343)
  urbano_condition =       (13.032000	<= urbano) and (urbano <= 100.000000)

  expectvida_condition =   (49.837000		<= expectvida) and (expectvida <= 81.700000	)
  neontlmort_condition =   (0.900000		<= neontlmort) and (neontlmort <= 42.000000	)

  dismort_condition =      (7.800000			<= dismort) and (dismort <= 30.600000		)
  lesion_condition =       (2.600000		<= lesion) and (lesion <= 28.400000	)
  enfnotrans_condition =   (26.000000			<= enfnotrans) and (enfnotrans <= 95.200000		)
  enftrans_condition =     (1.300000			<= enftrans) and (enftrans <= 65.300000	)
  pbi_condition =          (0.756838			<= pbi) and (pbi <= 123.213936)
  tuberculosis_condition = ( 1.000000			<= tuberculosis) and (tuberculosis <= 611.000000)
  diabetes_condition =     (1.000000			<= diabetes) and (diabetes <= 22.000000			)

  medicos_condition =      (0.017675		<= medicos) and (medicos <= 5.710111		)
  camas_condition =        (0.200000		<= camas) and (camas <= 13.796000	)

  immunsaramp_condition =  (30	<= immunsaramp) and (immunsaramp <= 99	)
  tempmarzocondition =     (-18.720000		<= tempmarzo) and (tempmarzo <= 30.630000	)

  hiptenh_condition =      (9.000000	<= hiptenh) and (hiptenh <= 54.600000)
  hiptenm_condition =      (12.400000	<= hiptenm) and (hiptenm <= 50.600000)
  hipten_condition =       (10.700000			<= hipten) and (hipten <= 50.600000)

  bcg_condition =            (0	== bcg) or (bcg == 1)
  tiempo_condition =         (0		<= tiempo) and (tiempo <= 136)
  l10casospermil_condition = (0.2897465890359868			<= l10casospermil) and (l10casospermil <= 4.245444059518778	)

  return not(
  casos_condition and casospermil_condition and hombres80_condition and mujeres80_condition and pobla80_condition and
  pobla65_condition and poblamid_condition and pobladata_condition and pobladens_condition and mujeres_condition and urbano_condition and expectvida_condition and neontlmort_condition and dismort_condition and
  lesion_condition and enfnotrans_condition and enftrans_condition and pbi_condition and tuberculosis_condition and diabetes_condition and medicos_condition and camas_condition and
  immunsaramp_condition and tempmarzocondition and hiptenh_condition and hiptenm_condition and hipten_condition and bcg_condition and tiempo_condition and l10casospermil_condition
  )

def get_business_prediction(features):
  "Here we could have some function of the feature"

  return -1

def trigger_events(request):
  # This pipeline supposes that we are using it to do just one inference at the time
  # If we want to do more inferences, we need to modify the functions to be able to handle them

  #This is to work inside the lambda fn
  request = request.get_json()
  event_id, features = parse_request(request)

  if check_business_logic(features):
      prediction = get_business_prediction(features)

  else:
      prediction = externalized_model(features)

  save_predictions(event_id, prediction)

  return str(prediction)

# Prueba cumpliendo con business logic
#{"event_id": "17cfe7d5-3cdb-4e62-861d-0371b79f16f2",
#"data": [10200, 382.5, 0.5, 0.45, 0.32, 3.21, 62.34, 0.42, 0.61,
#            52.67, 23.45, 60.52, 38.2, 19.7, 15.5, 45.1, 35.8, 1.23,
#            192, 10.3, 0.45, 0.32, 68, 19.1, 22.2, 22.2, 19.3,
#            1, 53, 0.6]}

# Prueba que no cumple business logic

#{"event_id": "17cfe7d5-3cdb-4e62-861d-0371b79f16f2",
#"data": [-10200, 382.5, 0.5, 0.45, 0.32, 3.21, 62.34, 0.42, 0.61,
#            52.67, 23.45, 60.52, 38.2, 19.7, 15.5, 45.1, 35.8, 1.23,
#            192, 10.3, 0.45, 0.32, 68, 19.1, 22.2, 22.2, 19.3,
#            1, 53, 0.6]}


import random
from os import listdir

import numpy as np
from PIL import Image
from PIL import ImageFilter

####### Object Classes ####
# 2: Red Canon
# 1: Red Caster
# 0: Red Melee

####### Params ############
# Print out the status messages and where stuff is placed
verbose = False
# Important the leaf directories have to be called masked_champions, masked_minions, masked_towers or you have to change add_object to write the object classes properly
# Directory in which the masked minion images are located
masked_minions = "../src_data/masked_minions"
# Directory in which the map backgrounds are located
map_images_dir = "../src_data/map_screenshots"
# Directory in which the dataset will be stored (creates jpegs and labels subdirectory there)
# Attention if you use darknet to train: the structure has to be exactly as follows:
# - Dataset
# -- images
# --- XYZ0.jpg
# --- XYZ1.jpg
# -- labels
# --- XYZ0.txt
# --- XYZ1.txt
# -- train.txt
# -- test.txt
output_dir = "output"
# Prints a box around the placed object in red (for debug purposes)
print_box = False
# Size of the datasets the program should generate
dataset_size = 10000
# Beginning index for naming output files
start_index = 0
# How many minons should be added minimum/maximum to each sample
minions_min = 1
minions_max = 10
assert (minions_min <= minions_max), "Error, minions_max needs to be larger than minions_min!"
# The scale factor of how much a champion image needs to be scaled to have a realistic size
scale_minions = 1
random_scale_minions = 0.25
# Random rotation maximum offset in counter-/clockwise direction
rotate = 10
# Output image size
output_size = (2560, 1440)
# Factor how close the objects should be clustered around the bias point larger->less clustered but also more out of the image bounds, value around 100 -> very clustered
bias_strength = 220  # 220 is good, dont select too large or the objects will be too often out of bounds
# Resampling method of the object scaling
# sampling_method = Image.BICUBIC
sampling_method = Image.BILINEAR  # IMO the best but use both to have more different methods
# Add random noise to pixels
noise = (0, 0, 0)
# Blur the image
blur = False
blur_strength = 1.4  # 0.6 is a good value
# Sometimes randomly add a cursor
cursors_min = 0
cursors_max = 0
assert (cursors_min <= cursors_max), "Error, cursors_max needs to be larger than cursors_min!"
cursor_scale = 0.40  # 0.45 seems good
cursor_random = 0.2
cursor_path = "../src_data/cursor"
# Padding for the bias point (to keep the clustering of the minions from spawning minions outside of the image
padding = 400
########### Helper functions ###################
"""
This funciton applies random noise to the rgb values of a pixel (R,G,B)
"""

def apply_noise(pixel):
    R = max(0, min(255, pixel[0] + random.randint(-noise[0], noise[0])))
    G = max(0, min(255, pixel[1] + random.randint(-noise[1], noise[1])))
    B = max(0, min(255, pixel[2] + random.randint(-noise[2], noise[2])))
    A = pixel[3]
    return (R, G, B, A)

"""
This function places a masked image with a given path onto a map fragment
Passing -1 to the object class allows you to set objects like the UI that are not affected by rotations bias etc.
"""

def add_object(path, cur_image_path, object_class, bias_point, last):
    # Set up the map data
    map_image = Image.open(cur_image_path)
    map_image = map_image.convert("RGBA")
    # Cut the image to the desired output image size
    map_data = map_image.getdata()
    w, h = map_image.size
    if verbose:
        print("Adding object: ", path)
    # Read the image file of the current object to add
    obj = Image.open(path)
    if object_class >= 0:
        # Randomly rotate the image, but make the normal orientation most likely using a normal distribution
        obj = obj.rotate(np.random.normal(loc=0.0, scale=rotate), expand=True)
    obj = obj.convert("RGBA")
    obj_w, obj_h = obj.size
    # Rescale the image based on the scale factor
    if object_class == 0 or object_class == 1 or object_class == 2:  # red canon minion
        scale_factor = random.uniform(scale_minions - random_scale_minions, scale_minions + random_scale_minions)
        size = int(obj_w * scale_factor), int(obj_h * scale_factor)
    elif object_class == -1:  # Cursor
        scale_factor = random.uniform(cursor_scale - cursor_random, cursor_scale + cursor_random)
        size = int(obj_w * scale_factor), int(obj_h * scale_factor)
    else:
        size = int(obj_w), int(obj_h)

    # Compute the position of minions based on the bias point. Normally distribute the mininons around
    # a central point to create clusters of objects for more realistic screenshot fakes
    # Champions and structures are uniformly distributed
    if object_class == -1:  # Champion or structure or cursor
        obj_pos_center = (random.randint(0, w - 1), random.randint(0, h - 1))
    else:
        x_coord = np.random.normal(loc=bias_point[0], scale=bias_strength)
        y_coord = np.random.normal(loc=bias_point[1], scale=bias_strength)
        obj_pos_center = (int(x_coord), int(y_coord))

    # Resize the image based on the scaling above
    obj = obj.resize(size, resample=sampling_method)
    obj_w, obj_h = obj.size

    if verbose:
        print("Placing at : {}|{}".format(obj_pos_center[0], obj_pos_center[1]))
    # Extract the image data
    obj_data = obj.getdata()
    out_data = np.array(map_image)
    last_pixel = 0
    # Compute the object corners
    min_x = int(min(w, max(0, obj_pos_center[0] - obj_w / 2 - 2)))
    max_x = int(min(w, max(0, obj_pos_center[0] + obj_w / 2 + 2)))
    min_y = int(min(h, max(0, obj_pos_center[1] - obj_h / 2 - 2)))
    max_y = int(min(h, max(0, obj_pos_center[1] + obj_h / 2 + 2)))
    # Place the images
    for y in range(min_y, max_y):
        for x in range(min_x, max_x):
            pixel = (0, 0, 0, 0)
            # Compute the pixel index in the map fragment
            map_index = x + w * y
            # print("x: ", x, " y: ", y)
            # If we want to print the box around the object, set the pixel to red
            if print_box is True and y == obj_pos_center[1] - int(obj_h / 2) and \
                    obj_pos_center[0] - int(obj_w / 2) < x < obj_pos_center[0] + int(obj_w / 2):
                pixel = (255, 0, 0, 255)
            elif print_box is True and y == obj_pos_center[1] + int(obj_h / 2) and \
                    obj_pos_center[0] - int(obj_w / 2) < x < obj_pos_center[0] + int(obj_w / 2):
                pixel = (255, 0, 0, 255)
            elif print_box is True and x == obj_pos_center[0] - int(obj_w / 2) and \
                    obj_pos_center[1] - int(obj_h / 2) < y < obj_pos_center[1] + int(obj_h / 2):
                pixel = (255, 0, 0, 255)
            elif print_box is True and x == obj_pos_center[0] + int(obj_w / 2) and \
                    obj_pos_center[1] - int(obj_h / 2) < y < obj_pos_center[1] + int(obj_h / 2):
                pixel = (255, 0, 0, 255)
            else:
                # Replace the old input image pixels with the object to add pixels
                if obj_pos_center[0] - int(obj_w / 2) <= x <= obj_pos_center[0] + int(obj_w / 2) \
                        and obj_pos_center[1] - int(obj_h / 2) <= y <= obj_pos_center[1] + int(obj_h / 2):
                    obj_x = x - obj_pos_center[0] - int(obj_w / 2) - 1
                    obj_y = y - obj_pos_center[1] - int(obj_h / 2) - 1
                    object_index = (obj_x + obj_w * obj_y)
                    # Check the alpha channel of the object to add
                    # If it is smaller 150, the pixel is invisible, 255: fully visible, 150: seethrough (brush simulation)
                    # Then use the original images pixel value
                    # Else use the object to adds pixel value
                    if obj_data[object_index][3] == 255:
                        pixel = (obj_data[object_index][0], obj_data[object_index][1], obj_data[object_index][2], 255)
                        last_pixel += 1
                    elif obj_data[object_index][3] == 0:
                        pixel = (map_data[map_index][0], map_data[map_index][1], map_data[map_index][2], 255)
                else:
                    pixel = (
                        map_data[map_index][0], map_data[map_index][1], map_data[map_index][2], map_data[map_index][3])
            out_data[y, x] = pixel
    if last and (noise[0] > 0 or noise[1] > 0 or noise[2] > 0):
        for y in range(0, h):
            for x in range(0, w):
                # Compute the pixel index in the map fragment
                map_index = x + w * y
                out_data[y, x] = apply_noise(out_data[y, x])
    # Save the image
    map_image = Image.fromarray(np.array(out_data))
    if blur and last:
        map_image = map_image.filter(ImageFilter.GaussianBlur(radius=blur_strength))
    map_image = map_image.convert("RGB")
    map_image.save(output_dir + "/images/" + filename + ".jpg", "JPEG")
    # Append the bounding box data to the labels file if the object class is not -1
    if object_class >= 0:
        with open(output_dir + "/labels/" + filename + ".txt", "a") as f:
            # Write the position of the object and its bounding box data to the labels file
            # All values are relative to the whole image size
            # Format: class, x_pos, y_pos, width, height
            f.write("" + str(object_class) + " " + str(float(obj_pos_center[0] / w)) + " " + str(
                float(obj_pos_center[1] / h)) + " " + str(float(obj_w / w)) + " " + str(float(obj_h / h)) + "\n")

########### Main function ######################
maps = sorted(listdir(map_images_dir))

for dataset in range(0, dataset_size):
    filename = str(dataset + start_index)
    print("Dataset: ", dataset, " / ", dataset_size, " : ", filename)
    # Randomly select a map background
    mp_fnam = map_images_dir + "/" + random.choice(maps)
    if verbose:
        print("Using map fragment: ", mp_fnam)

    # Randomly add 0-12 minions to the image
    # TODO change classification for blue and superminions
    minions = []
    for i in range(0, random.randint(minions_min, minions_max)):
        # Select a random subdirectory because the minions are sorted in subdirectories
        minions_dir = random.choice(sorted(listdir(masked_minions)))
        if minions_dir == "red_cannon":
            minions.append([masked_minions + "/" + minions_dir + "/" + random.choice(
                sorted(listdir(masked_minions + "/" + minions_dir))), 2])
        elif minions_dir == "red_caster":
            minions.append([masked_minions + "/" + minions_dir + "/" + random.choice(
                sorted(listdir(masked_minions + "/" + minions_dir))), 1])
        elif minions_dir == "red_melee":
            minions.append([masked_minions + "/" + minions_dir + "/" + random.choice(
                sorted(listdir(masked_minions + "/" + minions_dir))), 0])
        else:
            print("Error: This folder: ", minions_dir,
                  " was not specified to contain masked images. Skipping. Atention! Dataset might be broken!")
    if verbose:
        print("Adding {} minions!".format(len(minions)))

    # Now figure out the order in which we want to add the objects (So that sometimes objects will overlap)
    objects_to_add = minions
    random.shuffle(objects_to_add)
    # Read in the current map background as image
    map_image = Image.open(mp_fnam)
    w, h = map_image.size
    # Make sure the image is 2560x1440 (otherwise the overlay might not fit properly)
    assert (w == 2560 and h == 1440), "Error image has to be 2560x1440"

    map_image.save(output_dir + "/images/" + filename + ".jpg", "JPEG")
    cur_image_path = output_dir + "/images/" + filename + ".jpg"
    # Iterate through all objects in the order we want them to be added and add them to the background
    # Note this function also saves the image already
    # Point around which the objects will be clustered
    bias_point = (random.randint(padding, w - 1 - padding), random.randint(padding, h - 1 - padding))
    gui_areas = [[2000, 700, 2560, 1440], [750, 1250, 1600, 1440]]
    in_gui = True

    while in_gui:
        for gui_area in gui_areas:
            if gui_area[0] < bias_point[0] < gui_area[2]:
                in_gui = True
            elif gui_area[1] < bias_point[1] < gui_area[3]:
                in_gui = True
            else:
                in_gui = False
        if in_gui:
            bias_point = (random.randint(padding, w - 1 - padding), random.randint(padding, h - 1 - padding))

    for i in range(0, len(objects_to_add)):
        o = objects_to_add.pop()
        if len(objects_to_add) == 0:
            add_object(o[0], cur_image_path, o[1], bias_point, True)  # Set last to true to apply the possible noise
        else:
            add_object(o[0], cur_image_path, o[1], bias_point, False)
    # Lastly add a cursor
    for i in range(cursors_min, random.randint(cursors_min, cursors_max)):
        cursor = cursor_path + "/" + random.choice(sorted(listdir(cursor_path)))
        add_object(cursor, cur_image_path, -1, bias_point, False)
        # If no objects were added we still have to create an empty txt file
    with open(output_dir + "/labels/" + filename + ".txt", "a") as f:
        f.write("")
    if verbose:
        print("=======================================")


'''
This file contains methods to perform crud operation of sf instance
'''

# import slaesforce login credentials
import config
from simple_salesforce import Salesforce
import json

class ProductInstance:
    def __init__(self):
        try:
            self.connection = Salesforce(config.username,config.password,config.security_token)
            self.error = None
        except:
            self.connection = None
            self.error = "Invalid Credentials"

    def where(self,field,value):
        desc = self.connection.Product_Instance__c.describe()
        field_names_list = [field['name'] for field in desc['fields']]
        part = {name:None for name in field_names_list}
        field_names = ",".join(field_names_list)
        soql = "SELECT %s FROM Product_Instance__c WHERE %s = '%s'"%(field_names,field,value)
        results = self.connection.query_all(soql)
        self.count = results['totalSize']
        self.records = list()
        for record in results['records']:
            for key in field_names_list:
                part[key] = record[key]
            self.records.append(part)
            print(json.dumps(self.records))

    def getError(self):
        return self.error


from datetime import datetime
from Analizador import Analizador
from Cuenta import Cuenta

class Reporte:
    def __init__(self):
        self.fecha_generacion = datetime.now()

    def ocultar_digitos_cedula(self, cliente):
        # Mostrar solo los últimos 4 dígitos de la cédula del cliente
        return '******' + cliente.get_cedula()[-4:]

    def generar_reporte(self, cuentas):
        if not cuentas:
            print("No hay cuentas para generar el reporte.")
            return

        analizador = Analizador()
        saldo_promedio = analizador.calcular_saldo_promedio(cuentas)

        print("\n=== INFORME FINANCIERO ===")
        print(f"Fecha de Generación del Informe: {self.fecha_generacion}")
        print(f"Número total de cuentas: {len(cuentas)}")

        if saldo_promedio is not None:
            print(f"Saldo Promedio de las cuentas: ${saldo_promedio:.2f}")

        print("\nDetalles de cada cuenta:")
        for cuenta in cuentas:
            print(f"\nNúmero de Cuenta: {cuenta.get_numero_cuenta()}")
            print(f"Cédula del Cliente: {self.ocultar_digitos_cedula(cuenta.get_titular_cedula())}")
            print(f"Saldo de la Cuenta: ${cuenta.get_saldo():.2f}")


class Farm:
    def __init__(self,owner_name):
        self.owner_name=owner_name
        self.farm_animals=[]
    def add_animal(self,animal,*args):
        self.farm_animals.append(animal)
        nb=int(*args)-1
        while nb>0 :
            self.farm_animals.append(animal)
            nb-=1
    def get_info(self):
        dic={}
        print(f"{self.owner_name}'s Farm")
        print()
        for animal in self.farm_animals:
            if animal not in dic:
                dic[animal]=self.farm_animals.count(animal)
        for key , value in dic.items():
            print(f"{key}:  {value}")
        print()
        return "\tE-I-E-I-0!"

"""
mc=Farm("Cd")
mc.add_animal("mouton")
mc.add_animal("cabri",5)
mc.add_animal("mouton",6)
mc.add_animal("cabri")
"""

macdonald = Farm("McDonald")
macdonald.add_animal('cow',5)
macdonald.add_animal('sheep')
macdonald.add_animal('sheep')
macdonald.add_animal('goat', 12)
print(macdonald.get_info())