from collections import defaultdict
import pandas as pd
import datetime
from lode.utilities.util import parse_date
from itertools import izip

def create_date_limited_sql(master_table, dates=None,
                            begin_date=None, end_date=None,
                            date_col="trading_date", range_break="Year"):
    """
    This is the initialisation function which takes into account the separation
    of the tables on a year by year basis in the Database (due to memory
    considerations). It is called with either the dates keyword or both the
    begin_date and end_date keywords in order to change the behaviour apparent.
    These are ensured to exist by the check_required_range function which has
    been previously run. Will return a list of queries which may then be
    modified as needed to construct the full custom queries desired

    Parameters:
    -----------
    master_table: The master table to query
    dates: A string or iterable object of dates to return
    begin_date: The first date in a range of dates to return
    end_date: The last date in a range of dates to return
    date_col: What column the dates are contained in
    range_break: A modification for performance purposes, default set to Year
                 but setting to 'Month' may result in reduced memory usage.

    Returns:
    --------
    all_queries: A list of SQL queries contained as strings
    """

    all_queries = []
    # If passing a selection of date objects
    if dates:
        if hasattr(dates, '__iter__'):
            return list(singular_sql_dates(master_table, dates, date_col))

        else:
            dt = parse_date(dates)
            return ["""SELECT * FROM %s_%s WHERE %s='%s'""" % (
                master_table, dt.year, date_col, dt.strftime('%d-%m-%Y'))]

    # Work with Date Ranges
    else:
        if range_break == "Year":
            return list(yearly_sql_dates(begin_date, end_date, master_table,
                                         date_col))

        elif range_break == "Month":
            return list(monthly_sql_dates(begin_date, end_date, master_table,
                                          date_col))

        else:
            raise ValueError("""Range Breaks for %s have not been
                                implemented, try 'Year'""" % range_break)

    return all_queries

def singular_sql_dates(master_table, dates, date_col):
    """
    For a list of dates this will create a series of SQL queries with the
    basic format SELECT * FROM table where dates in date_col. It has a little
    bit of magic in it to handle the fact that tables are sharded into smaller
    tables, often on a year by year basis.

    It also handles parsing dates if needed (although datetime objects may be
    passed to the method).

    Parameters:
    -----------
    master_table: The root database table to construct the query for, e.g. for
                  nodal_prices_2012  this would just simply be nodal_prices
    dates: Either a singluar date string or object or a list of date strings
           and objects to construct the SQL queries for. These may be in any
           order for any number of dates
    date_col: The column name for the dates in the SQL database

    Returns:
    --------
    SQL: This is a generator expression where each iteration is a separate
         SQL query for each year with all of the dates from that year contained
         as a selection query

    """

    dts = [parse_date(x) for x in dates]

    # Map the specific dates to the specific years isomg a default dict
    years_dict = defaultdict(list)
    for dt in dts:
        years_dict[dt.year].append(dt)

    # Iterate through each of the years and add the trading dates belonging
    # to each query to a specific query, yield this SQL string as a generator
    for year in years_dict:
        # Set up a custom string and then place it inside brackets for
        # Use in the query
        strings = join_date_strings(years_dict[year])
        date_string = "('%s')" % strings

        # The base query string to use
        query_string = """ SELECT * FROM %s_%s WHERE %s in %s"""

        # Substitute the values into the string
        SQL = query_string % (master_table, year, date_col, date_string)

        yield SQL

def yearly_sql_dates(begin_date, end_date, mtable, date_col,
                     df="%d-%m-%Y"):
    """
    Create full year SQL dates which ar every useful if a range goes over
    the yearly amount. For example, if the requested date range is
    20/12/2014 to 20/02/2015 then this requires querying both the 2014 and
    the 2015 table. This function creates two separate queries for each of
    the tables which allows this to happen behind the scenes. Should only
    be called if the yearly overlap is different.

    Note that this is a kind of a hacky use of a generator to create the
    SQL queries desired but this is due to the desire to use smaller table
    sizes on RAM limited machines. For example, a year of data is often 1GB
    of data and as there are 10+ years this exceeds the RAM available on an
    8GB machine easily.

    Parameters:
    -----------
    begin_date: String or datetime object of the first date to consider
    end_date: String or datetime object of the last date to consider
    mtable: What table to query (master)
    date_col: The column containing the trading dates
    df: The date format to use if needed

    Returns:
    --------
    query_string: A string containing the appropriate date SQL query as a base

    """
    # Parse the dates as they're probably strings
    begin_date = parse_date(begin_date)
    end_date = parse_date(end_date)

    # Set up dummy strings
    jan1, dec31 = "01-01-%s", "31-01-%s"
    query_string = """SELECT * FROM %s_%s WHERE %s BETWEEN '%s' AND '%s'"""

    if begin_date.year == end_date.year:
        fd, ld = begin_date.strftime(df), end_date.strftime(df)
        yield query_string % (mtable, begin_date.year, date_col, fd, ld)

    else:

        # Return the first string
        # From the beginning date to the 31st of December
        fd, ld = begin_date.strftime(df), dec31 % begin_date.year
        yield query_string % (mtable, begin_date.year, date_col, fd, ld)

        # Yield the intermediate dates if any
        # For example, if we are "12/12/2013" and "02/04/2015" we would
        # still want  all of the dates in 2014 to be returned.
        years = range(begin_date.year + 1, end_date.year)
        if len(years) > 0:
            for year in years:
                fd, ld = jan1 % year, dec31 % year
                yield query_string % (mtable, year, date_col, fd, ld)

        # Yield the last date
        # This is from the 1st of January of that year to the ending date
        if end_date.year != begin_date.year:
            fd, ld = jan1 % end_date.year, end_date.strftime(df)
            yield query_string % (mtable, end_date.year, date_col, fd, ld)

def monthly_sql_dates(begin_date, end_date, mtable, date_col, df='%d-%m-%Y'):
    """
    Returns queries which have been isolated on a per month basis which can
    then be fed into a DataFrame.

    This is a modified version of the yearly SQL dates return function which
    has been implemented due to memory considerations. There is a cut off
    where the additional overhead from running more queries is less than the
    overhead of holding large datasets in memory and coercing these to Pandas
    DataFrames. By using a generator expressions we are able to overcome this
    and keep total RAM usage reduced as the garbage collection runs.

    Parameters:
    -----------
    begin_date: The first date as either a datetime object or string
    end_date: The last date as either a datetime object or string
    mtable: The master table to query from
    date_col: What column contains date information
    df: What date format to use

    Returns:
    --------
    query_string: The SQL query which we may then modify

    """
    query_string = """SELECT * FROM %s_%s WHERE %s BETWEEN '%s' AND '%s'"""

    # Parse the dates as they're probably strings
    begin_date = parse_date(begin_date)
    end_date = parse_date(end_date)

    # Add an additional day in order to get the next months
    month_range = list(pd.date_range(begin_date, end_date, freq="M"))
    month_range_p1 = [x + datetime.timedelta(days=1) for x in
                      month_range]

    if month_range[-1] == end_date:
        end_dates = month_range
    else:
        end_dates = month_range + [end_date]

    # Can I do this functionally? I don't want to mutate the data
    # structures, currently copying the list
    begin_dates = [begin_date] + month_range_p1

    for s, e in izip(begin_dates, end_dates):
        beg, end = s.strftime(df), e.strftime(df)

        yield query_string % (mtable, s.year, date_col, beg, end)

def join_date_strings(dates, separator="','", df="%d-%m-%Y"):
    """
    Join a list of dates together in a specific string time format separated
    by a custom string. In many cases this is used to get it into the SQL
    format string needed
    """
    return separator.join([x.strftime(df) for x in dates])

def add_equality_constraint(column, values):

    if not hasattr(values, '__iter__'):
        return add_single_selection_constraint(column, values)
    else:
        return add_multiple_selection_constraint(column, values)

def add_exclusion_constraint(column, values):

    if not hasattr(values, '__iter__'):
        return add_single_exclusion_constraint(column, values)
    else:
        return add_multiple_exclusion_constraint(column, values)

def add_minimum_constraint(column, value):
    return """ AND %s >= '%s'""" % (column, value)

def add_maximum_constraint(column, value):
    return """ AND %s <= '%s'""" % (column, value)

def add_range_constraint(column, begin, end):
    return """ AND %s BETWEEN '%s' AND '%s'""" % (column, begin, end)

def add_single_selection_constraint(column, value):
    return """ AND %s='%s'""" % (column, value)

def add_multiple_selection_constraint(column, values):
    joined = "','".join(values)
    jvalues = "('%s')" % joined
    return """ AND %s IN %s""" % (column, jvalues)

def add_single_exclusion_constraint(column, value):
    return """ AND %s!='%s'""" % (column, value)

def add_multiple_exclusion_constraint(column, values):
    joined = "','".join(values)
    jvalues = "('%s')" % joined
    return """ AND %s NOT IN %s""" % (column, jvalues)

if __name__ == '__main__':
    pass


from datetime import date
atual = date.today().year
totalmenor = 0
totalmaior = 0
for ano in range(1, 8):
    pessoa = int(input('Em que ano a {}ª nasceu? '.format(ano)))
    idade = atual - pessoa
    print('Essa pessoa tem {} anos.'.format(idade))
    if idade < 21:
        totalmenor += + 1
    else:
        totalmaior += +1
print('O total de maiores foi de: {}'.format(totalmaior))
print('O total de menores foi de: {}'.format(totalmenor))


import face_recognition
from PIL import Image, ImageDraw

# This is an example of running face recognition on a single image
# and drawing a box around each person that was identified.

# Load a sample picture and learn how to recognize it.
neutral_image = face_recognition.load_image_file("neutral.jpg")
neutral_face_encoding = face_recognition.face_encodings(neutral_image)[0]

# Load a second sample picture and learn how to recognize it.
sad_image = face_recognition.load_image_file("sad.jpg")
sad_face_encoding = face_recognition.face_encodings(sad_image)[0]

fear_image = face_recognition.load_image_file("fear.jpg")
fear_face_encoding = face_recognition.face_encodings(fear_image)[0]

disgust_image = face_recognition.load_image_file("disgust.jpg")
disgust_face_encoding = face_recognition.face_encodings(disgust_image)[0]
happy_image = face_recognition.load_image_file("happy.jpg")
happy_face_encoding = face_recognition.face_encodings(happy_image)[0]
angry_image = face_recognition.load_image_file("angry.jpg")
angry_face_encoding = face_recognition.face_encodings(angry_image)[0]
surprize_image = face_recognition.load_image_file("surprize.jpg")
surprize_face_encoding = face_recognition.face_encodings(surprize_image)[0]
# Create arrays of known face encodings and their names
known_face_encodings = [
    neutral_face_encoding,
    sad_face_encoding,
    fear_face_encoding,
    disgust_face_encoding,
    happy_face_encoding,
    angry_face_encoding,
    surprize_face_encoding
]
known_face_names = [
    "neutral",
    "sad",
    "happy",
    "surprize","disgust","fear","angry"

]

# Load an image with an unknown face
unknown_image = face_recognition.load_image_file("exp.jpg")

