"""
Page for utilities
Çeşitli fonksiyonların tanımlandığı yer
"""

import json
import os
import tempfile
import uuid
import xml.etree.ElementTree as et
import zipfile

import ee
import folium
import geemap.foliumap as geemap
import numpy as np
import pandas as pd
import streamlit as st
from lxml import etree
import plotly.graph_objects as go
from matplotlib import colors

delta_nbr_colors = {
    "Veri Yok": "ffffff",
    "Yüksek yeniden büyüme": "7a8737",
    "Düşük yeniden büyüme": "acbe4d",
    "Yanmamış": "0ae042",
    "Düşük Tahribat": "fff70b",
    "Orta-Düşük tahribat": "ffaf38",
    "Orta-yüksek tahribat": "ff641b",
    "Yüksek tahribat": "a41fd6",
}

ndvi_colors = {
    "min":-1, "max":1,
    "palette": [
        "#d73027",
        "#f46d43",
        "#fdae61",
        "#fee08b",
        "#d9ef8b",
        "#a6d96a",
        "#66bd63",
        "#1a9850",
    ]
}

ndvi_colors2 = {
    "min":-1, "max":1,
    "palette": [
        "#af002d", # -1, -0.9
        "#af002d", # -0.9, -0.8
        "#af002d", # -0.8, -0.7
        "#af002d", # -0.7, -0.6
        "#af002d", # -0.6, -0.5
        "#af002d", # -0.5, -0.4
        "#af002d", # -0.4, -0.3
        "#af002d", # -0.3, -0.2
        "#af002d", # -0.2, -0.1
        "#af002d", # -0.1, 0
        "#af002d", # 0, 0.1
        "#ee4c41", # 0.1, 0.2
        "#fd8958", # 0.2, 0.3
        "#ffbf7b", # 0.3, 0.4
        "#ffedab", # 0.4, 0.5
        "#e6f8a6", # 0.5, 0.6
        "#b9e284", # 0.6, 0.7
        "#66cc66", # 0.7, 0.8
        "#009966", # 0.8, 0.9
        "#006633", # 0.9, 1
    ]
}

ndvi_colors2_legend = {
    "0.9-1.0": "006633",
    "0.8-0.9": "009966",
    "0.7-0.8": "66cc66",
    "0.6-0.7": "b9e284",
    "0.5-0.6": "e6f8a6",
    "0.4-0.5": "ffedab",
    "0.3-0.4": "ffbf7b",
    "0.2-0.3": "fd8958",
    "0.1-0.2": "ee4c41",
    "-1.0-0.1 ": "af002d",
}

ndvi_colors2_hist = {
    "0.90": "#006633",
    "0.80": "#009966",
    "0.70": "#66cc66",
    "0.60": "#b9e284",
    "0.50": "#e6f8a6",
    "0.40": "#ffedab",
    "0.30": "#ffbf7b",
    "0.20": "#fd8958",
    "0.10": "#ee4c41",
    "0.00": "#af002d"
}

ndvi_colors2_imshow = colors.ListedColormap([
    "#af002d",
    "#ee4c41",
    "#fd8958",
    "#ffbf7b",
    "#ffedab",
    "#e6f8a6",
    "#b9e284",
    "#66cc66",
    "#009966",
    "#006633"
    ])

scale = [-1, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1]
ndvi_colors2_norm=colors.BoundaryNorm(scale, 10)

mask_seq_imshow = colors.ListedColormap([
    "white",
    "darkred",
    "red",
    "orange"
    ])

mask_seq_colors = {
    "min":0, "max": 3,
    "palette": [
        "#ffffff", # 0
        "#8b0000", # 0
        "#ff0000", # 1
        "#ffa500", # 2
    ]
}
mask_scale = [0, 1, 2, 3]
mask_colors_norm=colors.BoundaryNorm(mask_scale, 3)

evi_colors = {
    # "min":0.1, "max":0.8,
    "min":0, "max":1,
    "palette": [
        'FFFFFF', 'CE7E45', 'DF923D', 'F1B555', 'FCD163', '99B718',
        '74A901', '66A000', '529400', '3E8601', '207401', '056201',
        '004C00', '023B01', '012E01', '011D01', '011301'
    ]
}

evi_scale = [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8]
evi_colors_norm=colors.BoundaryNorm(evi_scale, 8)

evi_colors_imshow = colors.ListedColormap([
    "#FFFFFF",
    "#CE7E45",
    "#DF923D",
    "#F1B555",
    "#FCD163",
    "#99B718",
    "#74A901",
    "#66A000",
    "#529400",
    "#3E8601",
    "#207401",
    "#056201",
    "#004C00",
    "#023B01",
    "#012E01",
    "#011D01",
    "#011301"
    ])

mbi_colors = {
    "min":-0.3, "max":0.6,
    "palette": [
        'FFFFFF', 'CE7E45', 'DF923D', 'F1B555', 'FCD163', '99B718',
        '74A901', '66A000', '529400', '3E8601', '207401', '056201',
        '004C00', '023B01', '012E01', '011D01', '011301'
    ]
}

mbi_scale = [-0.3, -0.2, -0.1, 0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6]
mbi_colors_norm=colors.BoundaryNorm(mbi_scale, 9)

mbi_colors_imshow = colors.ListedColormap([
    "#FFFFFF",
    "#CE7E45",
    "#DF923D",
    "#F1B555",
    "#FCD163",
    "#99B718",
    "#74A901",
    "#66A000",
    "#529400",
    "#3E8601",
    "#207401",
    "#056201",
    "#004C00",
    "#023B01",
    "#012E01",
    "#011D01",
    "#011301"
    ])

NAMES = [
    "Veri Yok",
    "Yüksek tahribat",
    "Orta-yüksek tahribat",
    "Orta-Düşük tahribat",
    "Düşük Tahribat",
    "Yanmamış",
    "Düşük yeniden büyüme",
    "Yüksek yeniden büyüme",
]

def calculate_dnbr_dataframe(number_of_pixels):
    """
    The function to calculate the DNBR dataframe.
    """
    names = NAMES
    values = np.array(number_of_pixels)  # pixel numbers
    hectares = values * 900 / 10000  # convert to hectares
    percenteges = hectares / np.sum(hectares) * 100  # calculate percenteges

    dataframe = pd.DataFrame(
        {"dNBR sınıfları": names, "hektar": hectares, "yüzde": percenteges}
    )
    dataframe = dataframe.style.format(precision=2)
    return dataframe.to_html()

def get_plotly_charts(number_of_pixels):
    """
    The function to generate the plotly charts.
    """
    fig = go.Figure(
        data=[
            go.Pie(
                labels=NAMES,
                values=list(number_of_pixels),
                sort=False,
                marker=dict(
                    colors=[
                        "ffffff",
                        "a41fd6",
                        "ff641b",
                        "ffaf38",
                        "fff70b",
                        "0ae042",
                    ]
                ),
            )
        ],
    )

    return fig

def get_pixel_counts(image, geometry):
    """
    The function to get the pixel counts of classes in an dNBR image.
    """
    # pylint: disable=no-member
    thresholds = ee.Image([-1000, -251, -101, 99, 269, 439, 659, 2000])
    classified = image.lt(thresholds).reduce("sum").toInt()
    allpix = classified.updateMask(classified)
    pixstats = allpix.reduceRegion(
        maxPixels= 10000000000,
        reducer=ee.Reducer.count(),  # count pixels in a single class
        geometry=geometry,
        scale=30,
    )

    allpixels = ee.Number(pixstats.get("sum"))  # extract pixel count as a number
    allpixels.getInfo()
    results = []

    results = []
    for i in range(8):
        single_mask = classified.updateMask(classified.eq(i))  # mask a single class
        stats = single_mask.reduceRegion(
            maxPixels= 10000000000,
            reducer=ee.Reducer.count(),  # count pixels in a single class
            geometry=geometry,
            scale=30,
        )
        pix = ee.Number(stats.get("sum"))

        results.append(pix.getInfo())
    return results

def map_search(folium_map: geemap.Map) -> None:  # sourcery skip: use-named-expression
    """
    The function to generate the search box above the map.
    """
    keyword = st.text_input("Bölge arayın:", "")
    if keyword:
        locations = geemap.geocode(keyword)
        if locations is not None and len(locations) > 0:
            str_locations = [str(g)[1:-1] for g in locations]
            location = st.selectbox("Bölge seçin:", str_locations)
            loc_index = str_locations.index(location)
            selected_loc = locations[loc_index]
            lat, lng = selected_loc.lat, selected_loc.lng
            folium.Marker(location=[lat, lng], popup=location).add_to(folium_map)
            folium_map.set_center(lng, lat, 12)
            st.session_state["zoom_level"] = 12

def kml_geometry_export(file_path):
    """
    The function to export the geometry of a KML file.
    """
    # pylint: disable=c-extension-no-member
    root = etree.parse(file_path)

    for i in root.iter():
        path = root.getelementpath(i).split("}")[0] + "}"

    tree = et.parse(file_path)
    root = tree.getroot()

    name = root.find(f".//*{path}coordinates")
    geolist = name.text.strip().split(" ")

    geometry = []

    for i in geolist:
        current = i.split(",")
        # en az 3 point içermesi lazım yoksa EEException error veriyor.
        geometry.append([float(current[0]), float(current[1])])

    return ee.Geometry.Polygon(geometry)

def uploaded_file_to_gdf(data):
    """
    The function to convert uploaded file to geodataframe.
    """
    _, file_extension = os.path.splitext(data.name)
    file_id = str(uuid.uuid4())
    file_path = os.path.join(tempfile.gettempdir(), f"{file_id}{file_extension}")

    with open(file_path, "wb") as file:
        file.write(data.getbuffer())

    # gpd.io.file.fiona.drvsupport.supported_drivers["KML"] = "rw"

    if file_path.lower().endswith(".kml"):

        return kml_geometry_export(file_path)

    if file_path.lower().endswith(".kmz"):
        # unzip it to get kml file
        in_kmz = os.path.abspath(file_path)
        out_dir = os.path.dirname(in_kmz)
        out_kml = os.path.join(out_dir, "doc.kml")
        with zipfile.ZipFile(in_kmz, "r") as zip_ref:
            zip_ref.extractall(out_dir)

        return kml_geometry_export(out_kml)

    if file_path.lower().endswith(".geojson"):
        with open(file_path, "r", encoding="utf-8") as file:
            data = json.loads(file.read())

        return ee.Geometry.Polygon(data["features"][0]["geometry"]["coordinates"][0])


import os
import time
import datetime
import pandas as pd
import numpy as np
#import plotly.plotly as py
#import plotly.graph_objs as go

from django.utils import timezone
from dateutil.relativedelta import relativedelta

from .renderers import RenderTemplate
from .load import load_hdf

from .guru_responses import *

module_dir = os.path.dirname(__file__)

wor_master = load_hdf(os.path.join(module_dir, 'dumps/worxogo_merged.h5'))
#wor_badges = load_hdf(os.path.join(module_dir, 'dumps/badges.h5'))
wor_badges = load_hdf(os.path.join(module_dir, 'dumps/worxogo_merged_badges.h5'))
#wor_users = load_hdf(os.path.join(module_dir, 'dumps/users.h5'))