# Find all the faces and face encodings in the unknown image
face_locations = face_recognition.face_locations(unknown_image)
face_encodings = face_recognition.face_encodings(unknown_image, face_locations)

# Convert the image to a PIL-format image so that we can draw on top of it with the Pillow library
# See http://pillow.readthedocs.io/ for more about PIL/Pillow
pil_image = Image.fromarray(unknown_image)
# Create a Pillow ImageDraw Draw instance to draw with
draw = ImageDraw.Draw(pil_image)

# Loop through each face found in the unknown image
for (top, right, bottom, left), face_encoding in zip(face_locations, face_encodings):
    # See if the face is a match for the known face(s)
    matches = face_recognition.compare_faces(known_face_encodings, face_encoding)

    name = "Unknown"

    # If a match was found in known_face_encodings, just use the first one.
    if True in matches:
        first_match_index = matches.index(True)
        name = known_face_names[first_match_index]

    # Draw a box around the face using the Pillow module
    draw.rectangle(((left, top), (right, bottom)), outline=(0, 0, 255))

    # Draw a label with a name below the face
    text_width, text_height = draw.textsize(name)
    draw.rectangle(((left, bottom - text_height - 10), (right, bottom)), fill=(0, 0, 255), outline=(0, 0, 255))
    draw.text((left + 6, bottom - text_height - 5), name, fill=(255, 255, 255, 255))

# Remove the drawing library from memory as per the Pillow docs
del draw

# Display the resulting image
pil_image.show()

# You can also save a copy of the new image to disk if you want by uncommenting this line
# pil_image.save("image_with_boxes.jpg")


from __future__ import unicode_literals, print_function, division
__author__ = "mozman <mozman@gmx.at>"

import os
import zipfile
import random
from datetime import datetime

from .xmlns import etree, CN
from .manifest import Manifest
from .compatibility import tobytes, bytes2unicode, is_bytes, is_zipfile
from .compatibility import is_stream, StringIO

FNCHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'

class FileObject(object):
    __slots__ = ['element', 'media_type', 'zipinfo']

    def __init__(self, name, element, media_type=""):
        self.element = element
        self.media_type = media_type
        now = datetime.now().timetuple()
        self.zipinfo = zipfile.ZipInfo(name, now[:6])
        self.zipinfo.compress_type = zipfile.ZIP_DEFLATED

    def tobytes(self):
        if hasattr(self.element, 'tobytes'):
            if self.media_type == 'text/xml':
                return self.element.tobytes(xml_declaration=True)
            else:
                return self.element.tobytes()
        else:
            return tobytes(self.element)

    @property
    def filename(self):
        return self.zipinfo.filename

class FileManager(object):
    def __init__(self, zipname=None):
        self.directory = dict()
        self.zipname = zipname
        self.manifest = Manifest(self.get_bytes('META-INF/manifest.xml'))
        self.register('META-INF/manifest.xml', self.manifest, 'text/xml')

    def has_zip(self):
        if self.zipname is not None:
            return is_zipfile(self.zipname)
        return False

    def _open_bytestream(self):
        return open(self.zipname, 'rb')

    def tmpfilename(self, basefile=None):
        def randomname(count):
            return ''.join(random.sample(FNCHARS, count))

        folder = "" if basefile is None else os.path.dirname(basefile)
        while True:
            filename = os.path.abspath(os.path.join(folder, randomname(8)+'.tmp'))
            if not os.path.exists(filename):
                return filename

    def register(self, name, element, media_type=""):
        self.directory[name] = FileObject(name, element, media_type)
        # 'mimetype' need not to be in the manifest.xml file, but it seems
        # not to break the vadility of the manifest file:
        # if name != 'mimetype:
        #     self.manifest.add(name, media_type)
        self.manifest.add(name, media_type)

    def save(self, filename, backup=True):
        # always create a new zipfile
        write_to_memory = False
        if is_stream(filename):
            write_to_memory = True
        if write_to_memory:
            tmpfilename = filename
        else:
            tmpfilename = self.tmpfilename(filename)
        zippo = zipfile.ZipFile(tmpfilename, 'w', zipfile.ZIP_DEFLATED)
        self._tozip(zippo)
        zippo.close()

        if write_to_memory:
            # job done
            return

        if os.path.exists(filename):
            if backup:
                # existing document becomes the backup file
                bakfilename = filename+'.bak'
                # remove existing backupfile
                if os.path.exists(bakfilename):
                    os.remove(bakfilename)
                os.rename(filename, bakfilename)
            else:
                # just remove the existing document
                os.remove(filename)

        # rename the new created document
        os.rename(tmpfilename, filename)
        self.zipname = filename

    def get_bytes(self, filename):
        """ Returns a byte stream or None. """
        filecontent = None
        if self.has_zip():
            bytestream = self._open_bytestream()
            zipfile_ = zipfile.ZipFile(bytestream, 'r')
            try:
                filecontent = zipfile_.read(filename)
            except KeyError:
                pass
            zipfile_.close()
            bytestream.close()
        return filecontent

    def get_text(self, filename, default=None):
        """ Retuns a str or 'default'. """
        filecontent = self.get_bytes(filename)
        if filecontent is not None:
            return bytes2unicode(filecontent)
        else:
            return default

    def get_xml_element(self, filename):
        filecontent = self.get_bytes(filename)
        if filecontent:
            return etree.XML(filecontent)
        else:
            return None

    def _tozip(self, zippo):
        # mimetype file should be the first & uncompressed file in zipfile
        mimetype = self.directory.pop('mimetype')
        mimetype.zipinfo.compress_type = zipfile.ZIP_STORED
        zippo.writestr(mimetype.zipinfo, mimetype.tobytes())
        processed = [mimetype.filename]

        for file in self.directory.values():
            zippo.writestr(file.zipinfo, file.tobytes())
            processed.append(file.filename)

        # push mimetype back to directory
        self.directory['mimetype'] = mimetype
        self._copy_zip_to(zippo, processed)

    def _copy_zip_to(self, newzip, ignore=[]):
        """ Copy all files like pictures and settings except the files in 'ignore'.
        """
        if not self.has_zip():
            return # nothing to copy
        try:
            bytestream = self._open_bytestream()
        except IOError:
            return # nothing to copy

        origzip = zipfile.ZipFile(bytestream)
        try:
            self._copy_from_zip_to_zip(origzip, newzip, ignore)
        finally:
            origzip.close()
            bytestream.close()

    @staticmethod
    def _copy_from_zip_to_zip(fromzip, tozip, ignore):
        for zipinfo in fromzip.filelist:
            if zipinfo.filename not in ignore:
                tozip.writestr(zipinfo, fromzip.read(zipinfo.filename))

    def tobytes(self):
        iobuffer = StringIO()
        zippo = zipfile.ZipFile(iobuffer, 'w', zipfile.ZIP_DEFLATED)
        self._tozip(zippo)
        zippo.close()
        buffer = iobuffer.getvalue()
        del iobuffer
        return buffer

def check_zipfile_for_oasis_validity(filename, mimetype):
    """ Checks the zipfile structure and least necessary content, but not the
    XML validity of the document.
    """
    def check_manifest(stream):
        xmltree = etree.XML(stream)
        directory = dict([ (e.get(CN('manifest:full-path')), e) for e in xmltree.findall(CN('manifest:file-entry')) ])
        for name in ('content.xml', 'meta.xml', 'styles.xml', '/'):
            if name not in directory:
                return False
        if bytes2unicode(mimetype) != directory['/'].get(CN('manifest:media-type')):
            return False
        return True

    assert is_bytes(mimetype)
    if not is_zipfile(filename):
        return False
    # The first file in an OpenDocumentFormat zipfile should be the uncompressed
    # mimetype file, in a regular zipfile this file starts at byte position 30.
    # see also OASIS OpenDocument Specs. Chapter 17.4
    # LibreOffice ignore this requirement and opens all documents with
    # valid content (META-INF/manifest.xml, content.xml).
    with open(filename, 'rb') as f:
        buffer = f.read(38 + len(mimetype))
    if buffer[30:] != b'mimetype'+mimetype:
        return False
    zf = zipfile.ZipFile(filename)
    names = zf.namelist()
    if 'META-INF/manifest.xml' in names:
        manifest = zf.read('META-INF/manifest.xml')
    else:
        manifest = None
    zf.close()

    if manifest is None:
        return False
    # meta.xml and styles.xml are not required, but I think they should
    for filename in ['content.xml', 'meta.xml', 'styles.xml', 'mimetype']:
        if filename not in names:
            return False
    result = check_manifest(manifest)
    return result


#!/usr/bin/python3
from brownie import CallMeChallenge
from scripts.deploy import deploy
from scripts.helpful_scripts import get_account
from colorama import Fore

# * colours
green = Fore.GREEN
red = Fore.RED
blue = Fore.BLUE
magenta = Fore.MAGENTA
reset = Fore.RESET

def print_colour(target, solved=False):
    if solved:
        print(f"{blue}Is complete: {green}{target.isComplete()}{reset}")
    else:
        print(f"{blue}Is complete: {red}{target.isComplete()}{reset}")

def hack(contract_address=None, attacker=None):
    if not contract_address:
        target, _ = deploy()
        _, attacker = get_account()
    else:
        target = CallMeChallenge.at(contract_address)

    # print(target.address)
    print_colour(target, target.isComplete())

    tx = target.callme({"from": attacker})
    tx.wait(1)

    # print(f"{blue}Is complete: {green}{target.isComplete()}{reset}")
    print_colour(target, target.isComplete())

    assert target.isComplete() == True

def main(contract_address=None):
    if contract_address:
        hack(contract_address, get_account())
    else:
        hack()

if __name__ == "__main__":
    main()


from sklearn.model_selection import train_test_split
import tensorflow as tf
import keras
import os
import numpy as np
from PIL import Image
import matplotlib.pyplot as plt
from os import listdir
from matplotlib import image
import random
from keras.utils import np_utils
from keras import callbacks

# batch_size = higher batch size could be better, but I haven't got enough gpu memory
batch_size = 32
epochs = 50

train_dir = 'chest_xray/chest_xray/train/'
val_folder = 'chest_xray/chest_xray/val/'
test_folder = 'chest_xray/chest_xray/test/'

pneumonia_str = "PNEUMONIA/"
normal_str = "NORMAL/"

train_p_dir = train_dir + pneumonia_str
train_n_dir = train_dir + normal_str

val_p_dir = val_folder + pneumonia_str
val_n_dir = val_folder + normal_str

test_p_dir = test_folder + pneumonia_str
test_n_dir = test_folder + normal_str

filenames = tf.io.gfile.glob(str('chest_xray/chest_xray/train/*/*'))
filenames.extend(tf.io.gfile.glob(str('chest_xray/chest_xray/val/*/*')))

train_filenames, val_filenames = train_test_split(filenames, test_size=0.2)

COUNT_NORMAL = len([filename for filename in train_filenames if "NORMAL" in filename])
print("Normal images count in training set: " + str(COUNT_NORMAL))

COUNT_PNEUMONIA = len([filename for filename in train_filenames if "PNEUMONIA" in filename])
print("Pneumonia images count in training set: " + str(COUNT_PNEUMONIA))

train_list_ds = tf.data.Dataset.from_tensor_slices(train_filenames)
val_list_ds = tf.data.Dataset.from_tensor_slices(val_filenames)

# Print few file names
for f in train_list_ds.take(5):
    print(f.numpy())

# Check if there is good ratio between train and val photos number
TRAIN_IMG_COUNT = tf.data.experimental.cardinality(train_list_ds).numpy()
print("Training images count: " + str(TRAIN_IMG_COUNT))
VAL_IMG_COUNT = tf.data.experimental.cardinality(val_list_ds).numpy()
print("Validating images count: " + str(VAL_IMG_COUNT))

CLASS_NAMES = np.array([str(tf.strings.split(item, os.path.sep)[-1].numpy())[2:-1]
                        for item in tf.io.gfile.glob(str("chest_xray/chest_xray/train/*"))])
print(CLASS_NAMES)

def get_label(file_path):
    # convert the path to a list of path components
    parts = tf.strings.split(file_path, os.path.sep)
    # The second to last is the class-directory
    return parts[-2] == "PNEUMONIA"

IMAGE_SIZE = [180, 180]
input_shape = (IMAGE_SIZE[0], IMAGE_SIZE[1], 3)

def decode_img(img):
  # convert the compressed string to a 3D uint8 tensor
  img = tf.image.decode_jpeg(img, channels=3)
  # Use `convert_image_dtype` to convert to floats in the [0,1] range.
  img = tf.image.convert_image_dtype(img, tf.float32)
  # resize the image to the desired size.
  return tf.image.resize(img, IMAGE_SIZE)

def process_path(file_path):
    label = get_label(file_path)
    # load the raw data from the file as a string
    img = tf.io.read_file(file_path)
    img = decode_img(img)
    return img, label

AUTOTUNE = tf.data.experimental.AUTOTUNE
train_ds = train_list_ds.map(process_path, num_parallel_calls=AUTOTUNE)
val_ds = val_list_ds.map(process_path, num_parallel_calls=AUTOTUNE)

test_list_ds = tf.data.Dataset.list_files(str('chest_xray/chest_xray/test/*/*'))
TEST_IMAGE_COUNT = tf.data.experimental.cardinality(test_list_ds).numpy()
test_ds = test_list_ds.map(process_path, num_parallel_calls=AUTOTUNE)
test_ds = test_ds.batch(batch_size)

def prepare_for_training(ds, cache=True, shuffle_buffer_size=1000):
    # This is a small dataset, only load it once, and keep it in memory.
    # use `.cache(filename)` to cache preprocessing work for datasets that don't
    # fit in memory.
    if cache:
        if isinstance(cache, str):
            ds = ds.cache(cache)
        else:
            ds = ds.cache()

    ds = ds.shuffle(buffer_size=shuffle_buffer_size)

    # Repeat forever
    ds = ds.repeat()

    ds = ds.batch(batch_size)

    # `prefetch` lets the dataset fetch batches in the background while the model
    # is training.
    ds = ds.prefetch(buffer_size=AUTOTUNE)

    return ds

train_ds = prepare_for_training(train_ds)
val_ds = prepare_for_training(val_ds)
test_ds = prepare_for_training(test_ds)


import bpy
from bpy.types import NodeSocket

from . import ProkitekturaContainerNode

class ProkitekturaDemoAdvancedAttr(ProkitekturaContainerNode, bpy.types.Node): # make ProkitekturaNode the first super() in multiple inheritance
    # Optional identifier string. If not explicitly defined, the python class name is used.
    bl_idname = "ProkitekturaDemoAdvancedAttr"
    # Label for nice name display
    bl_label = "Advanced Attr"
    # Icon identifier
    bl_icon = 'SOUND'

    # list for iteration over advanced properties
    def declareProperties(self, propList):
        super().declareProperties(propList)
        propList.extend((
            {"type":"std", "name":"countGroundLevel","check":"activateProp1", "text":"count ground level", "pythName":"groundLevel" },
            {"type":"std", "name":"specificLevel",   "check":"activateProp2", "text":"levels",             "pythName":"levels" },
            {"type":"adv", "name":"prop1",           "check":"activateProp3", "text":"str",                "pythName":"strProp" },
            {"type":"adv", "name":"prop2",           "check":"activateProp4", "text":"check",              "pythName":"boolProp" },
            {"type":"adv", "name":"prop3",           "check":"activateProp5", "text":"int",                "pythName":"intProp" },
            {"type":"adv", "name":"prop4",           "check":"activateProp6", "text":"levels",             "pythName":"enumProp" }
        ))

    # list for iteration over advanced properties
    def declareCheckedSockets(self, socketList):
        super().declareCheckedSockets(socketList)
        socketList.extend((
            {"type":"std", "class":"ProkitekturaSocketEnum", "text":"std1", "pythName":"std1"},
            {"type":"std", "class":"ProkitekturaSocketEnum", "text":"std2", "pythName":"std2"},
            {"type":"adv", "class":"ProkitekturaSocketEnum", "text":"adv1", "pythName":"adv1"},
            {"type":"adv", "class":"ProkitekturaSocketEnum", "text":"adv2", "pythName":"adv2"}
        ))

    optionsList = (
        ("all", "all levels", "All"),
        ("ground", "ground level only", "Ground level only"),
        ("allButLast", "all but last one", "All levels but the last one"),
        ("last", "last level", "The last level"),
        ("specific", "specific level", "Specific level"),
        ("even", "even levels", "Even levels"),
        ("odd", "odd levels", "Odd levels")
    )

    propList = []
    socketList = []

    # examples of mandatory  attributes
    countGroundLevel: bpy.props.BoolProperty(name = "Count Ground Level",description = "Shall we count the the ground level for the setting below",default = False)
    specificLevel: bpy.props.IntProperty(name = "Specific Level",description = "The number of the specific level",subtype = 'UNSIGNED',default = 1,min = 0)

    # examples of advanced properties
    prop1: bpy.props.StringProperty(name = "Property1", description = "Name for property1",default = 'prop1')
    prop2: bpy.props.BoolProperty(name = "Property2", description = "Name for property2",default = False)
    prop3: bpy.props.IntProperty(name = "Property3", description = "Value for property1",default = 1)
    prop4: bpy.props.EnumProperty(name = "Property4", description = "Level for property1",items = optionsList,default = "all")

    # example of activation checks for advanced properties
    activateProp1: bpy.props.BoolProperty(name = "Activate1", description = "activate1", default = True)
    activateProp2: bpy.props.BoolProperty(name = "Activate2", description = "activate2", default = True)
    activateProp3: bpy.props.BoolProperty(name = "Activate3", description = "activate3", default = False)
    activateProp4: bpy.props.BoolProperty(name = "Activate4", description = "activate4", default = False)
    activateProp5: bpy.props.BoolProperty(name = "Activate5", description = "activate5", default = False)
    activateProp6: bpy.props.BoolProperty(name = "Activate6", description = "activate6", default = False)

    def init(self, context):
        if not self.propList:
            self.declareProperties(self.propList)
        if not self.socketList:
            self.declareCheckedSockets(self.socketList)

        self.init_sockets_checked(context,self.socketList)
        super().init(context)

    def draw_buttons(self, context, layout):
        self.draw_buttons_common(context, layout)
        self.draw_buttons_checked(context, layout, self.propList)
#        self.draw_buttons_container(context, layout)


""" GLPointCloudPlotItem.py - extension of pyqtgraph for plotting pointclouds

  This file implements an extension of pyqtgraph for visualizing PointClouds.

  Last update: 04/10/2013, Tadewos Somano(tadewos85@gmail.com)

"""

from OpenGL.GL import *
from pyqtgraph.opengl.GLGraphicsItem import GLGraphicsItem

__all__ = ['GLPointCloudPlotItem']

class GLPointCloudPlotItem(GLGraphicsItem):

    """ Plotting a 3D point cloud using pyqtgraph

      Parameters:
      points     =  a numpy array with shape [n,3] with the 3D-point coordinates
      color      =  a solid floating point (r,g,b,a), a is the alpha component
      colors     =  an array of (r,g,b,a) colors with the same size of points
      point_size =  the dimension of each point in the visualization (in pixels)

    """

    def __init__(self, **kwds):

        GLGraphicsItem.__init__(self)
        glopts = kwds.pop('glOptions', 'opaque')
        self.setGLOptions(glopts)
        self.points = None
        self.colors = None
        self.width = 1.
        self.color = (1.0,1.0,1.0,1.0)
        self.setData(**kwds)

    def setData(self, **kwds):

        """ Update the data displayed by this item """

        args = ['points', 'color', 'colors', 'point_size' ]
        for k in kwds.keys():
            if k not in args:
                raise Exception('Invalid keyword argument: %s (allowed: %s)'%(k, str(args)))

        for arg in args:
            if arg in kwds:
                setattr(self, arg, kwds[arg])

        self.update()

    def initializeGL(self):
        pass

    def paint(self):

        """ Paint the pointcloud """

        if self.points is None: return

        self.setupGLState()

        try:

            # Set the color state
            if self.colors is None:
                glColor4f(*self.color)
            else:
                glEnableClientState(GL_COLOR_ARRAY)
                glColorPointerf( self.colors )

            glPointSize(self.point_size)

            # Draw an array of points
            glEnableClientState(GL_VERTEX_ARRAY)
            glVertexPointerf(self.points)
            glDrawArrays(GL_POINTS, 0, self.points.size/self.points.shape[-1])

        finally:

            glDisableClientState(GL_VERTEX_ARRAY)

            if not self.colors is None:
                glDisableClientState(GL_COLOR_ARRAY)


# Helper functions for stochastic raytracer

import numpy as np
import pickle
import matplotlib.pyplot as plt
from scipy import interpolate
from sklearn import preprocessing

# Create a linear interpolant in each of the x, y, z directions
def create_interpolant(xyz, g):
    fx = interpolate.RegularGridInterpolator(xyz, g[0])
    fy = interpolate.RegularGridInterpolator(xyz, g[1])
    fz = interpolate.RegularGridInterpolator(xyz, g[2])
    return (fx, fy, fz)

#
def get_sdf_components(dict_name, xyz, space_subdivs):
    with open(dict_name, 'rb') as dictionary_file:
        r = pickle.load(dictionary_file)

    # Compute interpolant of the sdf
    phi = interpolate.RegularGridInterpolator(xyz, r)

    # Compute gradient (2/space_subdivs corresponds to the step size since r is space_subdivs subdivisions over an interval of 2)
    g = np.gradient(r, 2/space_subdivs)

    # Interpolant of gradient in each of x,y,z directions
    fx, fy, fz  = create_interpolant(xyz, g)

    return (phi, fx, fy, fz)

# Closest point operator
def cp(points, phi, fx, fy, fz):
    """
    points - a point in R^3 as a 3 ndarray, or multiple points as a 3xN ndarray
    phi    - interpolant of the sdf given by the array
    fu     - interpolant of gradient in the direction of u for u in [x,y,z]

    Returns the closest point on the level set 0
    """
    phi_points  = phi(points).reshape(len(points), 1)       # reshaping to (N, 1) for broadcasting with points_grad
    px, py, pz  = fx(points), fy(points), fz(points)        # the gradient of the generated points in each direction
    points_grad = np.transpose(np.array([px, py, pz]))
    closest     = points - phi_points * points_grad
    return closest