class ParsingError(Exception):
    """raised whenever there is some problem parsing
       condition or aggregate function parameters
    """
    def __init__(self, message):
        Exception.__init__(self, message)

def error_mesg(mesg):
    _mesg = {}
    _mesg['type'] = 'message'
    _mesg['data'] = mesg
    return [_mesg]

def generate_result(df, result_type, section, **others):
    answer = {}
    print(others)
    print(df.head())

    if result_type == 'graph':
        result = RenderTemplate('test.html')
        content = others
        content['header'] = others.get('header', '')
        content['type'] = 'graph'
        content['graph_type'] = others.get('graph_type', 'line')
        content['body'] = df
        result.render_to(section=section, content=content)
        result = result.render()
        answer['type'] = 'graph'
        answer['data'] = result
        answer['format'] = list(df.columns)
        return answer
    else:
        df = df.drop_duplicates()
        # limiting row count
        df = df[:5000]
        data = []
        answer_format = list(df.columns)
        for row in df.values:
            temp = []
            for r in row:
                temp.append(str(r))
            data.append(temp)

        table_data= '

'
        table_data+= '
'
        for col in answer_format:
            table_data+= '' + col + '	'
        table_data+= '
'
        for chunk in data:
            table_data+= '
'
            for i in range(len(chunk)):
                table_data+= '' + str(chunk[i]) + '	'
            table_data+= '
'
        table_data+= '
'

        result = RenderTemplate('test.html')
        content = others
        content['header'] = others.get('header', '')
        content['type'] = 'table'
        content['body'] = table_data
        result.render_to(section=1, content=content)
        result = result.render()
        answer['type'] = 'table'
        answer['data'] = result
        answer['format'] = list(df.columns)
        return answer

"""
templates = {}
limit = ''
templates['tb_name+columns'] = "{tb_name}[{columns}]"
templates['tb_name+columns+order_by'] = "{tb_name}[{columns}].sort_values(by={order_by}, ascending=False)"
templates['tb_name+columns+conditions'] = "{tb_name}.ix[{conditions}][{columns}]"
templates['tb_name+columns+conditions+order_by'] = "{tb_name}.ix[{conditions}][{columns}].sort_values(by={order_by}, ascending=False)"
templates['tb_name+columns+conditions+group_by+order_by+agg_func'] = "{tb_name}.ix[{conditions}][{columns}].groupby({group_by}){agg_func}"
"""

def get_query(query_parameters):
    #search templates
    print('inside get_query()')
    print(query_parameters)
    for key in templates.keys():
        key_set= set(key.split('+'))
        print(key_set, set(query_parameters.keys()))
        if key_set == set(query_parameters.keys()):
            print('Match Found!')
            return templates[key].format(**query_parameters)
        else:
            print('Not a Match.')
"""
def get_tbname(parameters):
    #accept some parameters (column_names)
    #return table name
    if 'style' in parameters:
        return 'ROS_sell_thru_ss_Report'
    elif 'sub_brand' in parameters:
        return 'ROS_sell_thru_ssb_Report'
    else:
        return 'ROS_sell_thru_sb_Report'
"""

table_column_map = {
       'wor_master': [('df', 'wor_master')],
       'wor_badges': [('df', 'wor_badges'), ('date', 'created_at')]
       }

def modify_columns(tbname, columns):
    #modify columns according to table name.
    for _map in table_column_map[tbname]:
        if _map[0] in columns:
            i = columns.index(_map[0])
            columns[i] = _map[1]
    print('inside modify columns:', columns)
    return columns

def modify_query(tbname, query):
    # modify query parameters as per table name
    for s1, s2 in table_column_map[tbname]:
        query = query.replace('<<' + s1 + '>>', s2)
    query = query.replace('<<', '').replace('>>', '')
    return query

def improved_users(entities, source):
    columns = ['user_employee_code', 'user_name', 'objective_points']
    condition_list, columns = get_conditions(entities, columns)
    agg_func_str, columns = get_agg_functions(entities, columns)
    print(columns)
    if 'date' not in columns:
        condition_list.append("(<<df>>.<<date>>.isin(pd.date_range(\
                    start=timezone.now().date()-timezone.timedelta(\
                    days=30), periods=30, freq='D')))")
        #condition_list.append("(<<df>>['<<date>>']=='2016-10-20')")
        #columns.append('date')
    if 'objective_text' not in columns:
        condition_list.append("(<<df>>.<<objective_text>>=='MSP')")
        columns.append('objective_text')

    tb_name = 'wor_master' #get_tbname(columns)
    #modify column_names as per the table
    columns = modify_columns(tb_name, columns)
    conditions = ' & '.join(condition_list)
    if conditions:
        query = "{tb_name}.ix[{conditions}][{columns}]".format(\
                    tb_name=tb_name, conditions=conditions, columns=columns)
    else:
        query = "{tb_name}[{columns}]".format(
                    tb_name=tb_name, conditions=conditions, columns=columns)

    if not query:
        return error_mesg(get_resp_negative())

    query = modify_query(tb_name, query)
    print(query)

    # execution
    try:
        #get rows and columns
        t1 = eval(query)

        t2 = t1.groupby(['user_employee_code',] )['objective_points'].sum().to_frame('points').reset_index().sort_values(by='points', ascending=False)
        print(t2.head())

        data = t2[['user_employee_code']].merge(t1[['user_employee_code', 'user_name', 'objective_text']].drop_duplicates())

        data = data[['user_name', 'objective_text']].head(10)

        data.rename(columns={'user_name':'User', 'objective_text':'Objective'}, inplace=True)

    except Exception as e:
        print(e)
        return error_mesg(get_resp_negative())

    if data.empty:
        return error_mesg(get_resp_no_records())

    res = []

    if source == 'web':
         # generate graph or table or text
        res.append(generate_result(data, 'text', section=1))
    else:
        json_data = {"header":[], "rows":[]}
        json_data["header"].extend(data.dtypes.index.tolist())
        for value in data.values:
            row_values = value.tolist()
            _time = row_values.pop(-1)
            row_values.append(str(_time))
            json_data["rows"].append(row_values)

        res.append({"type":"message", "data": get_resp_positive()})
        res.append({"type":"table", "data":json_data})
    return res

def consistent_users(entities, source):
    columns = ['user_employee_code','user_name', 'target_obj_skew_indicator']
    condition_list, columns = get_conditions(entities, columns)
    agg_func_str, columns = get_agg_functions(entities, columns)
    print(columns)
    if 'date' not in columns:
        condition_list.append("(<<df>>.<<date>>.isin(pd.date_range(start=timezone.now().date()-timezone.timedelta(days=30), periods=30, freq='D')))")
        #condition_list.append("(<<df>>['<<date>>']=='2016-10-20')")
        #columns.append('date')
    if 'objective_text' not in columns:
        condition_list.append("(<<df>>.<<objective_text>>=='MSP')")

    columns = ['user_employee_code', 'user_name', 'objective_text', 'target_obj_skew_indicator']
    tb_name = 'wor_master' #get_tbname(columns)
    #modify column_names as per the table
    columns = modify_columns(tb_name, columns)
    conditions = ' & '.join(condition_list)
    if conditions:
        query = "{tb_name}.ix[{conditions}][{columns}]".format(tb_name=tb_name, conditions=conditions, columns=columns)
    else:
        query = "{tb_name}[{columns}]".format(tb_name=tb_name, conditions=conditions, columns=columns)

    if not query:
        return error_mesg(get_resp_negative())

    query = modify_query(tb_name, query)
    print(query)

    # execution
    try:
        #get rows and columns
        t1 = eval(query)

        t2 = t1.groupby(['user_employee_code',] )['target_obj_skew_indicator'].count().to_frame('count').reset_index()

        t3 = t1.groupby(['user_employee_code', 'target_obj_skew_indicator'] )['target_obj_skew_indicator'].count().to_frame('count').reset_index()

        data = t2.merge(t3, on=['user_employee_code', 'count'])

        data = data[['user_employee_code', 'target_obj_skew_indicator']].merge(t1[['user_employee_code', 'user_name', 'objective_text']].drop_duplicates())

        data = data[['user_name', 'objective_text', 'target_obj_skew_indicator']]

        data.rename(columns={'user_name':'User', 'objective_text':'Objective', 'target_obj_skew_indicator':'Target Skew Indicator'}, inplace=True)
    except Exception as e:
        print(e)
        return error_mesg(get_resp_negative())

    if data.empty:
        return error_mesg(get_resp_no_records())

    res = []
    if source == 'web':
         # generate graph or table or text
        res.append(generate_result(data, 'text', section=1))
    else:
        json_data = {"header":[], "rows":[]}
        json_data["header"].extend(data.dtypes.index.tolist())
        for value in data.values:
            row_values = value.tolist()
            _time = row_values.pop(-1)
            row_values.append(str(_time))
            json_data["rows"].append(row_values)

        res.append({"type":"message", "data":get_resp_positive()})
        res.append({"type":"table", "data":json_data})
    return res

def get_badges(entities, source):

    columns = ['user_name', 'badge_name']

    if entities['objective_text']:
        entities['objective_text'] = 'Category Mix' if 'category mix' in entities['objective_text'].lower() else entities['objective_text']
        entities['badge_img_name'] = 'Badge_%s_L1.png' %entities.pop('objective_text')

    condition_list, columns = get_conditions(entities, columns)
    #print(condition_list)
    agg_func_str, columns = get_agg_functions(entities, columns)
    #print(columns)
    """
    if 'date' not in columns:
        #condition_list.append("(<<df>>.<<created_date>>.isin(pd.date_range(start=timezone.now().date()-timezone.timedelta(days=8), periods=8, freq='D')))")
        condition_list.append("(<<df>>['<<date>>']=='2016-10-20')")
        columns.append('date')
    """

    tb_name = 'wor_badges' #get_tbname(columns)
    #modify column_names as per the table
    columns = modify_columns(tb_name, columns)
    conditions = ' & '.join(condition_list)
    if conditions:
        query = "{tb_name}.ix[{conditions}][{columns}]".format(tb_name=tb_name, conditions=conditions, columns=columns)
    else:
        query = "{tb_name}[{columns}]".format(tb_name=tb_name, conditions=conditions, columns=columns)

    if not query:
        return error_mesg(get_resp_negative())

    query = modify_query(tb_name, query)
    print(query)

    # execution
    try:
        #get rows and columns
        cols = eval(query)
        print("rows and columns\n\n")
        print(cols.head())
        if cols.empty:
            return error_mesg(get_resp_no_records())
        #groupby
        data = cols.groupby(['user_name', 'badge_name']).size().to_frame('count').reset_index().sort_values(by=['count', 'user_name'], ascending=False )
        data.rename(columns={'user_name':'User', 'badge_name':'Badge', 'count':'Count'}, inplace=True)
    except Exception as e:
        print(e)
        return error_mesg(get_resp_negative())

    if data.empty:
        error_mesg(get_resp_no_records())

    res = []
    if source == 'web':
        res.append(generate_result(data, 'text', section=1))
    else:
        json_data = {"header":[], "rows":[]}
        json_data["header"].extend(data.dtypes.index.tolist())
        for value in data.values:
            row_values = value.tolist()
            _time = row_values.pop(-1)
            row_values.append(str(_time))
            json_data["rows"].append(row_values)

        res.append({"type":"message", "data":get_resp_positive()})
        res.append({"type":"table", "data":json_data})
    return res