# Find the points traced on the plane when tracing back to camera
def get_points_on_plane(cam, closest, k, n, D):
    """
    See report for justification as to why this works!

    cam     - location of camera
    closest - array of the closest points
    k       - vector normal to plane
    n       - normalized vector normal to plane
    D       - scalar parameter of plane
    """
    b = preprocessing.normalize(cam - closest)    # Normalized vectors in direction of closest points to camera
    cos = b @ (-n)                                # Cosine of the angle between n (in other direction) and b, simply the dot product since they are unit vectors
    d_plane = (closest @ k + D)/np.linalg.norm(k) # Distance from point to plane that is the screen (using standard point to plane formula)
    scale   = (d_plane/cos).reshape(-1,1)         # Scale to find the vector from point to plane via vector to camera
    points_plane = closest + scale * b            # Points on the
    return points_plane, scale

# Rotate the screen such that the camera vector is along x, then remove the x dimension
def get_rotation_matrix(k, cam):
    """
    Note: This only works if the plane passes through the z-axis. It can be generalized be changing the value of u.

    k            - vector normal to plane
    cam          - position of camera

    Returns A_mat, the inverse of T_mat, and T_mat, which brings the camera to the x-axis.
    """
    d_cam = np.linalg.norm(cam)           # Distance from origin to camera
    D_alt = - k @ cam                     # Alternate D that create the plane Ax + By + Cz + D_alt = 0 and cam lies on the plane
    u     = np.array([0, 0, -D_alt/k[2]]) # A point on this new plane (see notes above)
    v     = u - cam                       # A vector perpendicular to cam
    beta  = v*(d_cam/np.linalg.norm(v))   # Renormalize to have magnitude of cam
    gamma = np.cross(cam, beta)/d_cam     # Another vector parallel to both cam and beta with magnitude of cam

    A_mat    = np.transpose(np.array([cam, beta, gamma]))/d_cam # The matrix A which transform the standard coordinates with length d_cam to (cam, beta, gamma)
    T_mat    = np.linalg.inv(A_mat)                             # The transform T as a matrix
    return (A_mat, T_mat)

# Perform the rotation
def rotate_and_kill_x(T_mat, points_plane):
    """
    T_mat        - the transformation (rotation) matrix
    points_plane - the points on the plane
    """
    rotated  = np.transpose(T_mat @ np.transpose(points_plane)) # Apply rotation T to align screen to x-axis
    scrn     = rotated[:,1:]                                    # Kill off x dimension
    return scrn

# Get positions of unfilled pixels on the screen
def get_not_filled_positions(not_filled, n_x, n_y):
    count_not_filled     = np.sum(not_filled)
    not_filled_pos       = np.zeros((count_not_filled, 2))  # list of unfilled pixels by position

    not_filled_counter   = 0                                # counter for not filled
    for it_x in range(n_x):
        for it_y in range(n_y):
            if not_filled[it_x][it_y] == 1:
                not_filled_pos[not_filled_counter] = np.array([it_x, it_y])
                not_filled_counter += 1
    return not_filled_pos

# Get the direction in physical space of vectors from camera to missing pixels (this should be working)
def get_directional_vectors(not_filled_pos, n_x, n_y, a_x, a_y, b_x, b_y, A_mat, T_mat, cam):
    """
    not_filled - list of unfilled pixels
    All other parameters are standard as per its name

    Returns a list of unit vectors in physical space, which, when originating from cam, would pass through an unfilled pixel
    """
    not_filled_counter   = not_filled_pos.shape[0]            # number of not filled pixels

    cam_in_flat          = T_mat @ cam                        # location of camera in the rotated space
    not_filled_x_pos     = not_filled_pos[:, 0]               # x-coordinate in the screen (this corresponds to y-space)
    not_filled_y_pos     = not_filled_pos[:, 1]               # y-coordinate in the screen (this corresponds to z-space)

    # (approximate) real coordinates of pixels in rotated space
    unshifted_x          = not_filled_x_pos*(b_x - a_x)/n_x + a_x + (b_x - a_x)/(2*n_x) # this last term is to re-center
    unshifted_y          = not_filled_y_pos*(b_y - a_y)/n_y + a_y + (b_y - a_y)/(2*n_y)
    unshifted_coords     = np.array([np.zeros(not_filled_counter), unshifted_x, unshifted_y])

    cam_to_pixels_in_rot = unshifted_coords - np.repeat(cam_in_flat.reshape(3,1), not_filled_counter, axis=1) # vectors originating from camera to pixels
    ctp_in_rot_normal    = cam_to_pixels_in_rot/np.linalg.norm(cam_to_pixels_in_rot, axis=0)                  # normalize
    ctp_in_space         = A_mat @ ctp_in_rot_normal                                                          # return to physical space - these are the directions for sphere tracing
    return ctp_in_space

# Perform sphere tracing given a vector
def perform_sphere_tracing(cam, direction, phi, dist_threshold = 10e-5, t_max = 5):
    t = 0                                   # distance along the ray
    try:
        while(t < t_max):
            radius = phi(direction*t + cam)  # radius at current point
            if radius < dist_threshold:
                break
            t += radius
        if t < t_max:
            return t
        else:
            return np.inf
    except:
        return np.inf # this will happen if the evaluation of the interpolant phi is outside the interpolation range


__author__ = 'Victor Olaya'
__date__ = 'August 2012'
__copyright__ = '(C) 2012, Victor Olaya'

# This will get replaced with a git SHA1 when you do a git archive

__revision__ = '$Format:%H$'

import os
import codecs
import datetime
from processing.tools.system import userFolder
from processing.core.ProcessingConfig import ProcessingConfig
from qgis.core import QgsMessageLog
from qgis.PyQt.QtCore import QCoreApplication

class ProcessingLog:

    LOG_ERROR = 'ERROR'
    LOG_INFO = 'INFO'
    LOG_WARNING = 'WARNING'
    LOG_ALGORITHM = 'ALGORITHM'
    DATE_FORMAT = "%Y-%m-%d %H:%M:%S"
    recentAlgs = []

    @staticmethod
    def logFilename():
        logFilename = userFolder() + os.sep + 'processing.log'
        if not os.path.isfile(logFilename):
            logfile = codecs.open(logFilename, 'w', encoding='utf-8')
            logfile.write('Started logging at ' +
                          datetime.datetime.now().strftime(ProcessingLog.DATE_FORMAT) + '\n')
            logfile.close()

        return logFilename

    @staticmethod
    def addToLog(msgtype, msg):
        try:
            # It seems that this fails sometimes depending on the msg
            # added. To avoid it stopping the normal functioning of the
            # algorithm, we catch all errors, assuming that is better
            # to miss some log info than breaking the algorithm.
            if msgtype == ProcessingLog.LOG_ALGORITHM:
                line = msgtype + '|' + datetime.datetime.now().strftime(
                    ProcessingLog.DATE_FORMAT) + '|' \
                    + msg + '\n'
                logfile = codecs.open(ProcessingLog.logFilename(), 'a',
                                      encoding='utf-8')
                logfile.write(line)
                logfile.close()
                algname = msg[len('Processing.runalg("'):]
                algname = algname[:algname.index('"')]
                if algname not in ProcessingLog.recentAlgs:
                    ProcessingLog.recentAlgs.append(algname)
                    recentAlgsString = ';'.join(ProcessingLog.recentAlgs[-6:])
                    ProcessingConfig.setSettingValue(
                        ProcessingConfig.RECENT_ALGORITHMS,
                        recentAlgsString)
            else:
                if isinstance(msg, list):
                    msg = '\n'.join([m for m in msg])
                msgtypes = {ProcessingLog.LOG_ERROR: QgsMessageLog.CRITICAL,
                            ProcessingLog.LOG_INFO: QgsMessageLog.INFO,
                            ProcessingLog.LOG_WARNING: QgsMessageLog.WARNING, }
                QgsMessageLog.logMessage(msg, ProcessingLog.tr("Processing"), msgtypes[msgtype])
        except:
            pass

    @staticmethod
    def getLogEntries():
        entries = {}
        errors = []
        algorithms = []
        warnings = []
        info = []

        with open(ProcessingLog.logFilename()) as f:
            lines = f.readlines()
        for line in lines:
            line = line.strip('\n').strip()
            tokens = line.split('|')
            text = ''
            for i in range(2, len(tokens)):
                text += tokens[i] + '|'
            if line.startswith(ProcessingLog.LOG_ERROR):
                errors.append(LogEntry(tokens[1], text))
            elif line.startswith(ProcessingLog.LOG_ALGORITHM):
                algorithms.append(LogEntry(tokens[1], tokens[2]))
            elif line.startswith(ProcessingLog.LOG_WARNING):
                warnings.append(LogEntry(tokens[1], text))
            elif line.startswith(ProcessingLog.LOG_INFO):
                info.append(LogEntry(tokens[1], text))

        entries[ProcessingLog.LOG_ALGORITHM] = algorithms
        return entries

    @staticmethod
    def getRecentAlgorithms():
        recentAlgsSetting = ProcessingConfig.getSetting(
            ProcessingConfig.RECENT_ALGORITHMS)
        try:
            ProcessingLog.recentAlgs = recentAlgsSetting.split(';')
        except:
            pass
        return ProcessingLog.recentAlgs

    @staticmethod
    def clearLog():
        os.unlink(ProcessingLog.logFilename())

    @staticmethod
    def saveLog(fileName):
        entries = ProcessingLog.getLogEntries()
        with codecs.open(fileName, 'w', encoding='utf-8') as f:
            for k, v in entries.iteritems():
                for entry in v:
                    f.write('%s|%s|%s\n' % (k, entry.date, entry.text))

    @staticmethod
    def tr(string, context=''):
        if context == '':
            context = 'ProcessingLog'
        return QCoreApplication.translate(context, string)

class LogEntry:

    def __init__(self, date, text):
        self.date = date
        self.text = text


import functools
words=input().split()
def validate(word):
    letters=[]
    for i in word:
        if i.upper() not in letters:
            letters.append(i.upper())
    if len(letters)>3:
        return True
    return False
if __name__=='__main__':
    answer1=list(filter(validate, words))
    print(list(map(lambda a: a[0].swapcase()+a[1:], answer1)))
    answer2 = list(filter(lambda x: 'foo' in x, words))
    print(len(functools.reduce(lambda a,b: a+b, answer2)))


from datetime import datetime

from sqlalchemy import Column
from sqlalchemy.sql.sqltypes import Integer, Text, Date, Boolean

from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()

class Follower(Base):
    __tablename__ = 'follower'

    id = Column(Integer, primary_key=True)
    name = Column(Text)
    screen_name = Column(Text)
    twitter_id = Column(Integer)
    is_following = Column(Boolean)
    last_following = Column(Date)

    def __repr__(self):
        return "<Follower %s #%s>" % \
               (self.name, self.twitter_id)


#!/usr/bin/env python2

# [Ordered Dictionary for Py2.4 « Python recipes « ActiveState Code]
# (http://code.activestate.com/recipes/576693/)

from collections import OrderedDict

od = OrderedDict()

od["a"] = 1
od["b"] = 2
od["c"] = 4
od["d"] = 5
del od["a"]
od["a"] = 3

for k, v in od.iteritems():
    print("{},{}".format(k,v))
print("")

# print:
# b,2
# c,4
# d,5
# a,3
# OrderedDict is FIFO

for k in reversed(od) :         # reversed is not destructive
    print("{},{}".format(k,od[k]))
print("")

# a,3
# d,5
# c,4
# b,2

for k, v in od.iteritems():
    print("{},{}".format(k,v))
print("")

# b,2
# c,4
# d,5
# a,3


"""
Yo que se ya
"""

import argparse
import mido
import logging
from timeit import default_timer as timer

from video import Video

# from moviepy.editor import *

DEBUG = True

def print_d(msg):
    if DEBUG:
        print(msg)

def maxSymNotes(notes):
    curr = max = 0
    for note in notes:
        if note[2] == 0:
            curr+=1
            if curr > max:
                max = curr
        else:
            curr = 0
    return max

def keep_only_highest(notes):

    curr = 0
    highest = -1
    highest_t = 0
    h_v = 0
    new = []
    for (note, vel, t) in notes:
        if vel == 0: #stop note
            new += [(note, vel, t)]
            # v.addNote(note, vel, t)
        if t == 0:
            highest = max(highest, note)
            highest_t = t
            h_v = vel
        else:
            curr += t
            # print("now at: ", curr)
            if highest != -1:
                # print("adding:", highest)
                new += [(highest, h_v, highest_t)]
                highest = -1
                highest_t = 0
                h_v = 0
    return new

def misirlou(low = 52, c = 4, duration = 0.05, vel=10):
    """ Returns a sequence like misirlou kinda """
    notes = ([low+0]*c*3 + [low+1]*c + [low+4]*c*2 + [low+5]*c*2 +
            [low+7]*c*3 + [low+8]*c + [low+11]*c*2 + [low+8]*c*2 +
            [low+7]*c*8)
    notes = (notes*2 +
            [low+8]*c*2 + [low+7]*c + [low+8]*c + [low+7]*c*2 + [low+5]*c*2 +
            [low+7]*c*2 + [low+5]*c + [low+7]*c + [low+5]*c*2 + [low+4]*c + [low+1]*c +
            [low+4]*c*8 +
            [low+7]*c*2 + [low+5]*c + [low+7]*c + [low+5]*c*2 + [low+4]*c*2 +
            [low+5]*c*2 + [low+4]*c + [low+5]*c + [low+4]*c*2 + [low+1]*c*2 +
            [low+0]*c*8)
    msgs = []
    print(notes)
    # notes = [note for n in notes  for note in n]
    for note in notes:
        msgs += [(note, vel, 0)] # start
        msgs += [(note, 0, duration)]   # stop duration secs later
    return msgs

def chromatic(lowest=52, highest=76, duration = 0.5, vel=10):
    """ chromatic scale from from lowest to highest """
    notes = [n for n in range(lowest, highest+1)]
    msgs = []
    # print(notes)
    # notes = [note for n in notes  for note in n]
    for note in notes:
        msgs += [(note, vel, 0)] # start
        msgs += [(note, 0, duration)]   # stop duration secs later
    return msgs

def octaves(lowest=52, highest=76, duration = 0.5, vel=10):
    """ each octave of each note, lowest to highest """
    notes = []
    for n in range(12):
        note = lowest + n
        while note <= highest:
            notes += [note]
            note +=12
    msgs = []
    # print(notes)
    # notes = [note for n in notes  for note in n]
    for note in notes:
        msgs += [(note, vel, 0)] # start
        msgs += [(note, 0, duration)]   # stop duration secs later
    return msgs

def merge_parse(mid, ignore = [6,7,8, 10, 11, 12]):
    """
    Merges all tracks then returns the notes as [(notecode, vel, t)].
    Tempo changes are translated to (-1,tempo,t), unknown messages to (-2,0,t)
    """
    tracks = []

    for i, track in enumerate(mid.tracks):
        print_d('Track {}: {}'.format(i, track.name))
        if i not in ignore:
            tracks += [track]
        else: # fake track only to keep times
            print('(ignoring this one)')
            newtrack = mido.MidiTrack()
            for msg in track:
                newtrack.append(mido.Message('program_change', program=0, time=msg.time))
            tracks += [newtrack]
    track = mido.merge_tracks(tracks)

    notes = []

    bpm = 120 # default
    tempo = 500000

    total_ticks = 0
    for msg in track:
        total_ticks += msg.time
        if msg.is_meta:
            # print(msg)
            if msg.type == 'set_tempo':
                print('tempo msg:',msg)
                notes += [(-1,  msg.tempo * args.slow, msg.time)]
                if tempo == 500000:
                    tempo = msg.tempo * args.slow # only the first one
            else:
                # print('unknown meta msg:', msg)
                notes += [(-2, 0, msg.time)] # only add time
        elif msg.type == 'note_off': # convert to note_on with vel = 0
            notes += [(msg.note, 0, msg.time)]#mido.tick2second(msg.time, mid.ticks_per_beat, tempo))]
        elif msg.type == 'note_on':
            notes += [(msg.note, msg.velocity, msg.time)]# mido.tick2second(msg.time, mid.ticks_per_beat, tempo))]
        else:
            # print('unknown msg:', msg)
            notes += [(-2, 0, msg.time)]

    return notes, tempo, total_ticks

def print_notes(notes):
    all_notes = {n[0] for n in notes if n[0]>=0} # set, remove repetitions
    for note in sorted(all_notes): # sorted
        print(note)

def parseMidi(mid, args):
    """ returns the notes as [(notecode, vel, t)] """
    notes = []

    bpm = 120 # default
    tempo = 500000

    total_ticks = 0
    for i, track in enumerate(mid.tracks):
        print_d('Track {}: {}'.format(i, track.name))

        for msg in track:
            total_ticks += msg.time
            if i != args.track:
                break # TODO: this is bad!!
            if msg.is_meta:
                # print(msg)
                if msg.type == 'set_tempo':
                    print('tempo msg:',msg)
                    notes += [(-1,  msg.tempo * args.slow, msg.time)]
                    if tempo == 500000:
                        tempo = msg.tempo * args.slow # only the first one
                    # tempos += 1
                    # tempo = args.slow * msg.tempo
                    # bpm = mido.tempo2bpm(tempo)
                    # print("bpm: ", bpm)
                else:
                    # print('unknown meta msg:', msg)
                    notes += [(-2, 0, msg.time)]

            elif msg.type == 'note_off':
                notes += [(msg.note, 0, msg.time)]#mido.tick2second(msg.time, mid.ticks_per_beat, tempo))]
            elif msg.type == 'note_on':
                notes += [(msg.note, msg.velocity, msg.time)]# mido.tick2second(msg.time, mid.ticks_per_beat, tempo))]
            else:
                # print('unknown msg:', msg)
                notes += [(-2, 0, msg.time)]
                # video.addNote(msg.note, msg.velocity, mido.tick2second(msg.time))
                # print(msg, msg.type)
                # print("note: ", msg.note, " vel: ", msg.velocity, "t: ", msg.time)
    # print('tempo changes:', tempos)
    return notes, tempo, total_ticks

def main(args):
    program_times = {}

    do_chromatic = args.lowest_note != -1
    # ---------------------------------------------------------------------
    # Parse the midi file:
    start = timer()
    mid = mido.MidiFile(args.midi_file)
    ignore = []
    if args.track != -1:
        # print()
        ignore = [i for i in range(1,50) if i != args.track]
    print("ignore:",ignore)
    notes, tempo, total_ticks = merge_parse(mid, ignore) # else parseMidi(mid, args)
    end = timer()

    if args.print_track:
        print_notes(notes)
        exit(0)

    program_times['midi'] = end - start
    print("----------------------------\nMidi parsed in:", program_times['midi'], "s")

    #exit(0)

    # ---------------------------------------------------------------------
    # Initialize the video:
    start = timer()
    # rows = args.voices
    v = Video(args.clip, args.timestamps, rows=args.voices,cols=args.voices,text=do_chromatic,quality=args.quality,do_fade=True,only_audio=False)

    end = timer()
    program_times['initialize'] = end - start
    print("----------------------------\nVideo initialized in:", program_times['initialize'], "s")

    print(len(notes), "notes")

    #################### misirlou test:
    #notes = misirlou()

    #################### Chromatic test:
    # min 50
    if do_chromatic:
        notes = chromatic(lowest = args.lowest_note, highest = 76, duration = 1)
        # notes = chromatic(lowest = args.lowest_note, highest = args.lowest_note+12, duration = 1)

    #################### Octaves test:
    # min 50
    #notes = octaves(lowest = 50, highest = 96, duration = 0.5)

    # print(notes)
    # print('120 ticks = ', mido.tick2second(120, mid.ticks_per_beat, tempo))

    # ---------------------------------------------------------------------
    # Add notes to video (generate clips)
    start = timer()
    curr = 0 # ticks
    curr_s = 0 # secs
    full = mid.length

    msg_freq = 0.01
    next_msg = msg_freq

    desired_length = args.max_duration # sec
    for (note, vel, ticks) in notes:
        curr += ticks
        t = mido.tick2second(ticks, mid.ticks_per_beat, tempo) if not do_chromatic else ticks
        curr_s += t
        # just some feedback:
        # curr_s = mido.tick2second(curr, mid.ticks_per_beat, tempo)
        if curr_s >= next_msg*min(full, desired_length): # percentage advanced
            print("now at:", int(100*next_msg), "% processed: ", curr_s, "s")
            next_msg += msg_freq
        if curr_s >= desired_length:
            break
        if note == -1: # tempo change!!
            tempo = vel
            v.add_time(t)
        elif note == -2: # unknown msg, only add time
            v.add_time(t)
        elif curr_s>=args.initial_t: # normal notes
            v.addNote(note, vel, t) # this is the important stuff

    # tick_converted= mido.second2tick(full, mid.ticks_per_beat, tempo)
    # if tick_converted != full:
    #     print('1??', tick_converted,total_ticks)
    if curr != total_ticks:
        print('Warning: Wrong ticks!!', curr, '!=', total_ticks)
    if v.current_time != full:
        print('Warning: Wrong time!! (video != expected):', v.current_time, '!=', full)
        # exit(1)
    if curr_s != full:
        print('Warning: Wrong time!! (current != expected):', curr_s, '!=', full)
        # exit(1)

    end = timer()

    program_times['clips'] = end - start
    print("----------------------------\nClips generated in:", program_times['clips'], "s")
    print("Compiling... ", end="")

    # ---------------------------------------------------------------------
    # Merge clips and save:
    start = timer()
    v.compile(args.output)
    end = timer()
    program_times['join'] = end - start
    print("----------------------------\nVideo joined in:", program_times['join'], "s")
    total_t = sum(program_times.values())
    print('----------------------------\nTotal:', total_t, '\nTime in each step:')
    for name, t in program_times.items():
        print(name, '->', 100 * t / total_t, "%")

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument('-m', '--midi_file', help='Midi file', type=str, default="bumble_bee.mid")
    # TODO: permitir usar todas las tracks!!
    parser.add_argument('-tr', '--track', help='Number of the track from the midi to generate (default: all)', type=int, default=-1)
    parser.add_argument('-c', '--clip', help='original video', type=str, default="original/escala.mp4")

    # parser.add_argument('-i2', '--input2', help='Input video file 2', type=str, default="")
    parser.add_argument('-t', '--timestamps', help='timestamps for each note in the video', type=str, default="original/times-escala.csv")
    parser.add_argument('-o', '--output', help='output file', type=str, default="out.mp4")

    parser.add_argument('-v', '--voices', help='output file', type=int, default=1)

    parser.add_argument('-s', '--slow', help='slow mo (-s 2 makes it twice as slow)', type=float, default=1)
    parser.add_argument('-ini', '--initial_t', help='initial time (s) in midi to start video', type=float, default=0)
    parser.add_argument('-max', '--max_duration', help='max output duration', type=float, default=100000)

    parser.add_argument('-q', '--quality', help='reduce quality (e.g. 0.5)', type=float, default=1)

    parser.add_argument('-low', '--lowest_note', help='make a chromatic scale starting at this note', type=int, default=-1)

    parser.add_argument('-pt', '--print_track', help='Print the notes from the track', dest='print_track', action='store_true')
    parser.set_defaults(print_track=False)

    args = parser.parse_args()
    main(args)