def get_top_users(entities, source):
    columns = ['user_employee_code', 'user_name', 'region', 'territory', 'objective_points']
    condition_list, columns = get_conditions(entities, columns)
    agg_func_str, columns = get_agg_functions(entities, columns)
    print(columns)
    if 'date' not in columns:
        #condition_list.append("(<<df>>.<<created_date>>.isin(pd.date_range(start=timezone.now().date()-timezone.timedelta(days=8), periods=8, freq='D')))")
        condition_list.append("(<<df>>['<<date>>']=='2016-10-20')")
        columns.append('date')

    limit = "[0:]"
    filter = entities.get('filter')

    if filter and (len(filter) > 1):
        if isinstance(filter, dict):
            if filter['limit'] == 'top':
                limit = "[ : %s]"%filter['value']
            if filter['limit'] == 'bottom':
                limit = "[-%s: ]"%filter['value']

    tb_name = 'wor_master' #get_tbname(columns)
    #modify column_names as per the table
    columns = modify_columns(tb_name, columns)
    conditions = ' & '.join(condition_list)
    if conditions:
        query = "{tb_name}.ix[{conditions}][{columns}]".format(tb_name=tb_name, conditions=conditions, columns=columns)
    else:
        query = "{tb_name}[{columns}]".format(tb_name=tb_name, conditions=conditions, columns=columns)

    if not query:
        return error_mesg(get_resp_negative())

    query = modify_query(tb_name, query)
    print(query)
    # execution
    try:
        #get rows and columns
        cols = eval(query)
        #print("rows and columns\n\n")
        #print(cols.head())
        if cols.empty:
            return error_mesg(get_resp_no_records())
        #groupby
        t1 = cols.groupby(['user_employee_code', 'date']).sum().sort_values(by='objective_points', ascending=False).reset_index()
        #print("grouping\n\n")
        #print(t1.head())

        _m = list(set(cols.columns) - set(t1.columns))
        _m.append('user_employee_code')
        #print(_m)
        data = t1.merge(cols[_m].drop_duplicates(), on=['user_employee_code'])
        #print('Merging\n\n')
        #print(data.head())
        final_cols = columns
        final_cols.remove('user_employee_code')
        #print("data["+str(final_cols)+"]"+limit)
        data = eval("data["+str(final_cols)+"]"+limit)

        data.rename(columns={'user_name':'User', 'region':'Region', 'territory':'Territory', 'objective_points':'Performance points', 'date':'Date', 'objective_text': 'Objective'}, inplace=True)

    except Exception as e:
        print(e)
        return error_mesg(get_resp_negative())

    if data.empty:
        error_mesg(get_resp_no_records())

    res = []
    if source == 'web':
        res.append(generate_result(data, 'text', section=1))
    else:
        json_data = {"header":[], "rows":[], 'type':'table'}
        json_data["header"].extend(data.dtypes.index.tolist())
        for value in data.values:
            row_values = value.tolist()
            _time = row_values.pop(-1)
            row_values.append(str(_time))
            json_data["rows"].append(row_values)

        res.append({"type":"message", "data":get_resp_positive()})
        res.append({"type":"table", "data":json_data})

    return res

def plot_target_sales(entities):
    columns = ['moctarget', 'salesvalue']
    group_by = ['moc']
    order_by = []
    column_filters = []
    condition_list, columns = get_conditions(entities, columns)
    agg_func_str, columns = get_agg_functions(entities, columns)
    if 'created_date' not in columns:
        stop = '%s-%s-%s'%(timezone.now().year, timezone.now().month, 1)
        start = datetime.date.today() + relativedelta(months=-6)
        dates = []
        for date in pd.date_range(start=start, end=stop, freq='M'):
                dates.append('%s-%s-%s'%(date.year, date.month, 1))

        condition_list.append("(<<df>>.<<created_date>>.isin(pd.DatetimeIndex(%s)))"%str(dates))
        if 'moc' not in columns:
            columns.append('moc')
    else:
        columns.remove('created_date') # we donot want this column to appear in final results.
        if 'moc' not in columns:
            columns.append('moc')

    if set(['account', 'city', 'state', 'region']).intersection(set(columns)):
        columns.append('countercode')

    #add more to condition here
    tb_name = 'hul_df' #get_tbname(columns)
    #modify the column_names as per the Table_name
    columns = modify_columns(tb_name, columns)
    column_filters = modify_columns(tb_name, column_filters)

    query_parameters = {}
    query_parameters['tb_name'] = tb_name
    query_parameters['columns'] = str(columns)
    if condition_list:
        query_parameters['conditions'] = ' & '.join(condition_list)
    if order_by:
        query_parameters['order_by'] = str(order_by)
    #if group_by:
        #query_parameters['group_by'] = str(group_by)

    query = get_query(query_parameters)

    for s1, s2 in table_column_map[tb_name]:
        query = query.replace('<<' + s1 + '>>', s2)
    query = query.replace('<<', '').replace('>>', '')

    t1 = execute_query([query, 'df'])
    t2 = t1[['moc', 'salesvalue']].groupby('moc').sum().reset_index()

    if set(['account', 'city', 'state', 'region']).intersection(set(columns)):
        t3 = t1[['moc', 'moctarget', 'countercode']].drop_duplicates().groupby('moc').sum().reset_index()
        data = t2.merge(t3, on='moc')

    elif 'countercode' in columns:
        t3 = t1[['moc', 'moctarget']].drop_duplicates()
        data = t2.merge(t3, on='moc')

    print(data)
    data = data.set_index('moc').unstack()
    data = data.to_frame('')
    res = generate_result(data, 'graph')
    return res
    #return (query, 'text')

def plot_store_report(entities):
    columns = ['store', 'target_obj_skew_indicator','created_date']
    column_filters = []
    group_by = ['target_obj_skew_indicator', 'created_date']
    order_by = []
    condition_list, columns = get_conditions(entities, columns)

    if 'created_date' not in columns:
        condition_list.append("(<<df>>.<<created_date>>.isin(pd.date_range(start=timezone.now().date()-timezone.timedelta(days=8), periods=8, freq='D')))")
        columns.append('created_date')

    if 'store' not in columns:
       return error_mesg("Didn't understand your query. Sorry.")

    tb_name = 'worxogo_df' #get_tbname(columns)
    #modify column_names as per the table
    columns = modify_columns(tb_name, columns)
    conditions = ' & '.join(condition_list)
    if conditions:
        query = "{tb_name}.ix[{conditions}][{columns}]".format(tb_name=tb_name, conditions=conditions, columns=columns)
    else:
        query = "{tb_name}.[{columns}]".format(tb_name=tb_name, conditions=conditions, columns=columns)

    if not query:
        return error_mesg("Sorry, couldn't understand your query")

    query = modify_query(tb_name, query)

    # execution
    try:
        #get rows and columns
        data = eval(query)
        _groupby = ['created_date', 'target_obj_skew_indicator']
        data = data.groupby(_groupby)['target_obj_skew_indicator'].count()
    except Exception as e:
        print(e)
        return error_mesg('Problem in execution!')

    # generate graph or table or text
    print(data)
    data = data.to_frame().unstack()
    print(data)
    #res = generate_result(data, 'graph', section=1)
    #g_data = [go.Scatter(x=data['created_date'], y=data['target_obj_skew_indicator'])]
    #print(g_data)
    #cufflinks.set_config_file(offline=False, world_readable=True, theme='ggplot')
    #data = cufflinks.datagen.lines()
    py.sign_in('headrun', '9gt3caodzr')
    #url = py.plot(g_data, filename='pandas-line-naming-traces')
    src = data.iplot(kind='bar', filename='cf-simple-line')
    res = {}
    res['type'] = 'graph'
    res['data'] = src.embed_code
    return res

def plot_region_report(entities, source):
    columns = ['region', 'target_obj_skew_indicator']
    column_filters = []
    group_by = ['target_obj_skew_indicator', 'date']
    order_by = []
    condition_list, columns = get_conditions(entities, columns)
    if 'date' not in columns:
        condition_list.append("(<<df>>.<<date>>.isin(pd.date_range(start=timezone.now().date()-timezone.timedelta(days=8), periods=8, freq='D')))")
        columns.append('date')

    if 'region' not in columns:
       return error_mesg("Didn't understand your query. Sorry.")

    tb_name = 'wor_master' #get_tbname(columns)
    #modify column_names as per the table
    columns = modify_columns(tb_name, columns)
    conditions = ' & '.join(condition_list)
    if conditions:
        query = "{tb_name}.ix[{conditions}][{columns}]".format(tb_name=tb_name, conditions=conditions, columns=columns)
    else:
        query = "{tb_name}.[{columns}]".format(tb_name=tb_name, conditions=conditions, columns=columns)

    if not query:
        return error_mesg("Sorry, couldn't understand your query")

    query = modify_query(tb_name, query)

    # execution
    try:
        #get rows and columns
        data = eval(query)
        _groupby = ['target_obj_skew_indicator', 'date']
        data = data.groupby(_groupby)['target_obj_skew_indicator'].count()
    except Exception as e:
        print(e)
        return error_mesg('Problem in execution!')

    # generate graph or table or text
    data = data.to_frame()
    res = generate_result(data, 'graph', section=1, graph_type='barh')
    return [res]

def plot_city_report(entities):
    columns = ['city', 'target_obj_skew_indicator','created_date']
    column_filters = []
    group_by = ['target_obj_skew_indicator', 'created_date']
    order_by = []
    condition_list, columns = get_conditions(entities, columns)
    if 'created_date' not in columns:
        condition_list.append("(<<df>>.<<created_date>>.isin(pd.date_range(start=timezone.now().date()-timezone.timedelta(days=8), periods=8, freq='D')))")
        columns.append('created_date')

    if 'city' not in columns:
       return error_mesg("Didn't understand your query. Sorry.")

    tb_name = 'worxogo_df' #get_tbname(columns)
    #modify column_names as per the table
    columns = modify_columns(tb_name, columns)
    conditions = ' & '.join(condition_list)
    if conditions:
        query = "{tb_name}.ix[{conditions}][{columns}]".format(tb_name=tb_name, conditions=conditions, columns=columns)
    else:
        query = "{tb_name}.[{columns}]".format(tb_name=tb_name, conditions=conditions, columns=columns)

    if not query:
        return error_mesg("Sorry, couldn't understand your query")

    query = modify_query(tb_name, query)

    # execution
    try:
        #get rows and columns
        data = eval(query)
        _groupby = ['target_obj_skew_indicator', 'created_date']
        data = data.groupby(_groupby)['target_obj_skew_indicator'].count()
    except Exception as e:
        print(e)
        return error_mesg('Problem in execution!')

    # generate graph or table or text
    data = data.to_frame()
    res = generate_result(data, 'graph', section=1, graph_type='bar')
    return res

def _get_value_from_context(context, keyword, current_index=0):
    #search for the keyword in context (list of dict's)
    #search left side
    for exp in context[current_index-1::-1]:
        value = exp.get(keyword, None)
        if value:
            return value
    #search right side
    for exp in context[current_index+1:]:
        value = exp.get(keyword, None)
        if value:
            return value

operators = {
    'gt': '>',
    'lt': '<',
    'gte': '>=',
    'lte': '<=',
    'eq': '='}

connectors = {
    'and': '&',
    'or': '|'}

def get_agg_functions(entities, columns):
    #normalising aggregate functions
    agg_func_list = []
    agg_func_str = ''
    _agg_func_list = entities.get('function_agg_list', None)
    print(_agg_func_list)
    if _agg_func_list:
        keys = list(_agg_func_list.keys())
        keys.sort()
        for e in keys:
            agg_func_list.append(_agg_func_list[e])
        print('functions', agg_func_list, len(agg_func_list))
        for i in range(len(agg_func_list)):
            func = agg_func_list[i]
            if not func.get('func', None):
                val = _get_value_from_context(agg_func_list, 'func', current_index=i)
                if val:
                    agg_func_list[i]['func'] = val
                else:
                    raise ParsingError('Not a valid agg_func name.')
            if not func.get('arg', None):
                val = _get_value_from_context(agg_func_list, 'arg', current_index=i)
                if val:
                    agg_func_list[i]['arg'] = '<<' + val + '>>'
                    columns.append(agg_func_list[i]['arg'])
                else:
                    raise ParsingError('Not a valid argument to agg_func.')
            else:
                columns.append(agg_func_list[i]['arg'])
                agg_func_list[i]['arg'] = '<<' + agg_func_list[i]['arg'] + '>>'

            if i < len(agg_func_list)-1:
                if not func.get('conn', None):
                    agg_func_list[i]['conn'] = '&'
            else:
                if func.get('conn', None):
                    del agg_func_list[i]['conn']

        print(agg_func_list)
        for agg_func in agg_func_list:
            agg_func_str += "(df['{arg}'] == df['{arg}'].{func}())".format(arg=agg_func['arg'], func=agg_func['func'])
            if agg_func.get('conn', None):
                agg_func_str += ' ' + connectors[agg_func['conn']]
    print(agg_func_str)
    columns = sorted(set(columns), key=columns.index) #removing duplicates while retaining original sequence
    return (agg_func_str, columns)