import os
from os import getenv
from dotenv import load_dotenv

if os.path.exists("local.env"):
    load_dotenv("local.env")

API_ID = int(getenv("API_ID", "6435225")) #optional
API_HASH = getenv("API_HASH", "") #optional

SUDO_USERS = list(map(int, getenv("SUDO_USERS", "").split()))
OWNER_ID = int(getenv("OWNER_ID"))
MONGO_URL = getenv("MONGO_URL")
BOT_TOKEN = getenv("BOT_TOKEN", "")
ALIVE_PIC = getenv("ALIVE_PIC", 'https://telegra.ph/file/3c52a01057865f7511168.jpg')
ALIVE_TEXT = getenv("ALIVE_TEXT")
PM_LOGGER = getenv("PM_LOGGER")
LOG_GROUP = getenv("LOG_GROUP")
GIT_TOKEN = getenv("GIT_TOKEN") #personal access token
REPO_URL = getenv("REPO_URL", "https://github.com/ITZ-ZAID/ZAID-USERBOT")
BRANCH = getenv("BRANCH", "master") #don't change

STRING_SESSION1 = getenv("STRING_SESSION1", "")
STRING_SESSION2 = getenv("STRING_SESSION2", "")
STRING_SESSION3 = getenv("STRING_SESSION3", "")
STRING_SESSION4 = getenv("STRING_SESSION4", "")
STRING_SESSION5 = getenv("STRING_SESSION5", "")
STRING_SESSION6 = getenv("STRING_SESSION6", "")
STRING_SESSION7 = getenv("STRING_SESSION7", "")
STRING_SESSION8 = getenv("STRING_SESSION8", "")
STRING_SESSION9 = getenv("STRING_SESSION9", "")
STRING_SESSION10 = getenv("STRING_SESSION10", "")


# -*- coding: utf-8 -*-
from scrapy import Spider, Request, FormRequest
from MobaiSpider.items import MobaispiderItem
import numpy as np
import json
import time

class MobaiSpider(Spider):
    name = 'mobai'
    # allowed_domains = ['mobike.com']
    # start_urls = ['http://mobike.com/']
    url = "https://mwx.mobike.com/mobike-api/rent/nearbyBikesInfo.do"

    headers = {
        'charset': "utf-8",
        'platform': "4",
        "referer": "https://servicewechat.com/wx80f809371ae33eda/144/page-frame.html",
        'content-type': "application/x-www-form-urlencoded",
        'user-agent': "MicroMessenger/6.5.4.1000 NetType/WIFI Language/zh_CN",
        'host': "mwx.mobike.com",
        'connection': "Keep-Alive",
        'accept-encoding': "gzip",
        'cache-control': "no-cache",
    }

    def start_requests(self):
        left = 32.2418440767
        top = 118.5623931885
        right = 31.8892185988
        bottom = 119.0059661865

        # 32.2418440767, 118.5623931885 左上
        # 31.8892185988, 119.0059661865 右下

        offset = 0.002

        print("Start")
        self.total = 0
        lat_range = np.arange(left, right, -offset)
        for lat in lat_range:
            lon_range = np.arange(top, bottom, offset)
            for lon in lon_range:
                self.total += 1
                # self.get_nearby_bikes(lat, lon)
                item = MobaispiderItem()
                item['currentX'] = lat
                item['currentY'] = lon
                item['timestamp'] = time.time()
                yield FormRequest(
                    self.url,
                    headers=self.headers,
                    formdata = {
                        'accuracy': '30',
                        'citycode': '025',
                        'errMsg': 'getLocation:ok',
                        'horizontalAccuracy': '30',
                        'latitude': str(lat),
                        'longitude': str(lon),
                        'speed': '-1',
                        'verticalAccuracy': '0',
                        'wxcode': '021Ay5DV0LUt2V1bRUDV0E8ICV0Ay5DN'
                    },
                    callback=self.parse,
                    meta={'item': item}
                )

    def parse(self, response):
        print(response.text)
        data = json.loads(response.text)
        bikes = data['object']
        if bikes:
            for bike in bikes:
                item = response.meta['item']
                item['bikeIds'] = bike['bikeIds']
                item['bikeType'] = bike['biketype']
                item['distX'] = bike['distX']
                item['distY'] = bike['distY']
                item['distId'] = bike['distId']
                item['distance'] = bike['distance']
                item['boundary'] = bike['boundary']
                yield item


""" Preprocess the ISBI data set.
"""

__author__ = "Mike Pekala"
__copyright__ = "Copyright 2015, JHU/APL"
__license__ = "Apache 2.0"

import argparse, os.path
import numpy as np
from scipy.stats.mstats import mquantiles
import scipy.io

import emlib

def get_args():
    """Command line parameters for the 'deploy' procedure.

    You will probably want to override the train/valid/test split
    to better suit your problem of interest...
    """
    parser = argparse.ArgumentParser()

    parser.add_argument('-X', dest='dataFileName', type=str, required=True,
		    help='EM data file')

    parser.add_argument('-Y', dest='labelsFileName', type=str, required=True,
		    help='Ground truth labels for X')

    parser.add_argument('--train-slices', dest='trainSlices',
		    type=str, default='range(10)',
		    help='which slices to use for training')

    parser.add_argument('--valid-valid', dest='validSlices',
		    type=str, default='range(10,20)',
		    help='which slices to use for validation')

    parser.add_argument('--test-valid', dest='testSlices',
		    type=str, default='range(20,30)',
		    help='which slices to use for test')

    parser.add_argument('--brightness-quantile', dest='brightQuant',
		    type=float, default=0.97,
		    help='top quantile for non-membrane pixels.')

    parser.add_argument('--out-dir', dest='outDir',
		    type=str, default='./',
		    help='output directory')

    args = parser.parse_args()
    assert(args.brightQuant <= 1.0)
    assert(args.brightQuant > 0)

    # map strings to python objects (XXX: a cleaner way than eval)
    args.trainSlices = eval(args.trainSlices)
    args.validSlices = eval(args.validSlices)
    args.testSlices = eval(args.testSlices)

    return args

if __name__ == "__main__":
    args = get_args();

    #outDir = os.path.split(args.dataFileName)[0]
    if not os.path.isdir(args.outDir):
        os.mkdir(args.outDir)

    X = emlib.load_cube(args.dataFileName, np.uint8)
    Y = emlib.load_cube(args.labelsFileName, np.uint8)

    # remap Y labels from ISBI convention to membrane-vs-non-membrane
    Y[Y==0] = 1;      #  membrane
    Y[Y==255] = 0;    #  non-membrane

    # change type of Y so can use -1 as a value.
    Y = Y.astype(np.int8)

    Xtrain = X[args.trainSlices,:,:]; Ytrain = Y[args.trainSlices,:,:]
    Xvalid = X[args.validSlices,:,:]; Yvalid = Y[args.validSlices,:,:]
    Xtest = X[args.testSlices,:,:];   Ytest = Y[args.testSlices,:,:]

    # brightness thresholding
    thresh = mquantiles(np.concatenate((Xtrain[Ytrain==1], Xvalid[Yvalid==1])), args.brightQuant)
    pctOmitted = 100.0*np.sum(X > thresh) / np.prod(np.size(X))
    print('[preprocess]: percent of pixels omitted by brightness filter: %0.2f' % pctOmitted)

    Ytrain[Xtrain > thresh] = -1
    Yvalid[Xvalid > thresh] = -1
    Ytest[Xtest > thresh] = -1

    # EM data preprocessing
    # For now, do nothing.

    # save results
    np.save(os.path.join(outDir, 'Xtrain.npy'), Xtrain)
    np.save(os.path.join(outDir, 'Ytrain.npy'), Ytrain)
    np.save(os.path.join(outDir, 'Xvalid.npy'), Xvalid)
    np.save(os.path.join(outDir, 'Yvalid.npy'), Yvalid)
    np.save(os.path.join(outDir, 'Xtest.npy'), Xtest)
    np.save(os.path.join(outDir, 'Ytest.npy'), Ytest)

    print('[preprocess]: done!')


import pickle
import struct
from pathlib import Path

from interact import interact as io
from utils import Path_utils

import samplelib.SampleHost
from samplelib import Sample

packed_faceset_filename = 'faceset.pak'

class PackedFaceset():
    VERSION = 1

    @staticmethod
    def pack(samples_path):
        samples_dat_path = samples_path / packed_faceset_filename

        if samples_dat_path.exists():
            io.log_info(f"{samples_dat_path} : file already exists !")
            io.input_bool("Press enter to continue and overwrite.", False)

        of = open(samples_dat_path, "wb")

        image_paths = Path_utils.get_image_paths(samples_path)

        samples = samplelib.SampleHost.load_face_samples(image_paths)
        samples_len = len(samples)

        samples_configs = []
        for sample in samples:
            sample.filename = str(Path(sample.filename).relative_to(samples_path))
            samples_configs.append ( sample.get_config() )
        samples_bytes = pickle.dumps(samples_configs, 4)

        of.write ( struct.pack ("Q", PackedFaceset.VERSION ) )
        of.write ( struct.pack ("Q", len(samples_bytes) ) )
        of.write ( samples_bytes )

        sample_data_table_offset = of.tell()
        of.write ( bytes( 8*(samples_len+1) ) ) #sample data offset table

        data_start_offset = of.tell()
        offsets = []

        for sample in io.progress_bar_generator(samples, "Packing"):
            try:
                with open( samples_path / sample.filename, "rb") as f:
                    b = f.read()

                offsets.append ( of.tell() - data_start_offset )
                of.write(b)
            except:
                raise Exception(f"error while processing sample {sample.filename}")

        offsets.append ( of.tell() )

        of.seek(sample_data_table_offset, 0)
        for offset in offsets:
            of.write ( struct.pack("Q", offset) )
        of.seek(0,2)
        of.close()

        for filename in io.progress_bar_generator(image_paths,"Deleting"):
            Path(filename).unlink()

    @staticmethod
    def unpack(samples_path):
        samples_dat_path = samples_path / packed_faceset_filename
        if not samples_dat_path.exists():
            io.log_info(f"{samples_dat_path} : file not found.")
            return

        samples = PackedFaceset.load(samples_path)

        for sample in io.progress_bar_generator(samples, "Unpacking"):
            with open(samples_path / sample.filename, "wb") as f:
                f.write( sample.read_raw_file() )

        samples_dat_path.unlink()

    @staticmethod
    def load(samples_path):
        samples_dat_path = samples_path / packed_faceset_filename
        if not samples_dat_path.exists():
            return None

        f = open(samples_dat_path, "rb")
        version, = struct.unpack("Q", f.read(8) )
        if version != PackedFaceset.VERSION:
            raise NotImplementedError

        sizeof_samples_bytes, = struct.unpack("Q", f.read(8) )

        samples_configs = pickle.loads ( f.read(sizeof_samples_bytes) )
        samples = []
        for sample_config in samples_configs:
            samples.append ( Sample (**sample_config) )

        offsets = [ struct.unpack("Q", f.read(8) )[0] for _ in range(len(samples)+1) ]
        data_start_offset = f.tell()
        f.close()

        for i, sample in enumerate(samples):
            start_offset, end_offset = offsets[i], offsets[i+1]
            sample.set_filename_offset_size( str(samples_dat_path), data_start_offset+start_offset, end_offset-start_offset )

        return samples


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

def coin():
    return random.randrange(0,2)

def coins20():
    X = []
    for i in range(0,20):
        X.append(coin())
    return X

def mili():
    E = []
    for i in range(0,1000000):
        E.append(coins20())
    return E

mil_reps = mili()
np.shape(mil_reps)
def frqs(bs):
    data = []
    a = 0.5
    while a < 1.05:
        count = 0
        for i in range(0,1000000):
            freq = 0.05*sum(bs[i])
            if freq >= a:
                count = count+1
        data.append(count)
        a = a+0.05
    return data

emp_freqs = frqs(mil_reps)
emp_freqs
aaaa = [a*0.05 for a in range(10,21)]

plt.figure(1)
plt.plot(aaaa, emp_freqs, label="Empirical freq. of observations", color="red", linestyle=':')
plt.title(" 20 coin flips plot of frequency", color="blue")
plt.xlabel("Alpha", color="blue")
plt.ylabel("Frequency greater than alpha", color="blue")
plt.legend()
plt.show()

def hoff(es):
    hoff_bound = []
    for e in es:
        hoff_bound.append(np.exp(-2*20*(e-0.5)**2)*1000000)
    return hoff_bound

def markov(aaaa):
    mark_bound=[]
    for a in aaaa:
        mark_bound.append(1000000*0.5/a);
    return mark_bound

plt.figure(2)
plt.plot(aaaa, emp_freqs, label="Empirical frequency", color="red", linestyle=':')
plt.plot(aaaa, hoff(aaaa), label = "Hoeffding's Bound", color="blue", linestyle=':')
plt.plot(aaaa, markov(aaaa), label = "Markov's Bound", color="green", linestyle=':')
plt.title("Hoeffding's and Markov's Bounds", color="blue")
plt.xlabel(" alpha", color="red")
plt.ylabel("Frequency of average greater than alpha", color="red")
plt.legend()
plt.axis([0.5,1.0, 0,1000000])
#plt.legend(bbox_to_anchor=(0, -0.15, 1, 0), loc=2, borderaxespad=0)
plt.legend()
plt.show()

#Handling Data
locationTrain = 'IrisTrainML.dt'
locationTest = 'IrisTestML.dt'
dfTrain = pd.read_csv(locationTrain, header=None, sep=' ')
dfTest = pd.read_csv(locationTest, header=None, sep=' ')

dfTrainNO2 = dfTrain.loc[dfTrain[2] != 2]
dfTestNO2 = dfTest.loc[dfTest[2] != 2]

irisTrainX = dfTrainNO2.as_matrix(columns=[0,1])
irisTrainY = dfTrainNO2.as_matrix(columns=[2])
irisTestX = dfTestNO2.as_matrix(columns=[0,1])
irisTestY = dfTestNO2.as_matrix(columns=[2])

np.place(irisTrainY, irisTrainY == 0, -1)
np.place(irisTestY, irisTestY == 0, -1)

def bigX(inputData):
    if inputData.shape[0] > inputData.shape[1]:
        inputNoTilde = inputData
    else:
        inputNoTilde = np.transpose(inputData)
    ones = np.ones((len(inputNoTilde), 1), dtype=np.int)
    inputX = np.hstack((inputNoTilde, ones))
    return inputX

# Weights
def initWeights(data):
    dimensions = data.shape[1]
    weights = np.zeros((dimensions))
    return weights

# Simple Gradient
def gradOneSimple(x, y, w):
    yMULTx = np.multiply(y,x)
    wDOTx = np.dot(np.transpose(w),x)
    yMULTwtx = np.multiply(y, wDOTx)
    exp = np.exp(yMULTwtx)
    gradient = np.divide(yMULTx, 1 + exp)
    return gradient

# Full Gradient
def gradient(dataX, dataY, weights):
    accum = initWeights(dataX)
    n = len(dataY)
    for i in range(len(dataX)):
        gradient = gradOneSimple(dataX[i], dataY[i], weights)
        accum += gradient
    mean = np.divide(accum, n)
    gradient = np.negative(mean)
    return gradient

# Function for updating weights.
def updateWeights(oldWeights, direction, learningRate):
    newWeight = oldWeights + np.multiply(learningRate, direction)
    return newWeight

# Logistic regression model. Implementation of LFD algorithm.
def logReg(dataX, dataY, learningRate):
    X = bigX(dataX)
    weights = initWeights(X)
    for i in range(0,1000):
        g = gradient(X, dataY, weights)
        direction = -g
        weights = updateWeights(weights, direction, learningRate)
    return weights

# Building affine linear model and reporting results.
vectorWandB = logReg(irisTrainX, irisTrainY, 0.1)

vectorW = np.transpose(vectorWandB[:-1])

b = vectorWandB[-1]

print(vectorWandB)
print('\n')
print('Affine linear model build. w: ' + str(vectorW) + '   b: '
                                             + str(b) + '\n')

# Function that computes conditional probability using logistic regression.
def conditionalProb(x, vectorW, b):
    wDOTx = np.dot(vectorW, x)
    y = wDOTx + b
    exp = np.exp(y)
    prob = np.divide(exp, 1 + exp)
    return prob

# Function that classifies using the probability from logistic regression.
def linearClassifier(x, vectorW, b ):
    y = -2
    prob = conditionalProb(x, vectorW, b)
    if prob > 0.5:
        y = 1
    else:
        y = -1
    return y

# Function that finds the number of wrong classifications for test data.
def testingFalse(trainX, trainY, testX, testY, learningRate):
    trueCount = 0
    falseCount = 0
    weights = logReg(trainX, trainY, learningRate)
    vectorW = weights[:-1]
    b = weights[-1]
    for i in range(0,len(testY)):
        if linearClassifier(testX[i], vectorW, b) == testY.item(i):
            trueCount += 1
        else:
            falseCount += 1
    return falseCount

# Finding the empirical loss of linear classification model with a zero-one loss
# function.
def zeroOneLoss(trainX, trainY, testX, testY, learningRate):
        N = len(testY)
        misClassified = testingFalse(trainX, trainY, testX, testY, learningRate)
        zeroOneLoss = (1/N)*misClassified
        return zeroOneLoss

lossTrain = zeroOneLoss(irisTrainX, irisTrainY, irisTrainX, irisTrainY, 0.1)
lossTest = zeroOneLoss(irisTrainX, irisTrainY, irisTestX, irisTestY, 0.1)
print("0-1 loss of logistic regression linear classifier on training data: " + str(lossTrain))
print("0-1 loss of logistic regression linear classifier on testing data: " + str(lossTest))


import pygame as pg
from pygame.math import Vector2

from src.camera import Camera
from src.game_objects.abstract.tile import Tile
from src.game_objects.movable_tile import MovableTile
from src.game_objects.selection_box import SelectionBox
from src.game_objects.static_tile import StaticTile
from src.graphics import SpriteSheet
from src.main_loop import MainLoop
from src.map import Map
from src.settings.constants import (
    CAPTION,
    SCREEN_SIZE,
    FPS,
    TILE_SIZE,
    ACTIVATE_SCROLLING_BORDERS,
    ACTIVATE_TEST_GRID,
    BG_COLOR,
)
from src.settings.controllers import CONTROLLERS_CAMERA
from src.settings.paths import *

class GameCore(MainLoop):
    def __init__(self):
        super().__init__(CAPTION, SCREEN_SIZE, FPS)

        self.image_manager = SpriteSheet()
        self.selection_box = pg.sprite.GroupSingle(None)

        self.nature_tiles = pg.sprite.Group()
        self.player1_villages = pg.sprite.Group()
        self.player1_units = pg.sprite.Group()

        self.search_order = [
            self.nature_tiles,
            self.player1_villages,
            self.player1_units,
        ]

        self.create_objects()
        self.mouse_handlers.append(self.handle_mouse_event)

    def create_objects(self):
        self._create_test_map()
        self._create_camera()

    def _create_camera(self):
        self.camera = Camera(self.map.width, self.map.height, ACTIVATE_SCROLLING_BORDERS)
        for key in CONTROLLERS_CAMERA.values():
            self.add_up_down_key_handlers(self.camera, key)

    def _draw_grid(self):
        width, height = self.main_surface.get_size()
        for x in range(0, width, TILE_SIZE):
            pg.draw.line(self.main_surface, "darkgrey", (x, 0), (x, height))
        for y in range(0, height, TILE_SIZE):
            pg.draw.line(self.main_surface, "darkgrey", (0, y), (width, y))

    def _create_test_map(self):
        self.map = Map(TEST_MAP)
        for row, tiles in enumerate(self.map.get_data):
            for column, tile in enumerate(tiles):
                if tile == "1":
                    t = StaticTile(Vector2(column, row), self.image_manager.get_image("grass"))
                    self.nature_tiles.add(t)
                    self.visible_sprites.add(t, layer=0)
                if tile == "0":
                    t = StaticTile(Vector2(column, row), self.image_manager.get_image("water"))
                    self.nature_tiles.add(t)
                    self.visible_sprites.add(t, layer=0)
                if tile == "8":
                    t = StaticTile(Vector2(column, row), self.image_manager.get_image("grass"))
                    self.nature_tiles.add(t)
                    self.visible_sprites.add(t, layer=0)

                    t = MovableTile(Vector2(column, row), self.image_manager.get_image("farmer"))
                    self.player1_units.add(t)
                    self.visible_sprites.add(t, layer=2)
                if tile == "9":
                    # TODO: Remove double sprite on one coordinate
                    t = StaticTile(Vector2(column, row), self.image_manager.get_image("grass"))
                    self.nature_tiles.add(t)
                    self.visible_sprites.add(t, layer=0)

                    t = Tile(Vector2(column, row), self.image_manager.get_image("village"))
                    self.player1_villages.add(t)
                    self.visible_sprites.add(t, layer=1)

    def handle_mouse_event(self, type_, pos, button=0):
        pos = self.camera.apply(pos)

        if type_ == pg.MOUSEMOTION:
            pass
        elif type_ == pg.MOUSEBUTTONDOWN:
            self.handle_mouse_down(pos, button)
        elif type_ == pg.MOUSEBUTTONUP:
            pass

    def left_click(self, clicked_sprite):
        # select
        if self.selection_box.sprite is None:
            sb = SelectionBox(clicked_sprite)
            self.selection_box.add(sb)
            self.visible_sprites.add(sb)

        # unselect
        elif self.selection_box.sprite.target is clicked_sprite:
            self.selection_box.sprite.kill()

    def right_click(self, clicked_sprite):
        if self.selection_box.sprite is not None:
            if isinstance(self.selection_box.sprite.target, MovableTile):
                self.selection_box.sprite.target.move_to(clicked_sprite)

    def handle_mouse_down(self, mouse_pos, mouse_button):
        def mouse_button_function():
            """Call the appropriate click function with the clicked_sprite parameter depending on the button"""
            return {
                1: self.left_click,
                3: self.right_click,
            }.get(mouse_button, lambda _: None)(clicked_sprite)

        clicked_sprite = None
        for group in self.search_order:
            for sprite in group:
                if sprite.check_click(mouse_pos) is True:
                    clicked_sprite = sprite
                    break

        if clicked_sprite is not None:
            mouse_button_function()

    def draw(self):
        for sprite in self.visible_sprites:
            self.main_surface.blit(sprite.image, self.camera.apply(sprite))

        if ACTIVATE_TEST_GRID is True:
            self._draw_grid()

    def update(self):
        self.main_surface.fill(BG_COLOR)
        super().update()
        self.camera.update()