def get_conditions(entities, columns=[]):
    """
        composes SQL WHERE CONDITION from entities
    """
    condition_list = []
    print('InPut inside compose condition:', columns)
    #normalising expressions
    _exp_l = entities.get('expression_list', {})
    exp_l = []
    if _exp_l:
        keys = list(_exp_l.keys())
        keys.sort()
        for e in keys:
            exp_l.append(_exp_l[e])
        for i in range(len(exp_l)):
            exp = exp_l[i]
            if not exp.get('prop', None):
                val  = _get_value_from_context(exp_l, 'prop', current_index=i)
                if val:
                    exp_l[i]['prop'] = val
                else:
                    #parsing error
                    raise ParsingError('Not a valid expression...prop missing.')
            if not exp.get('operator', None):
                val = _get_value_from_context(exp_l, 'operator', current_index=i)
                if val:
                    exp_l[i]['operator'] = operators[val]
                else:
                    raise ParsingError('Not a valid expression...operator missing.')
            else:
                exp_l[i]['operator'] = operators[exp['operator']]
            if not exp.get('value', None):
                val = _get_value_from_context(exp_l, 'value', current_index=i)
                if val:
                    exp_l[i]['value'] = val
                else:
                    raise ParsingError('Not a valid expression...prop_value missing.')
            if i < len(exp_l)-1:
                if not exp.get('conn', None):
                    exp_l[i]['conn'] = '&'
            else:
                if exp.get('conn', None):
                    del exp_l[i]['conn']

        _exp = ''
        for i, exp in enumerate(exp_l):
            _exp += "(<<df>>['<<{prop}>>'] {operator} {value})".format(prop=exp['prop'], operator=exp['operator'], value=exp['value'])
            columns.append(exp['prop'])
            if exp.get('conn', None):
                _exp += ' ' + connectors[exp['conn']]
        condition_list.append(_exp)
        print(condition_list)

    brand = entities.get('brand')
    if brand:
        condition_list.append("(<<df>>['<<brand>>'] == '%s')"%brand)
        columns.append('brand')

    store_code = entities.get('store_code')
    if store_code:
        condition_list.append("(<<df>>['<<store_code>>'] == '%s')"%store_code)
        columns.append('store_code')

    city = entities.get('city')
    if city:
        condition_list.append("(<<df>>['<<city>>'] == '%s')"%city)
        columns.append('city')

    state = entities.get('state')
    if state:
        condition_list.append("(<<df>>['<<state>>'] == '%s')"%state)
        columns.append('state')

    style = entities.get('style')
    if style:
        condition_list.append("(<<df>>['<


from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals

from pysot.core.config import cfg
from pysot.tracker.siamrpn_tracker import SiamRPNTracker
from pysot.tracker.siamrpnlt_tracker import SiamRPNLTTracker
from mot_zj.MUST_utils import find_candidate_detection, calc_overlap_occlusion, motion_predict, find_detections_for_association
from mot_zj.MUST_utils import result_leverage, traj_interpolate
import cv2
import numpy as np
import os

class MUSTTracker(object):
    """
    The Wapper used to implenment SiamsRPN++ tracker and as the memory of other state variables
    """
    def __init__(self, model):
        ############################################################
        # define some overall variables for multi-objects tracking #
        ############################################################
        # SiamsRPN++ tracker and current states
        self.tracker = SiamRPNTracker(model)
        # self.tracker = SiamRPNLTTracker(model)
        # the state of current tracker
        self.track_state = cfg.STATE.START
        # the current tracking bbox
        self.track_bbox = np.array([])
        # frames when this tracker exists
        self.frames = []
        ############################################################
        # bboxes records when this tracker exists
        self.tracking_bboxes = np.array([])
        # state records when this tracker exists (state of each bbox)
        self.bboxes_state = []
        ############################################################
        # the number of frames that this tracker has tracked
        self.num_tracked = 0
        # the number of frames that this tracker has while tracking
        self.num_occluded = 0
        # bounding boxes overlap flag (judge the overlap state between)
        self.bb_overlaps = np.ones((10,))

    def init(self, img, bbox, id_num, frame, seq_name, asso_model):
        # check if the tracker is correctly created
        if self.track_state is not cfg.STATE.START:
            raise
        self.track_state = cfg.STATE.ACTIVATED
        self.id_num = id_num
        # save the tracked frame index
        self.frames.append(frame)
        # init the SiamRPN++ tracker (resnet50)
        self.tracker.init(img, bbox)
        if len(self.tracker.model.zf) > 1:
            self.template = [zf.clone().cpu() for zf in self.tracker.model.zf]
        else:
            self.template = self.tracker.model.zf.clone().cpu()
        self.track_bbox = bbox[np.newaxis, :]
        # init bbox ratio
        self.template_ratio = bbox[2]/bbox[3]

        # set the tracked frame number (the number is set to 1)
        self.num_tracked = 1
        # set the occluded frame number
        self.num_occluded = 0
        # save the tracking bboxes
        self.tracking_bboxes = self.track_bbox
        # save the state of tracking bboxes
        self.bboxes_state.append(self.track_state)
        # the name of sequence
        self.seq_name = seq_name
        # the association model
        self.asso_model = asso_model
        # the target can not be to small
        if bbox[2]*bbox[3] <= 1000 and self.seq_name in ['b2', 'b3', 'b4', 'b5']:
            self.track_state = cfg.STATE.STOP

        if bbox[2]*bbox[3] <= 1000 and bbox[1] > 200 and self.seq_name in ['b1']:
            self.track_state = cfg.STATE.STOP

    def track(self, img, bboxes_det, frame):
        # the tracking and activated state (in last frame the object is tracked)
        if self.track_state == cfg.STATE.TRACKED or self.track_state == cfg.STATE.ACTIVATED:
            # condition set (track or occlusion)
            self.num_tracked += 1
            self.num_occluded = 0
            ############################################
            #     *** tracking process start***        #
            ############################################
            # implement the SiamRPN++ tracker (resnet50)
            if len(self.template) > 1:
                self.tracker.model.zf = [zf.clone().cuda() for zf in self.template]
            else:
                self.tracker.model.zf = self.template.clone().cuda() # replace the tracker with its own template
            output = self.tracker.track(img)
            # append the tracking boxes
            result_bbox = np.array(output['bbox'])
            result_score = output['best_score']
            overlap_score = np.mean(self.bb_overlaps) # used to compare with overlap threshold
            # leverage the results between tracker and detections
            result_bbox = result_leverage(result_bbox, bboxes_det)
            # print("Tracker id {} Original score: {}".format(self.id_num, result_score))
            if result_score >= cfg.PARAMS.TRACKING_SCORE_THRESHOLD:
                if self.track_state == cfg.STATE.TRACKED and overlap_score > cfg.PARAMS.OVERLAP_THRESHOLD:
                    track_label = 1
                elif self.track_state == cfg.STATE.ACTIVATED:
                    track_label = 1
                else:
                    track_label = -1
            else:
                track_label = -1

            # the target can not be to small
            if result_bbox[2]*result_bbox[3] <= 1000 and self.seq_name in ['b2', 'b5']:
                track_label = -1

            # judge the state of tracker:
            if track_label > 0:
                if self.num_tracked > 0.25*30:
                    self.track_state = cfg.STATE.TRACKED
                else:
                    self.track_state = cfg.STATE.ACTIVATED
            else: # tracked -> lost, activated -> stop
                if self.track_state == cfg.STATE.ACTIVATED:
                    self.track_state = cfg.STATE.STOP
                    print("Target {} end.".format(self.id_num))
                else:
                    self.track_state = cfg.STATE.LOST

            # save the result as attribute
            if self.track_state == cfg.STATE.TRACKED or self.track_state == cfg.STATE.ACTIVATED:
                self.track_bbox = np.expand_dims(result_bbox, axis=0) # use new tracking result
                ratio = result_bbox[2]/result_bbox[3]
                change = ratio/self.template_ratio
                if np.maximum(change, 1/change) > 1.2:
                    # print("tracker template {} update.".format(self.id_num))
                    self.template_ratio = result_bbox[2]/result_bbox[3]
                    self.tracker.init(img,result_bbox)
                    if len(self.tracker.model.zf) > 1:
                        self.template = [zf.clone().cpu() for zf in self.tracker.model.zf]
                    else:
                        self.template = self.tracker.model.zf.clone().cpu()

                # find whether the track_bbox coincides with detection bbox
                # if the tracking score is confident, we can directly set it as solid result
                if not bboxes_det.size == 0:
                    ov, _ = calc_overlap_occlusion(self.track_bbox, bboxes_det)
                    self.bb_overlaps[:-1] = self.bb_overlaps[1:]
                    if np.max(ov) > 0.5:
                        self.bb_overlaps[-1] = 1
                    else:
                        self.bb_overlaps[-1] = 0
                else:
                    self.bb_overlaps[:-1] = self.bb_overlaps[1:]
                    self.bb_overlaps[-1] = 0
            else:
                pass # track_box will not change

            # if self.track_state == cfg.STATE.ACTIVATED and self.bb_overlaps[-1] == 0:
            #     self.track_state == cfg.STATE.STOP

            ############################################
            #      *** tracking process end***         #
            ############################################
            # judge the bbox out of the frame size or not (e.g. image.shape = (1920, 1080))
            frame_bbox = np.array([1, 1, img.shape[1], img.shape[0]])
            # calculate the occlusion ratio of the bbox with respect to frame size
            _, occ1 = calc_overlap_occlusion(self.track_bbox, frame_bbox)
            if occ1 < cfg.PARAMS.EXIT_THRESHOLD:
                print("The target exits from the camera view.")
                self.track_state = cfg.STATE.STOP
            # TODO: if not track the object, the state variable update or not ?
            # save relative variables
            self.bboxes_state.append(self.track_state)
            self.frames.append(frame)
            self.tracking_bboxes = np.concatenate((self.tracking_bboxes, self.track_bbox), axis=0)

        # the lost state
        elif self.track_state == cfg.STATE.LOST:
            self.num_occluded += 1
            # find a set of detections for association
            bboxes_asso = find_detections_for_association(self, bboxes_det, frame)
            # association prpcess
            if bboxes_asso.size == 0:
                asso_label = -1
            else:
                # association process
                ctrack = motion_predict(frame, self)
                # calculate predicted bbox
                width = self.tracking_bboxes[-1, 2]
                height = self.tracking_bboxes[-1, 3]
                x1 = ctrack[0] - (width - 1) / 2
                y1 = ctrack[1] - (height -1) / 2
                bbox_pred = np.array([x1, y1, width, height])

                o_predict, _ = calc_overlap_occlusion(bbox_pred, bboxes_asso)
                motion_score = np.max(o_predict)
                motion_ind = np.argmax(o_predict)
                # find the last tracked and activated frame index
                indices = []
                for ind, bbox_state in enumerate(self.bboxes_state):
                    if bbox_state == cfg.STATE.TRACKED or bbox_state == cfg.STATE.ACTIVATED:
                        indices.append(ind)
                # the last tracked frame of tracker
                fr_tracker = self.frames[indices[-1]]

                # use deep ReID model to associated tracklet and detections (not implement)
                prediction = self.asso_model(bboxes_asso, self.seq_name, frame, self.id_num)
                # in the following results,
                ass_score = np.max(prediction)
                asso_ind = np.argmax(prediction)

                if ass_score > cfg.PARAMS.ASSOCIATION_SCORE_THRESHOLD:
                    asso_label = 1
                    bboxes_det_one = bboxes_asso[asso_ind, :]
                    # print("Target {} associated by appearance with score {}.".format(self.id_num, ass_score))

                elif frame - fr_tracker < 5 and ass_score > 0.4 and motion_score > 0.5:
                    asso_label = 1
                    bboxes_det_one = bboxes_asso[motion_ind, :]
                    # print("Target {} associated by motion.".format(self.id_num))
                else:
                    asso_label = -1

                # update the parameters when asso_label is equal to 1
                if asso_label == 1:
                    # change the parameters
                    center_x = bboxes_det_one[0] + (bboxes_det_one[2]-1)/2
                    center_y = bboxes_det_one[1] + (bboxes_det_one[3]-1)/2
                    w = bboxes_det_one[2]
                    h = bboxes_det_one[3]
                    self.tracker.center_pos = np.array([center_x, center_y])
                    self.tracker.size = np.array([w, h])
                    if len(self.template) > 1:
                        self.tracker.model.zf = [zf.clone().cuda() for zf in self.template] # replace the tracker with its own template
                    else:
                        self.tracker.model.zf = self.template.clone().cuda()
                    output = self.tracker.track(img)
                    # append the tracking boxes
                    result_bbox = np.array(output['bbox'])
                    result_score = output['best_score']
                    # print("Tracker id {} Modified score: {}".format(self.id_num, result_score))
                    # leverage between tracking and detection
                    ratio = result_bbox[2]/result_bbox[3]
                    change = ratio/self.template_ratio
                    if np.maximum(change, 1/change) > 1.2:
                        print("tracker template {} update.".format(self.id_num))
                        self.template_ratio = result_bbox[2]/result_bbox[3]
                        self.tracker.init(img,result_bbox)
                        if len(self.tracker.model.zf) > 1:
                            self.template = [zf.clone().cpu() for zf in self.tracker.model.zf]
                        else:
                            self.template = self.tracker.model.zf.clone().cpu()
                    if not result_score > 0.7:
                        result_bbox = result_leverage(result_bbox, bboxes_det)

            if asso_label > 0:

                if self.num_tracked > 0.25 * 30:
                    self.track_state = cfg.STATE.TRACKED
                else:
                    self.track_state = cfg.STATE.ACTIVATED

                self.track_bbox = np.expand_dims(result_bbox, axis=0)
                self.bboxes_state.append(self.track_state)
                self.tracking_bboxes = np.concatenate((self.tracking_bboxes, self.track_bbox), axis=0)
                self.frames.append(frame)

                # if self.frames[-1] == frame:
                #     # remove the last item of bbox
                #     self.tracking_bboxes = self.tracking_bboxes[:-1, :]
                #     self.frames = self.frames[:-1]
                #     self.bboxes_state = self.bboxes_state[:-1]
                # try to interpolation the tracklet
                # traj_interpolate(self, result_bbox, frame, 30)

                if not bboxes_det.size == 0:
                    ov, _ = calc_overlap_occlusion(self.track_bbox, bboxes_det)
                    self.bb_overlaps[:-1] = self.bb_overlaps[1:]
                    if np.max(ov) > 0.5:
                        self.bb_overlaps[-1] = 1
                    else:
                        self.bb_overlaps[-1] = 0
                # elif result_score > 0.7:
                #     self.bb_overlaps[:-1] = self.bb_overlaps[1:]
                #     self.bb_overlaps[-1] = 1
                else:
                    self.bb_overlaps[:-1] = self.bb_overlaps[1:]
                    self.bb_overlaps[-1] = 0
            else:
                self.track_state = cfg.STATE.LOST
                self.bboxes_state[-1] = self.track_state
                # else:
                #     self.bboxes_state.append(self.track_state)
                #     self.frames.append(frame)
                #     # TODO: think of mechanism
                #     self.tracking_bboxes = np.concatenate((self.tracking_bboxes, np.expand_dims(self.tracking_bboxes[-1, :], axis=0)), axis=0)

            # finish association
            if self.track_state == cfg.STATE.TRACKED or self.track_state == cfg.STATE.ACTIVATED:
                self.num_occluded = 0

            # terminate if lost for a long time
            if self.num_occluded > cfg.PARAMS.TERMINATION_THRESHOLD * 30:
                self.track_state = cfg.STATE.STOP
                print("target {} exits due to long time occlusion".format(self.id_num))

           # judge the bbox out of the frame size or not (e.g. image.shape = (1920, 1080))
            frame_bbox = np.array([1, 1, img.shape[1], img.shape[0]])
            # calculate the occlusion ratio of the bbox with respect to frame size
            _, occ1 = calc_overlap_occlusion(self.track_bbox, frame_bbox)
            if occ1 < cfg.PARAMS.EXIT_THRESHOLD:
                print("target outside image by checking boarders.")
                tracker.track_state = cfg.STATE.STOP

    def results_return(self):
        results_bbox = self.tracking_bboxes
        results_frame = np.array(self.frames)
        results_ids = self.id_num * np.ones_like(results_frame)
        results_state = np.array(self.bboxes_state)
        results = np.hstack((results_frame[np.newaxis, :].T, results_ids[np.newaxis, :].T, results_bbox))
        num_results = results.shape[0]
        img_path = os.path.join(os.path.join("pysot","img_traj"), self.seq_name, str(self.id_num))
        if os.path.exists(img_path):
            img_num = len(os.listdir(img_path))
        else:
            img_num = 0
        if num_results >= 8 and img_num >=8:
            indices = []
            for ii, res_state in enumerate(results_state):
                if res_state == cfg.STATE.TRACKED or res_state == cfg.STATE.ACTIVATED:
                    indices.append(ii)
            results = results[indices]
        else:
            results = np.array([])
        return results


# -*- coding: utf-8 -*-
from zerotk.zops import call_main, Console

import click

click.disable_unicode_literals_warning = True

@click.group('code-standards')
def main():
    pass

@main.command()
@click.argument('paths', nargs=-1)
@click.pass_context
def apply(ctx, paths):
    Console.title('zops code-standards apply')
    for i_path in paths:
        ctx.invoke(isort, path=i_path)
        ctx.invoke(autoflake, path=i_path)
        ctx.invoke(autopep8, path=i_path)

@main.command()
@click.argument('path')
def isort(path):
    import os
    from isort.main import main as isort_main

    Console.title('zops code-standards isort')
    isort_args = [
        #'--verbose',
        '-m3',
        '-l120',
        #'--order-by-type',
        #'--combine-as',
        #'--force-alphabetical-sort-within-sections',
        #'--force-alphabetical-sort',
        #'--force-sort-within-sections',
        #'--lines-between-types=1',
        #'--atomic',
        #'-y',
        path,
    ]
    if os.path.isdir(path):
        isort_args.insert(0, '--recursive')
    Console.execution('isort', *isort_args)
    call_main(isort_main, *isort_args)

@main.command()
@click.argument('path')
def autoflake(path):
    import os
    from autoflake import main as autoflake_main

    Console.title('zops code-standards autoflake')
    autoflake_args = [
        '-i',
        '--remove-all-unused-imports',
        path
    ]
    if os.path.isdir(path):
        autoflake_args.insert(0, '--recursive')
    Console.execution('autoflake', *autoflake_args)
    call_main(autoflake_main, *autoflake_args)

@main.command()
@click.argument('path')
def autopep8(path):
    import os
    from autopep8 import main as autopep8_main

    Console.title('zops code-standards autopep8')
    autopep8_args = [
        '-a',
        '-i',
        '--max-line-length=120',
        path
    ]
    if os.path.isdir(path):
        autopep8_args.insert(0, '--recursive')
    Console.execution('autopep8', *autopep8_args)
    call_main(autopep8_main, *autopep8_args)


import random, math

def binary_search(numbers, look):
    """Binary Search algorithm"""

    # Split at the start
    start = 0 # Start is beginning
    mid = len(numbers) // 2 # the middle
    end = len(numbers) - 1 # end
    found = -2 # temp not found

    # is it empty?
    if not numbers:
        return -1

    def check_val(_start, _mid, _end):
        """Checks if the value is equal"""
        if numbers[_start] == look: # is the start found?
            return _start
        elif numbers[_end] == look: # is the end found?
            return _end
        elif numbers[_mid] == look: # is the middle found?
            return _mid
        elif _mid == _end or _mid == _start: # Is there no middle?
            return -1
        else:
            return -2 # Nothing found

    while 1: # Start looping
        found = check_val(start, mid, end) # do the check
        if found > -2: # is the value finally found
            break

        # Split the list.
        if numbers[mid] > look: # Split from the start, to middle. [left]
            end = mid # Set end to middle
            mid = int(end / 2) # Find the new middle
        else:
            start = mid # Set start to middle
            mid = int(start + ((end - mid) / 2)) # Find the new middle

    return found # final answer

# TEST CASES

# Find value in a decent sized list, looking for 7
nums = sorted([random.randint(1, 10) for n in range(20)])
print(nums, binary_search(nums, 7))

# Find value in an empty list, should not find
nums = []
print(nums, binary_search(nums, 1))

# Finding 1 in a very small list.
nums = [1]
print(nums, binary_search(nums, 1))

# Find a value at the end of a size 2 array.
nums = [1, 10]
print(nums, binary_search(nums, 10))

# Find exact center value.
nums = [1, 4, 10]
print(nums, binary_search(nums, 4))

# Find value in a decent sized list, looking for 7
nums = sorted([random.randint(1, 20) for n in range(100)])
print(nums, binary_search(nums, 7))


import urllib.request
import csv
import sys
import io
import pandas as pd
from functools import reduce

url = "https://data.cityofnewyork.us/Public-Safety/FDNY-Line-Of-Duty-Deaths/32y8-s55cs/data.csv" \
    "?accessType=DOWNLOAD"

try:
    fileFromUrl = urllib.request.urlopen(url)
except urllib.error.URLError as error:
    print("urllib.error.URLError", error)
    sys.exit(1)

sequenceOfBytes = fileFromUrl.read() #Read whole file into one big sequenceOfBytes.
fileFromUrl.close()

try:
    s = sequenceOfBytes.decode("utf-8")    #s is a string
except UnicodeError as unicodeError:
    print(unicodeError)
    sys.exit(1)

fileFromString = io.StringIO(s)
df = pd.read_csv(fileFromString, dtype = {'str'})  #reads in fileFromString as DataFrame
fileFromString.close()

deaths=[
    "Rank",
    "Name",
    "Unit",
    "Date"
    ]

deaths.drop(columns=deaths, inplace=True)

print("FDNY NY DEATHS")
print()
print("Rank")
print()
print("Name")
print()
print("Unit")
print()
print("Date")

sys.exit(0)


import numpy as np
from numpy.testing import assert_array_equal
import pytest

from tompy.core import argsort_like, rankdata

def test_argsort_like():
    # confirm sorting
    a = np.random.randint(0, 100, 42)
    b = a[np.random.permutation(len(a))]

    assert_array_equal(a[argsort_like(a, b)], b)

    # confirm raising value error if different number of elements
    with pytest.raises(ValueError):
        argsort_like(a, b[1:])

    # confirm raising value error if different elements
    b[0] = -1  # impossible value
    with pytest.raises(ValueError):
        argsort_like(a, b)

def test_rankdata():
    # check vectors
    a = [0.5, 0.2, 4, -3]
    target = [2, 1, 3, 0]
    assert_array_equal(rankdata(a), target)

    # check matrices without axis definition
    a = [[0.5, 0.2, 4, -3], [2, 6, 1, 5]]
    target = [[2, 1, 3, 0], [1, 3, 0, 2]]
    assert_array_equal(rankdata(a), target)

    # check matrices with axis=1 (same as above)
    assert_array_equal(rankdata(a, axis=1), target)

    # check matrices with axis=0
    a = [[0.5, 0.2, 4, -3], [2, 6, 1, 5], [-3, 5, 2, 0]]
    target = [[1, 0, 2, 0], [2, 2, 0, 2], [0, 1, 1, 1]]
    assert_array_equal(rankdata(a, axis=0), target)

    # check matrices with axis=None
    target = [4,  3,  8,  0,  6, 11,  5,  9,  1, 10,  7,  2]
    assert_array_equal(rankdata(a, axis=None), target)


test_string = "(([])){}{}[]"
# test_string = "(([]))"

def isValid(self, s: str) -> bool:
	# Python EZ-Stack:
	# Just use List with append(), pop() // both run in O(1) time

	if len(s) % 2 != 0:
		return False

	stackerooni = []

	for char in s:
		# If opening character, push it onto stack
		if char == '(' or char == '{' or char == '[':
			stackerooni.append(char)

		# If closing character but there's nothing on the stack, invalid
		elif (char == ']' or char == '}' or char == ')') and len(stackerooni) == 0:
			return False

		# If closing character and matching opening char is ontop of stack, proceed
		elif char == ')' and stackerooni[-1] == '(' or \
			 char == '}' and stackerooni[-1] == '{' or \
			 char == ']' and stackerooni[-1] == '[':
			stackerooni.pop()
		else:
			return False

	# If youve gotten through all characters and nothing left in stack, string is valid!
	if len(stackerooni) == 0:
		return True
	else:
		return False

print(isValid(test_string))


import matplotlib.pyplot as plt
import numpy as np
import math
import os

class Surfaces_math_functions:

    def __init__(self, X_MIN, X_MAX, Y_MIN, Y_MAX, COFF, OFFSET, equation_name):
        self.X_MIN = X_MIN
        self.X_MAX = X_MAX
        self.Y_MIN = Y_MIN
        self.Y_MAX = Y_MAX
        self.COFF = COFF
        self.OFFSET = OFFSET
        self.equation_name = equation_name
        self.equation = self.__get_equation(equation_name)

    # ---- Private methods ----

    # Private getters
    def __get_equation(self, string):
        string = string.lower()
        equation_table = {
            'paraboloide hiperbolico' or 'silla de montura':
                [
                    lambda x, y: ((y**2)/5 - (x**2)/3) * self.COFF,
                    "y^2/5 - x^2/3"
                ],
            'seno' or 'sin':
                [
                    lambda x, y: (np.sin(x+y)) * self.COFF,
                    "sin(x+y)"
                ],
            'coseno' or 'cos':
                [
                    lambda x, y: (np.cos(x+y)) * self.COFF,
                    "cos(x+y)"
                ],
            'tangente' or 'tan':
                [
                    lambda x, y: (np.tan(x+y)) * self.COFF,
                    "tan(x+y)"
                ],
            'exponencial' or 'exp':
                [
                    lambda x, y: (np.exp(x+y)) * self.COFF,
                    "e^(x+y)"
                ],
            'logaritmo' or 'log':
                [
                    lambda x, y: (np.log(x**2+y**2+1)) * self.COFF,
                    "log(x^2+y^2+1)"
                ],
            'raiz cuadrada' or 'sqrt':
                [
                    lambda x, y: (np.sqrt(x**2+y**2)) * self.COFF,
                    "sqrt(x^2+y^2)"
                ],
            'seno hiperbolico' or 'sinh':
                [
                    lambda x, y: (np.sinh(x+y)) * self.COFF,
                    "sinh(x+y)"
                ],
            'coseno hiperbolico' or 'coseno hiperbolico' or 'cosh':
                [
                    lambda x, y: (np.cosh(x+y)) * self.COFF,
                    "cosh(x+y)"
                ],
            'superficie 1' or 's1':
                [
                    lambda x, y: ((1-x/2+x**5+y**3) *
                                  np.exp(-x**2-y**2)) * self.COFF,
                    "(1-x/2+x^5+y^3) * e^(-x^2-y^2)"
                ],
            'superficie 2' or 's2':
                [
                    lambda x, y: ((x**2+y**2)*np.exp(-x**2-y**2)) * self.COFF,
                    "(x^2+y^2) * e^(-x^2-y^2)"
                ],
            'superficie 3' or 's3':
                [
                    lambda x, y: ((x**2+y**2)/(x**2+y**4)) * self.COFF,
                    "(x^2+y^2)/(x^2+y^4)"
                ],
            'superficie 4' or 's4':
                [
                    lambda x, y: ((x**2*y)/(x**2+y**4)) * self.COFF,
                    "(x^2*y)/(x^2+y^4)"
                ],
            'superficie 5' or 's5':
                [
                    lambda x, y: ((x**2*y**2)/(x**2+y**4)) * self.COFF,
                    "(x^2*y^2)/(x^2+y^4)"
                ],
        }

        return equation_table[string]

    def __get_surface_image(self):
        x = np.arange(self.X_MIN, self.X_MAX, 0.6)
        y = np.arange(self.Y_MIN, self.Y_MAX, 0.6)
        X, Y = np.meshgrid(x, y)
        Z = self.equation[0](X, Y)
        # reshaped_Z = np.reshape(Z, (len(x), len(y)))
        return X, Y, Z

    # ---- Public methods ----

    # Public getters

    def get_plot_data(self):
        X, Y, Z = self.__get_surface_image()
        return X, Y, Z

    def get_equation_function(self):
        return self.equation[0]

    def get_cartesian_equation_str(self):
        return self.equation[1]

class Fan_mapping:

    def __init__(self, QTY_FAN, V_FAN, I_FAN, surface_eq):
        self.QTY_FAN = QTY_FAN
        self.ROWS_FAN, self.COLS_FAN = self.__get_row_col()
        self.V_FAN = V_FAN
        self.I_FAN = I_FAN
        self.surface_eq = surface_eq

    # ---- Private methods ----

    # Create a matrix given the fan's quantity
    def __fan_to_grid(self):
        # 1.01 to avoid 0 (common discontinuity)
        _x = np.arange(-self.ROWS_FAN/2, self.ROWS_FAN/2, 1.01)
        # 1.01 to avoid 0 (common discontinuity)
        _y = np.arange(-self.COLS_FAN/2, self.COLS_FAN/2, 1.01)
        _xx, _yy = np.meshgrid(_x, _y)
        X, Y = _xx.ravel(), _yy.ravel()
        return X, Y

    # Private getters
    def __get_row_col(self):
        rows = math.ceil(math.sqrt(self.QTY_FAN))
        cols = math.ceil(self.QTY_FAN / rows)
        return rows, cols

    def __get_voltage_point(self, X, Y):

        voltage = self.surface_eq.get_equation_function()(X, Y)

        # Normalize values
        self.max_value = np.amax(voltage)
        self.min_value = np.amin(voltage)
        self.mean_value = np.mean(voltage)
        voltage = (voltage - self.min_value) / \
            (self.max_value - self.min_value)
        return voltage * self.V_FAN

    def __get_voltage_map(self):
        X, Y = self.__fan_to_grid()
        Z = self.__get_voltage_point(X, Y)
        self.max_value = round(np.max(Z), 2)
        self.min_value = round(np.min(Z), 2)
        self.mean_value = round(np.mean(Z), 2)
        self.power_consumption = round(np.sum(Z * self.I_FAN), 2)
        return X, Y, Z

    # ---- Public methods ----

    # Public getters

    def get_max_value(self):
        return self.max_value

    def get_min_value(self):
        return self.min_value

    def get_mean_value(self):
        return self.mean_value

    def get_power_consumption(self):
        return self.power_consumption

    def get_plot_data(self):
        X, Y, Z = self.__get_voltage_map()
        return X, Y, Z

    def get_row_col(self):
        return self.ROWS_FAN, self.COLS_FAN

def input_data():

    # TODO Check if the limits are correct

    qty_fan = int(input("¿Cuantos ventiladores hay disponibles? "))
    if qty_fan <= 1:
        raise ValueError("La cantidad de ventiladores debe ser mayor a 0")

    v_fan = float(input("¿Cuál es la tension nominal de los ventiladores? "))
    if v_fan <= 1:
        raise ValueError("La tension de los ventiladores debe ser mayor a 0")

    i_fan = float(input("¿Cuál es la corriente nominal de los ventiladores? "))
    if i_fan <= 0:
        raise ValueError("La corriente de los ventiladores debe ser mayor a 0")

    return qty_fan, v_fan, i_fan

def main():

    # ---- General parameters ----
    eq_available = ["paraboloide hiperbolico",
                    # "superficie 1",
                    # "superficie 2",
                    # "superficie 3",
                    # "superficie 4",
                    # "superficie 5",
                    # "seno",
                    # "coseno",
                    # "tangente",
                    # "exponencial",AAAz

                    # "logaritmo",
                    # "raiz cuadrada",
                    # "seno hiperbolico",
                    # "coseno hiperbolico"
                    ]

    X_MIN = -3
    X_MAX = 3
    Y_MIN = -3
    Y_MAX = 3
    COFF = 1
    OFFSET = 0

    # ---- Input data ----
    qty_fan, v_fan, i_fan = input_data()
    # qty_fan, v_fan, i_fan = 50, 12, 0.3

    # ---- Folder creation ----
    folder_name = "./" + str(qty_fan) + " ventiladores"
    if not os.path.exists(folder_name):

        os.makedirs(folder_name)

    # General parameters log
    with open(folder_name + "/parametros.txt", "w") as f:
        f.write("Cantidad de ventiladores: " + str(qty_fan) + "\n")
        f.write("Tension nominal de los ventiladores: " + str(v_fan) + "\n")
        f.write("Corriente nominal de los ventiladores: " + str(i_fan) + "\n")
        f.write("X_MIN: " + str(X_MIN) + "\n")
        f.write("X_MAX: " + str(X_MAX) + "\n")
        f.write("Y_MIN: " + str(Y_MIN) + "\n")
        f.write("Y_MAX: " + str(Y_MAX) + "\n")
        f.write("COFF: " + str(COFF) + "\n")
        f.write("OFFSET: " + str(OFFSET) + "\n")

    figs_pairs = []
    for i in range(len(eq_available)):
        figs_pairs.append(plt.figure(figsize=(8, 4)))
        figs_pairs[i].suptitle(eq_available[i], fontsize=12)
        figs_pairs[i].subplots_adjust(hspace=0.5)
        figs_pairs[i].subplots_adjust(wspace=0.5)
        figs_pairs[i].subplots_adjust(
            left=0.11, right=0.85, top=0.9, bottom=0.3)

    # Generate plot for each surface-fan_voltage_map pair
    for i, eq_str in enumerate(eq_available):

        # Instantiate surface equation
        surface_eq = Surfaces_math_functions(
            X_MIN, X_MAX, Y_MIN, Y_MAX, COFF, OFFSET, eq_str)

        # Instantiate fan_voltage_map
        fan_map = Fan_mapping(QTY_FAN=qty_fan, V_FAN=v_fan,
                              I_FAN=i_fan, surface_eq=surface_eq)

        # Surface plot data
        x_s, y_s, z_s = surface_eq.get_plot_data()
        # Voltage map data
        x_f, y_f, z_f = fan_map.get_plot_data()

        # Plot surface
        surface_plot = figs_pairs[i].add_subplot(1, 2, 1, projection='3d')
        surface_plot.plot_surface(
            x_s, y_s, z_s, rstride=1, cstride=1, cmap='inferno', edgecolor='none')
        surface_plot.set_title(
            "f(x,y)= " + surface_eq.get_cartesian_equation_str())
        surface_plot.set_xlabel("X")
        surface_plot.set_ylabel("Y")
        surface_plot.set_zlabel("Z")
        surface_plot.set_xlim3d(X_MIN, X_MAX)
        surface_plot.set_ylim3d(Y_MIN, Y_MAX)

        # Plot fan voltage map
        fan_plot = figs_pairs[i].add_subplot(1, 2, 2, projection='3d')
        fan_plot.bar3d(x_f, y_f, 0, 1, 1, z_f, shade=True, color='red')
        fan_plot.set_title("Mapa de ventiladores")
        fan_plot.set_xlabel("X")
        fan_plot.set_ylabel("Y")
        fan_plot.set_zlabel("Z")
        fan_plot.set_xlim3d(-fan_map.ROWS_FAN/2, fan_map.ROWS_FAN/2)
        fan_plot.set_ylim3d(-fan_map.COLS_FAN/2, fan_map.COLS_FAN/2)
        fan_plot.set_zlim3d(0, fan_map.V_FAN)

        #Labels (V_max, V_min, P_total)
        figs_pairs[i].text(0.3, 0.15, "V_max: " + str(fan_map.get_max_value()) +
                           " V", ha='center', va='center', transform=figs_pairs[i].transFigure)
        figs_pairs[i].text(0.5, 0.15, "V_min: " + str(fan_map.get_min_value()) +
                           " V", ha='center', va='center', transform=figs_pairs[i].transFigure)
        figs_pairs[i].text(0.7, 0.15, "V_mean: " + str(fan_map.get_mean_value()) +
                           " V", ha='center', va='center', transform=figs_pairs[i].transFigure)
        figs_pairs[i].text(0.5, 0.05, "P_total: " + str(fan_map.get_power_consumption()) +
                           " W", ha='center', va='center', transform=figs_pairs[i].transFigure)

        # Save figure
        figs_pairs[i].savefig(folder_name + "/" + eq_str + ".png")

        print("x_f: " + str(x_f))
        print("y_f: " + str(y_f))
        print("z_f: " + str(z_f))

        #Write in file the fan_voltage_map as lookup table (for the Arduino)
        with open(folder_name + "/" + eq_str + ".txt", "w") as f:
            rows,cols = fan_map.get_row_col()
            f.write("const static float fan_voltage_map[" + str(rows) + "][" + str(cols) + "] = {")
            # for i in range(rows):
            #     for j in range(cols):
            #         f.write(str(fan_map.get_value(i,j)) + ",")
            #     f.write("\n")
            f.write("};")

    plt.show()
    plt.close()

if __name__ == '__main__':
    main()


from django.conf.urls import url, include
from django.views.generic import TemplateView
from . import django_urls

from allauth.socialaccount.providers.facebook.views import FacebookOAuth2Adapter
from allauth.socialaccount.providers.twitter.views import TwitterOAuthAdapter

from rest_framework.decorators import api_view

from rest_auth.urls import urlpatterns
from rest_auth.registration.views import SocialLoginView
from rest_auth.social_serializers import TwitterLoginSerializer

class FacebookLogin(SocialLoginView):
    adapter_class = FacebookOAuth2Adapter

class TwitterLogin(SocialLoginView):
    adapter_class = TwitterOAuthAdapter
    serializer_class = TwitterLoginSerializer

class TwitterLoginSerializerFoo(TwitterLoginSerializer):
    pass

@api_view(['POST'])
def twitter_login_view(request):
    serializer = TwitterLoginSerializerFoo(
        data={'access_token': '11223344', 'token_secret': '55667788'},
        context={'request': request}
    )
    serializer.is_valid(raise_exception=True)

class TwitterLoginNoAdapter(SocialLoginView):
    serializer_class = TwitterLoginSerializer

urlpatterns += [
    url(r'^rest-registration/', include('rest_auth.registration.urls')),
    url(r'^test-admin/', include(django_urls)),
    url(r'^account-email-verification-sent/$', TemplateView.as_view(),
        name='account_email_verification_sent'),
    url(r'^account-confirm-email/(?P<key>[-:\w]+)/$', TemplateView.as_view(),
        name='account_confirm_email'),
    url(r'^social-login/facebook/$', FacebookLogin.as_view(), name='fb_login'),
    url(r'^social-login/twitter/$', TwitterLogin.as_view(), name='tw_login'),
    url(r'^social-login/twitter-no-view/$', twitter_login_view, name='tw_login_no_view'),
    url(r'^social-login/twitter-no-adapter/$', TwitterLoginNoAdapter.as_view(), name='tw_login_no_adapter'),
    url(r'^accounts/', include('allauth.socialaccount.urls'))
]


#day42

from selenium import webdriver

# Inicialize o driver do navegador
driver = webdriver.Chrome()

# Acesse o site de música
driver.get("https://www.youtube.com/")

# Localize a caixa de pesquisa no site
search_box = driver.find_element_by_xpath('//input[@id="search"]')

# Digite a música que você deseja reproduzir
search_box.send_keys("music name")
search_box.submit()

# Localize o primeiro vídeo na lista de resultados de pesquisa
video = driver.find_element_by_xpath('//a[@id="video-title"]')

# Clique no vídeo para reproduzí-lo
video.click()


#
#   sprite sheet to c64 sprite converter
#   (c)2020 by awsm of Mayday!
#   http://www.awsm.de
#
#   converts a bitmap with a spritesheet
#   into a sprite data binary
#
#
#   usage:
#   spritesheet_to_spd(input_file,output_file, sprite_width, sprite_height)
#   input_file: name of the PNG image. Image must be (24*X)*(21*X) pixels
#   output_file: name of the sprite file (usually ends with .spd)
#   sprite_width: usually 24, which is the width of a hires C64 sprite
#   sprite_height: usually 21, which is the height of a hires C64 sprite
#
#   example:
#   spritesheet_to_spd("spritesheet.png","sprites.spd", 24, 21)
#   loads a PNG file called "spritesheet.png" and exports it
#   as "sprites.spd" in C64 SpritePad format
#

from PIL import Image
import math

def get_sprites(image_path,x,y):
    i = Image.open(image_path, 'r')
    i.pixels = list(i.getdata())
    i.x, i.y = i.size
    i.col = i.x / x
    i.row = i.y / y
    i.total = int(i.row * i.col)
    i.sprite_width = x
    i.sprite_height = y
    return i

def convert_sprite(sprites,number):
    sprite_length = sprites.sprite_width * sprites.sprite_height
    row = int(math.ceil(number / sprites.col)) -1
    row_offset = row * (sprite_length * sprites.col)
    col = number - row*sprites.col -1
    col_offset = col * sprites.sprite_width
    start = int(row_offset + col_offset)
    end = int(start + sprite_length)

    line = 0
    pixel_count = 0
    bit_array = []

    for i in range(start,end):
        pixel_count = pixel_count + 1

        pixel_pos = i + line
        pixel = sprites.pixels[pixel_pos]

        if pixel == 0:
            print(" ", end='')
            bit_array.append(0)
        else:
            print("#", end='')
            bit_array.append(1)

        if pixel_count == sprites.sprite_width:
            print()
            pixel_count = 0
            line = line + sprites.x -sprites.sprite_width
    return bit_array

def bits_to_bytes(data):
    byte_counter = 0
    byte = ""
    bytes_array = []

    for pixel in data:
        byte = byte + str(pixel)

        if byte_counter == 7:
            byte_counter = 0
            hex_number = int(byte,2)
            bytes_array.append(hex_number)
            byte = ""
        else:
            byte_counter = byte_counter + 1
    bytes_array.append(1)
    return bytes_array

def write_file(filename, data):
    if not filename:
        filename = "test"

    newFile = open(filename, "wb")
    file_array = [11,8,6]
    file_array = file_array + data
    newFileByteArray = bytearray(file_array)
    newFile.write(newFileByteArray)

def png_to_spd(input_filename, output_filename, sprite_width, sprite_height ):
    image = get_sprites(input_filename, sprite_width,sprite_height)

    all_sprites = []

    for i in range(1,image.total+1):
        sprite_data = convert_sprite(image,i)
        sprite_bytes = bits_to_bytes(sprite_data)
        all_sprites = all_sprites + sprite_bytes

    write_file(output_filename,all_sprites)

#-----------------------------------------------------------------

png_to_spd("test.png","test2.spd", 24, 21)


#8/13/18
#cnn classification

#neural network transforms an input by putting it through a series of hidden layers
#layers made-up of neurons-connected neurons to neurons

#cnn-layers built in 3 dimensions (width,height,depth)
#for cnn, neurons in one layer don't connect to all neurons in the next layer (only a small fraction of other neurons)
#cnn-i.hidden layers/feature extraction ii. classification (probability)
import numpy as np
from keras.layers import Conv2D, Activation, MaxPool2D, Flatten, Dense
from keras.models import Sequential

#filter/kernels produce a feature map
#relu-to make the output non-linear
#stide-the size of the step that the convolutional filter moves each time (filter slides pixel by pixel)

#feed the image into the model (512 x 512 pixels with 3 channels)
img_shape=(28,28,1)

#hidden layers/feature extraction
model=Sequential()
#add a convolutional layer with 3x3 by 3 filters and a stride of one
#set padding so that the input size equals the output size
model.add(Conv2D(6,2,input_shape=img_shape))
#add a relu activation to the layer
model.add(Activation('relu'))
#Pooling
model.add(MaxPool2D(2))

#fully connected layers
#use flatten to convert 3d to 1d
model.add(Flatten())
#add dense layer with ten neurons
model.add(Dense(10))
#using the softmax activation function for the last layer
model.add(Activation('softmax'))
#model summary
model.summary

#classification (optimizer, loss, and metrics)
from keras.datasets import mnist

(x_train,y_train),(x_test,y_test)=mnist.load_data()
x_train=np.expand_dims(x_train,-1)
x_test=np.expand_dims(x_test,-1)

model.compile(loss='sparse_categorical_crossentropy',optimizer='adam',
metrics=['acc'])

#train the model, iterating on the data in batches of 32 samples with 5 epochs
model.fit(x_train, y_train, batch_size=32, epochs=5, validation_data=(x_test,y_test))


#! /usr/bin/env python

from __future__ import print_function
import sys
import rospy
# import topics_lister.srv import *
from topics_lister.srv import FetchTopics, FetchTopicsRequest, FetchTopicsResponse

rospy.init_node('topics_client')

def topics():
    rospy.wait_for_service('fetch_topics')
    try:
        fetch_topics = rospy.ServiceProxy('fetch_topics', FetchTopics)
        print(fetch_topics)
        response = fetch_topics()
        # service.call('sendTopics')
        return response.topics
    except rospy.ServiceException as ex:
        print("Service call exception: %s"%ex)

if __name__ == "__main__":
    topics()


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

import arcade
import arcade.gui

from twisted.internet import reactor

from game import FONT, FONT_THIN
from game import app

class MenuView(arcade.View):

    def __init__(self):
        super().__init__()

        # --- Required for all code that uses UI element,
        # a UIManager to handle the UI.
        self.manager = arcade.gui.UIManager()

        # Create a vertical BoxGroup to align buttons
        self.v_box = arcade.gui.UIBoxLayout()

        ui_text_label = arcade.gui.UITextArea(text="Menu",
                                              width=450,
                                              height=100,
                                              font_size=50,
                                              font_name="Kenney Future")
        self.v_box.add(ui_text_label.with_space_around(bottom=20))

        # Create the buttons
        start_button = arcade.gui.UIFlatButton(text="Start Game", width=200, style={'font_name': FONT})
        self.v_box.add(start_button.with_space_around(bottom=20))

        settings_button = arcade.gui.UIFlatButton(text="Settings", width=200, style={'font_name': FONT})
        self.v_box.add(settings_button.with_space_around(bottom=20))

        quit_button = arcade.gui.UIFlatButton(text="Quit", width=200, style={'font_name': FONT})
        self.v_box.add(quit_button.with_space_around(bottom=20))

        @start_button.event("on_click")
        def on_click_start(event):
            print("Start:", event)
            self.window.set_state(app.ArcadeState.ready)

        @settings_button.event("on_click")
        def on_click_settings(event):
            print("Settings:", event)
            self.window.set_state(app.ArcadeState.settings)

        @quit_button.event("on_click")
        def on_click_quit(event):
            print("quit:", event)
            arcade.exit()
            reactor.callFromThread(reactor.stop)

        # Create a widget to hold the v_box widget, that will center the buttons
        self.manager.add(
            arcade.gui.UIAnchorWidget(
                anchor_x="center_x",
                anchor_y="center_y",
                child=self.v_box)
        )

    def on_show_view(self):
        self.manager.enable()
        arcade.set_background_color(arcade.csscolor.CHOCOLATE)
        arcade.set_viewport(0, self.window.width, 0, self.window.height)

    def on_hide_view(self):
        self.manager.disable()

    def on_draw(self):
        self.clear()
        self.manager.draw()


from __future__ import print_function, unicode_literals
import hashlib
from tqdm import tqdm
from twisted.internet.defer import inlineCallbacks
from twisted.protocols import basic
from ..errors import TransferError
from ..util import bytes_to_dict, bytes_to_hexstr

@inlineCallbacks
def send_file(transit_sender, fd_to_send, timing, stderr, hide_progress):
    ts = transit_sender

    fd_to_send.seek(0, 2)
    filesize = fd_to_send.tell()
    fd_to_send.seek(0, 0)

    record_pipe = yield ts.connect()
    timing.add("transit connected")
    # record_pipe should implement IConsumer, chunks are just records
    print(u"Sending (%s).." % record_pipe.describe(), file=stderr)

    hasher = hashlib.sha256()
    progress = tqdm(
        file=stderr,
        disable=hide_progress,
        unit="B",
        unit_scale=True,
        total=filesize)

    def _count_and_hash(data):
        hasher.update(data)
        progress.update(len(data))
        return data

    fs = basic.FileSender()

    with timing.add("tx file"):
        with progress:
            if filesize:
                # don't send zero-length files
                yield fs.beginFileTransfer(
                    fd_to_send,
                    record_pipe,
                    transform=_count_and_hash)

    expected_hash = hasher.digest()
    expected_hex = bytes_to_hexstr(expected_hash)
    print(u"File sent.. waiting for confirmation", file=stderr)
    with timing.add("get ack") as t:
        ack_bytes = yield record_pipe.receive_record()
        record_pipe.close()
        ack = bytes_to_dict(ack_bytes)
        ok = ack.get(u"ack", u"")
        if ok != u"ok":
            t.detail(ack="failed")
            raise TransferError("Transfer failed (remote says: %r)" % ack)
        if u"sha256" in ack:
            if ack[u"sha256"] != expected_hex:
                t.detail(datahash="failed")
                raise TransferError("Transfer failed (bad remote hash)")
        print(u"Confirmation received. Transfer complete.", file=stderr)
        t.detail(ack="ok")


from re import L
import random
from functions_1 import *
from database import *
import tkinter as tk
from tkinter import messagebox
# from socketlistener import carwidth
#client-server
# car width calculation
# carwidth
# count=1
with open('readme.txt') as f:
    lines=f.readlines()
carwidth=int(lines[0])

def checkin_clicked(window,fare,pic_path):
    new_pic_path = pic_path.replace('/', '\\')
    fare = float(fare)
    number_plate_str = getNumberPlateSting(new_pic_path)
    res = addVehicleCheckin(vehicle_num=number_plate_str, fare=fare)
    if(res == True):
        messagebox.showinfo('SUCCESS!!!','Vehicle is allocated slots:{}'.format(find_slot(carwidth)))

def checkout_clicked(window, pic_path):
    new_pic_path = pic_path.replace('/', '\\')
    number_plate_str = getNumberPlateSting(pic_path)
    res = addVehicleCheckout(vehicle_num=number_plate_str)
    ans = getCheckoutdetails(vehicle_num=number_plate_str)
    text_str = 'Number= '+str(ans[0])+'\n'+'Check-In Time= ' + str(ans[1])+'\n'+'Check-Out Time= '+str(ans[2])+'\n'+'Base Fare= '+str(ans[3])+'\n'+'Collectible Fare= ' + \
        str(ans[4])+'\n'+'Durationin hrs = '+str(ans[5])+'\n'
    if(res == True):
        messagebox.showinfo('Charges Calculated!!',text_str)

# def checkin_clicked(window,fare,pic_path):
#     new_pic_path = pic_path.replace('/', '\\')
#     fare = float(fare)
#     number_plate_str = getNumberPlateSting(new_pic_path)
#     res = addVehicleCheckin(vehicle_num=number_plate_str, fare=fare)
#     if(res == True):
#         messagebox.showinfo('SUCCESS!!!','Vehicle is allocated slots:{}'.format(random.randint(0,9)))


import json
import requests
import time

def send(token,message,channel_id):
    header = {
        "authorization" : token
    }
    payload = {
        "content": "@Clyde " + message
    }
    message = requests.post(f"https://discord.com/api/v9/channels/{channel_id}/messages",headers=header,json=payload)

def get_reply(token,message,channel_id,limit = 6):
	url = f'https://discord.com/api/v9/channels/{channel_id}/messages?limit={limit}'
	headers= {
		"authorization" : token
		}
	response = requests.get(
		url=url,
		headers = headers,
		timeout=30,
		)
	for i in range(limit):
		try:
			if json.loads(response.text)[i]["referenced_message"]["content"] == "@Clyde " + message:
				return json.loads(response.text)[i]["content"]
		except:
			pass

def talk(name,token,message,channel_id,wait= 3,limit = 6):
	message = message + f"私の名前は{name}です。返信の際は{name}と呼んでください"
	send(token,message,channel_id)
	time.sleep(wait)
	return get_reply(token,message,channel_id,limit)


import miller_rabin as mr
from random import randrange

# function that applies Miller-Rabin test 10 times on the given n
def isPrime(n):
    for i in range(10):
        result = mr.millerRabinTest(n)
        if result:
            return False
    return True

# function that generates a prime number in the chosen order of magnitude
def generate_prime(exp):
    while True:
        n = randrange(1, 10**exp, 2)
        # making sure the number is of the chosen order of magnitude
        while len(str(n)) == exp:
            if isPrime(n):
                return n
            else:
                break

def main():
    print("This script generates prime numbers using Miller-Rabin test.")
    exp = 100
    print(generate_prime(exp))

    return

if __name__ == "__main__":
    main()