if __name__ == '__main__':
    GameCore().run()


__author__ = 'nipunbatra'

import numpy as np
import pandas as pd

def read_df():

    df = pd.read_csv("../data/input/main-data.csv",index_col=0)
    dfc = df.copy()

    df = df.drop(871)
    df = df.drop(1169)

    w=df[['aggregate_%d' %i for i in range(1,13)]]

    df = df.ix[w[w>0].dropna().index]

    features_individual = {'fraction':["fraction_%d" % i for i in range(1, 25)],
                           'area': 'area',
                           'autocorr':'autocorr',
                           'month': ["aggregate_%d" % i for i in range(1, 13)],
                           'occupants': 'total_occupants',
                           'rooms': 'num_rooms',
                           'seasonal_12':['stdev_seasonal_12','max_seasonal_12'],
                           'trend_12':['stdev_trend_12','max_trend_12'],

                           'seasonal_daily':['stdev_seasonal_daily','max_seasonal_daily'],
                           'trend_daily':['stdev_trend_daily','max_trend_daily'],
                           'seasonal_weekly':['stdev_seasonal_weekly','max_seasonal_weekly'],
                           'trend_weekly':['stdev_trend_weekly','max_trend_weekly'],
                           'cluster_big':'cluster_big',
                           'cluster_small':'cluster_small',
                           'diff':['lt_500','bet_500_1000','gt_1000'],
                           'temp':'temperature_corr',
                           'week':["fraction_%d" % i for i in range(1, 8)],
                           #'disag_fridge':'disag_fridge'}
                           'mins_hvac':'mins_hvac',
                           'month_extract':['variance','ratio_min_max', 'difference_min_max',
                                            'ratio_difference_min_max']}

    from itertools import combinations
    features_dict = {}
    for feature_size in range(1,max(4,len(features_individual))):
        combinations_size_n = list(combinations(features_individual.keys(), feature_size))
        for com in combinations_size_n:
            features_dict[com] = np.hstack([features_individual[x] for x in com]).tolist()

    national_average = {"fridge": 0.07, "hvac": 0.18, 'wm': 0.01, 'furnace': 0.09, 'dw': 0.02, 'dr': 0.04, 'light': .11}

    def scale_0_1(ser, minimum=None, maximum=None):
        if minimum is not None:
            pass
        else:
            minimum = ser.min()
            maximum = ser.max()
        return (ser-minimum).div(maximum-minimum)

    #Normalising features
    max_aggregate = df[["aggregate_%d" % i for i in range(1, 13)]].max().max()
    min_aggregate = df[["aggregate_%d" % i for i in range(1, 13)]].min().min()
    df[["aggregate_%d" % i for i in range(1, 13)]] = scale_0_1(df[["aggregate_%d" % i for i in range(1, 13)]], min_aggregate, max_aggregate)

    max_weekly = df[["daily_usage_%d" % i for i in range(1, 8)]].max().max()
    min_weekly = df[["daily_usage_%d" % i for i in range(1, 8)]].min().min()
    df[["daily_usage_%d" % i for i in range(1, 8)]] = scale_0_1(df[["daily_usage_%d" % i for i in range(1, 8)]], min_weekly, max_weekly)

    df['area'] = scale_0_1(df['area'])

    df['num_rooms'] = scale_0_1(df['num_rooms'])
    df['total_occupants'] = scale_0_1(df['total_occupants'])
    df['mins_hvac'] =  scale_0_1(df['mins_hvac'])

    # Adding new feature
    aa = df[["aggregate_%d" % i for i in range(1, 13)]].copy()
    df['variance'] = df[["aggregate_%d" % i for i in range(1, 13)]].var(axis=1)
    df['ratio_min_max'] = aa.min(axis=1)/aa.max(axis=1)

    df['difference_min_max'] = aa.max(axis=1)-aa.min(axis=1)
    df['ratio_difference_min_max'] = (aa.max(axis=1)-aa.min(axis=1)).div(aa.max(axis=1))

    # Adding skew and kurtosis on monthly aggregate
    k = {}
    s ={}
    p_25 ={}
    p_75 = {}
    p_50 = {}
    for home in df.index:
        signal = df.ix[home][['aggregate_%d' %i for i in range(1, 13)]]
        k[home] = signal.kurtosis()
        s[home] = signal.skew()
        p_25[home] =np.percentile(signal, 25)
        p_50[home] =np.percentile(signal, 50)
        p_75[home] = np.percentile(signal, 75)

    df['skew'] = pd.Series(s)
    df['kurtosis']=pd.Series(k)
    df['p_25']=pd.Series(p_25)
    df['p_50'] =pd.Series(p_50)
    df['p_75']=pd.Series(p_75)

    for col in ["stdev_trend_12","stdev_seasonal_12","max_seasonal_12","max_trend_12",
                "stdev_trend_daily","stdev_seasonal_daily","max_seasonal_daily","max_trend_daily",
                "stdev_trend_weekly","stdev_seasonal_weekly","max_seasonal_weekly","max_trend_weekly","disag_fridge",
                'stdev_trend','stdev_seasonal','max_seasonal','max_trend',
                'cluster_small','cluster_big', 'temperature_corr', 'variance',
                'ratio_min_max','ratio_difference_min_max','seasonal_energy_5','seasonal_energy_6',
                'seasonal_energy_7','seasonal_energy_8','seasonal_energy_9','seasonal_energy_10',
               'fft_1','fft_2','fft_3','fft_4','fft_5','skew','kurtosis','p_25','p_50','p_75']:
        if col in df.columns:

            df[col] = scale_0_1(df[col])

    dfs = {}
    total = features_dict.values()[np.array(map(len, features_dict.values())).argmax()]
    for appliance in ['fridge','hvac','dr','light','dw','wm']:
        temp=df.ix[df[['%s_%d' %(appliance, i) for i in range(1,13)]].dropna().index]
        dfs[appliance] =temp.ix[temp[total].dropna().index]

    appliance_min = {'fridge':5,'hvac':5,'wm':0,'dw':0,'dr':0,'light':0}

    all_homes = {
        'dw':[  94,  370,  545,  624, 2156, 2242, 2814, 2829, 3723,
                4767, 5357,6636, 6910, 7769, 9934],
        'wm':[  94,  370,  545,  624, 2156, 2242, 2814, 3367, 3456, 3723, 3967,
                5357, 7769, 9654, 9922, 9934],
        'hvac':[  26,   94,  370,  410,  545,  624, 1283, 1642, 1953, 2129,
                2156, 2242, 2470, 2814, 2829,  3367, 3456, 3723,
                3967, 4767, 5218, 5357, 5371, 5746, 5785, 5814, 6072,
                6636, 6836, 6910, 7731, 7769, 7866, 9609, 9654, 9922, 9933, 9934],
        'fridge':[  94,  370,  410,  545,  624, 1953, 2156, 2242, 2814, 2829, 3367,
                3456, 3723, 3967, 4767, 5357, 5371, 6072, 6636, 6910, 7769, 7866],
        'light':df.index.tolist(),
            #[ 624, 1334, 2814, 2925, 2986, 3367, 3456, 3482, 3723, 3967, 4732,
            #    4767, 5814, 5817, 6072, 6266, 6910, 7016, 7429, 7731, 7769, 7866,
            #    8317, 8626, 9052, 9654, 9922],
        'dr':[  94,  370,  410, 2156, 2242, 2814, 3456, 3723, 4767,
                5785, 5814, 6072, 6636, 6836, 7731, 7769, 7866, 9654, 9922,
                9933, 9982]
    }

    all_homes = {appliance:dfs[appliance].index for appliance in dfs.keys()}

    all_homes['fridge'] = np.array(np.setdiff1d(all_homes['fridge'], [26, 1334, 1642, 2233,3482,6836, 5746, 7016, 9982]))

    ### HVAC ###
    # 1334 is not used in some months, ideally we can do signal processing and remove it,
    # Currently removed it manually; similarly 94
    all_homes['hvac'] = np.array(np.setdiff1d(all_homes['hvac'], [94, 252, 1334, 2925, 2986, 3482, 4732, 5439, 6266,
                                                                  8626, 1800, 2233, 5817, 7016, 7429, 8317,
                                                                  9052, 9982]))

    all_homes['dw'] =  np.array(np.setdiff1d(all_homes['dw'],[2233, 7016]))

    all_homes['wm'] = [  94,  370,  545,  624, 2156, 2242, 2814, 3367, 3456, 3723, 3967,
            5357, 7769, 9654, 9922, 9934]

    all_homes['light']=[624, 1334, 3367, 3456, 3723, 5814, 6072, 6910, 7769, 7866, 9654,
            9922]

    return df, dfc, all_homes, appliance_min, national_average


from django.urls import reverse_lazy
from django.views.generic.edit import FormView

from forum.forms import ContactForm

class ContactView(FormView):
    template_name = 'pages/contact.html'
    form_class = ContactForm
    success_url = reverse_lazy('forum:home')

    def form_valid(self, form):
        form.send_email()
        return super().form_valid(form)